Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - some V4L2 API updates needed by embedded devices - DVB API extensions for ATSC-MH delivery system, used in US for mobile TV - new tuners for fc0011/0012/0013 and tua9001 - a new dvb driver for af9033/9035 - a new ATSC-MH frontend (lg2160) - new remote controller keymaps - Removal of a few legacy webcam driver that got replaced by gspca on several kernel versions ago - a new driver for Exynos 4/5 webcams(s5pp fimc-lite) - a new webcam sensor driver (smiapp) - a new video input driver for embedded (sta2x1xx) - several improvements, fixes, cleanups, etc inside the drivers. Manually fix up conflicts due to err() -> dev_err() conversion in drivers/staging/media/easycap/easycap_main.c * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (484 commits) [media] saa7134-cards: Remove a PCI entry added by mistake [media] radio-sf16fmi: add support for SF16-FMD [media] rc-loopback: remove duplicate line [media] patch for Asus My Cinema PS3-100 (1043:48cd) [media] au0828: Move the Kconfig knob under V4L_USB_DRIVERS [media] em28xx: simple comment fix [media] [resend] radio-sf16fmr2: add PnP support for SF16-FMD2 [media] smiapp: Use v4l2_ctrl_new_int_menu() instead of v4l2_ctrl_new_custom() [media] smiapp: Add support for 8-bit uncompressed formats [media] smiapp: Allow generic quirk registers [media] smiapp: Use non-binning limits if the binning limit is zero [media] smiapp: Initialise rval in smiapp_read_nvm() [media] smiapp: Round minimum pre_pll up rather than down in ip_clk_freq check [media] smiapp: Use 8-bit reads only before identifying the sensor [media] smiapp: Quirk for sensors that only do 8-bit reads [media] smiapp: Pass struct sensor to register writing commands instead of i2c_client [media] smiapp: Allow using external clock from the clock framework [media] zl10353: change .read_snr() to report SNR as a 0.1 dB [media] media: add support to gspca/pac7302.c for 093a:2627 (Genius FaceCam 300) [media] m88rs2000 - only flip bit 2 on reg 0x70 on 16th try ...
This commit is contained in:
commit
ab11ca34ee
|
@ -70,6 +70,8 @@ IOCTLS = \
|
|||
VIDIOC_SUBDEV_ENUM_MBUS_CODE \
|
||||
VIDIOC_SUBDEV_ENUM_FRAME_SIZE \
|
||||
VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \
|
||||
VIDIOC_SUBDEV_G_SELECTION \
|
||||
VIDIOC_SUBDEV_S_SELECTION \
|
||||
|
||||
TYPES = \
|
||||
$(shell perl -ne 'print "$$1 " if /^typedef\s+[^\s]+\s+([^\s]+)\;/' $(srctree)/include/linux/videodev2.h) \
|
||||
|
@ -193,7 +195,7 @@ DVB_DOCUMENTED = \
|
|||
#
|
||||
|
||||
install_media_images = \
|
||||
$(Q)cp $(OBJIMGFILES) $(MEDIA_OBJ_DIR)/media_api
|
||||
$(Q)cp $(OBJIMGFILES) $(MEDIA_SRC_DIR)/v4l/*.svg $(MEDIA_OBJ_DIR)/media_api
|
||||
|
||||
$(MEDIA_OBJ_DIR)/%: $(MEDIA_SRC_DIR)/%.b64
|
||||
$(Q)base64 -d $< >$@
|
||||
|
|
|
@ -531,6 +531,139 @@ typedef enum fe_delivery_system {
|
|||
here are referring to what can be found in the TMCC-structure -
|
||||
independent of the mode.</para>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-FIC-VER">
|
||||
<title><constant>DTV_ATSCMH_FIC_VER</constant></title>
|
||||
<para>Version number of the FIC (Fast Information Channel) signaling data.</para>
|
||||
<para>FIC is used for relaying information to allow rapid service acquisition by the receiver.</para>
|
||||
<para>Possible values: 0, 1, 2, 3, ..., 30, 31</para>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-PARADE-ID">
|
||||
<title><constant>DTV_ATSCMH_PARADE_ID</constant></title>
|
||||
<para>Parade identification number</para>
|
||||
<para>A parade is a collection of up to eight MH groups, conveying one or two ensembles.</para>
|
||||
<para>Possible values: 0, 1, 2, 3, ..., 126, 127</para>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-NOG">
|
||||
<title><constant>DTV_ATSCMH_NOG</constant></title>
|
||||
<para>Number of MH groups per MH subframe for a designated parade.</para>
|
||||
<para>Possible values: 1, 2, 3, 4, 5, 6, 7, 8</para>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-TNOG">
|
||||
<title><constant>DTV_ATSCMH_TNOG</constant></title>
|
||||
<para>Total number of MH groups including all MH groups belonging to all MH parades in one MH subframe.</para>
|
||||
<para>Possible values: 0, 1, 2, 3, ..., 30, 31</para>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-SGN">
|
||||
<title><constant>DTV_ATSCMH_SGN</constant></title>
|
||||
<para>Start group number.</para>
|
||||
<para>Possible values: 0, 1, 2, 3, ..., 14, 15</para>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-PRC">
|
||||
<title><constant>DTV_ATSCMH_PRC</constant></title>
|
||||
<para>Parade repetition cycle.</para>
|
||||
<para>Possible values: 1, 2, 3, 4, 5, 6, 7, 8</para>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-RS-FRAME-MODE">
|
||||
<title><constant>DTV_ATSCMH_RS_FRAME_MODE</constant></title>
|
||||
<para>RS frame mode.</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_rs_frame_mode {
|
||||
ATSCMH_RSFRAME_PRI_ONLY = 0,
|
||||
ATSCMH_RSFRAME_PRI_SEC = 1,
|
||||
} atscmh_rs_frame_mode_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-RS-FRAME-ENSEMBLE">
|
||||
<title><constant>DTV_ATSCMH_RS_FRAME_ENSEMBLE</constant></title>
|
||||
<para>RS frame ensemble.</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_rs_frame_ensemble {
|
||||
ATSCMH_RSFRAME_ENS_PRI = 0,
|
||||
ATSCMH_RSFRAME_ENS_SEC = 1,
|
||||
} atscmh_rs_frame_ensemble_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-RS-CODE-MODE-PRI">
|
||||
<title><constant>DTV_ATSCMH_RS_CODE_MODE_PRI</constant></title>
|
||||
<para>RS code mode (primary).</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_rs_code_mode {
|
||||
ATSCMH_RSCODE_211_187 = 0,
|
||||
ATSCMH_RSCODE_223_187 = 1,
|
||||
ATSCMH_RSCODE_235_187 = 2,
|
||||
} atscmh_rs_code_mode_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-RS-CODE-MODE-SEC">
|
||||
<title><constant>DTV_ATSCMH_RS_CODE_MODE_SEC</constant></title>
|
||||
<para>RS code mode (secondary).</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_rs_code_mode {
|
||||
ATSCMH_RSCODE_211_187 = 0,
|
||||
ATSCMH_RSCODE_223_187 = 1,
|
||||
ATSCMH_RSCODE_235_187 = 2,
|
||||
} atscmh_rs_code_mode_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-SCCC-BLOCK-MODE">
|
||||
<title><constant>DTV_ATSCMH_SCCC_BLOCK_MODE</constant></title>
|
||||
<para>Series Concatenated Convolutional Code Block Mode.</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_sccc_block_mode {
|
||||
ATSCMH_SCCC_BLK_SEP = 0,
|
||||
ATSCMH_SCCC_BLK_COMB = 1,
|
||||
} atscmh_sccc_block_mode_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-SCCC-CODE-MODE-A">
|
||||
<title><constant>DTV_ATSCMH_SCCC_CODE_MODE_A</constant></title>
|
||||
<para>Series Concatenated Convolutional Code Rate.</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_sccc_code_mode {
|
||||
ATSCMH_SCCC_CODE_HLF = 0,
|
||||
ATSCMH_SCCC_CODE_QTR = 1,
|
||||
} atscmh_sccc_code_mode_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-SCCC-CODE-MODE-B">
|
||||
<title><constant>DTV_ATSCMH_SCCC_CODE_MODE_B</constant></title>
|
||||
<para>Series Concatenated Convolutional Code Rate.</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_sccc_code_mode {
|
||||
ATSCMH_SCCC_CODE_HLF = 0,
|
||||
ATSCMH_SCCC_CODE_QTR = 1,
|
||||
} atscmh_sccc_code_mode_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-SCCC-CODE-MODE-C">
|
||||
<title><constant>DTV_ATSCMH_SCCC_CODE_MODE_C</constant></title>
|
||||
<para>Series Concatenated Convolutional Code Rate.</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_sccc_code_mode {
|
||||
ATSCMH_SCCC_CODE_HLF = 0,
|
||||
ATSCMH_SCCC_CODE_QTR = 1,
|
||||
} atscmh_sccc_code_mode_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
<section id="DTV-ATSCMH-SCCC-CODE-MODE-D">
|
||||
<title><constant>DTV_ATSCMH_SCCC_CODE_MODE_D</constant></title>
|
||||
<para>Series Concatenated Convolutional Code Rate.</para>
|
||||
<para>Possible values are:</para>
|
||||
<programlisting>
|
||||
typedef enum atscmh_sccc_code_mode {
|
||||
ATSCMH_SCCC_CODE_HLF = 0,
|
||||
ATSCMH_SCCC_CODE_QTR = 1,
|
||||
} atscmh_sccc_code_mode_t;
|
||||
</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
<section id="DTV-API-VERSION">
|
||||
<title><constant>DTV_API_VERSION</constant></title>
|
||||
|
@ -774,6 +907,33 @@ typedef enum fe_hierarchy {
|
|||
<listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section id="atscmh-params">
|
||||
<title>ATSC-MH delivery system</title>
|
||||
<para>The following parameters are valid for ATSC-MH:</para>
|
||||
<itemizedlist mark='opencircle'>
|
||||
<listitem><para><link linkend="DTV-API-VERSION"><constant>DTV_API_VERSION</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-DELIVERY-SYSTEM"><constant>DTV_DELIVERY_SYSTEM</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-TUNE"><constant>DTV_TUNE</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-CLEAR"><constant>DTV_CLEAR</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-FREQUENCY"><constant>DTV_FREQUENCY</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-BANDWIDTH-HZ"><constant>DTV_BANDWIDTH_HZ</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-FIC-VER"><constant>DTV_ATSCMH_FIC_VER</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-PARADE-ID"><constant>DTV_ATSCMH_PARADE_ID</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-NOG"><constant>DTV_ATSCMH_NOG</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-TNOG"><constant>DTV_ATSCMH_TNOG</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-SGN"><constant>DTV_ATSCMH_SGN</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-PRC"><constant>DTV_ATSCMH_PRC</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-RS-FRAME-MODE"><constant>DTV_ATSCMH_RS_FRAME_MODE</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-RS-FRAME-ENSEMBLE"><constant>DTV_ATSCMH_RS_FRAME_ENSEMBLE</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-CODE-MODE-PRI"><constant>DTV_ATSCMH_CODE_MODE_PRI</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-CODE-MODE-SEC"><constant>DTV_ATSCMH_CODE_MODE_SEC</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-SCCC-BLOCK-MODE"><constant>DTV_ATSCMH_SCCC_BLOCK_MODE</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-A"><constant>DTV_ATSCMH_SCCC_CODE_MODE_A</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-B"><constant>DTV_ATSCMH_SCCC_CODE_MODE_B</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-C"><constant>DTV_ATSCMH_SCCC_CODE_MODE_C</constant></link></para></listitem>
|
||||
<listitem><para><link linkend="DTV-ATSCMH-SCCC-CODE_MODE-D"><constant>DTV_ATSCMH_SCCC_CODE_MODE_D</constant></link></para></listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
<section id="frontend-property-cable-systems">
|
||||
<title>Properties used on cable delivery systems</title>
|
||||
|
|
|
@ -197,4 +197,33 @@ in the frequency range from 87,5 to 108,0 MHz</title>
|
|||
<title>NTSC-4: United States RBDS Standard</title>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="iso12232">
|
||||
<abbrev>ISO 12232:2006</abbrev>
|
||||
<authorgroup>
|
||||
<corpauthor>International Organization for Standardization
|
||||
(<ulink url="http://www.iso.org">http://www.iso.org</ulink>)</corpauthor>
|
||||
</authorgroup>
|
||||
<title>Photography — Digital still cameras — Determination
|
||||
of exposure index, ISO speed ratings, standard output sensitivity, and
|
||||
recommended exposure index</title>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="cea861">
|
||||
<abbrev>CEA-861-E</abbrev>
|
||||
<authorgroup>
|
||||
<corpauthor>Consumer Electronics Association
|
||||
(<ulink url="http://www.ce.org">http://www.ce.org</ulink>)</corpauthor>
|
||||
</authorgroup>
|
||||
<title>A DTV Profile for Uncompressed High Speed Digital Interfaces</title>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry id="vesadmt">
|
||||
<abbrev>VESA DMT</abbrev>
|
||||
<authorgroup>
|
||||
<corpauthor>Video Electronics Standards Association
|
||||
(<ulink url="http://www.vesa.org">http://www.vesa.org</ulink>)</corpauthor>
|
||||
</authorgroup>
|
||||
<title>VESA and Industry Standards and Guidelines for Computer Display Monitor Timing (DMT)</title>
|
||||
</biblioentry>
|
||||
|
||||
</bibliography>
|
||||
|
|
|
@ -724,41 +724,49 @@ if (-1 == ioctl (fd, &VIDIOC-S-STD;, &std_id)) {
|
|||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
<section id="dv-timings">
|
||||
<title>Digital Video (DV) Timings</title>
|
||||
<para>
|
||||
The video standards discussed so far has been dealing with Analog TV and the
|
||||
The video standards discussed so far have been dealing with Analog TV and the
|
||||
corresponding video timings. Today there are many more different hardware interfaces
|
||||
such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry
|
||||
video signals and there is a need to extend the API to select the video timings
|
||||
for these interfaces. Since it is not possible to extend the &v4l2-std-id; due to
|
||||
the limited bits available, a new set of IOCTLs is added to set/get video timings at
|
||||
the limited bits available, a new set of IOCTLs was added to set/get video timings at
|
||||
the input and output: </para><itemizedlist>
|
||||
<listitem>
|
||||
<para>DV Presets: Digital Video (DV) presets. These are IDs representing a
|
||||
<para>DV Timings: This will allow applications to define detailed
|
||||
video timings for the interface. This includes parameters such as width, height,
|
||||
polarities, frontporch, backporch etc. The <filename>linux/v4l2-dv-timings.h</filename>
|
||||
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.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Custom DV Timings: This will allow applications to define more detailed
|
||||
custom video timings for the interface. This includes parameters such as width, height,
|
||||
polarities, frontporch, backporch etc.
|
||||
</para>
|
||||
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,
|
||||
applications use the &VIDIOC-ENUM-DV-TIMINGS; and &VIDIOC-DV-TIMINGS-CAP; ioctls.
|
||||
To set DV timings for the device, applications use the
|
||||
&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.</para>
|
||||
<para>To set custom DV timings for the device, applications use the
|
||||
&VIDIOC-S-DV-TIMINGS; ioctl and to get current custom DV timings they use the
|
||||
&VIDIOC-G-DV-TIMINGS; ioctl.</para>
|
||||
&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>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
&sub-controls;
|
||||
|
|
|
@ -2407,6 +2407,54 @@ details.</para>
|
|||
<para>Added <link linkend="jpeg-controls">JPEG compression control
|
||||
class</link>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Extended the DV Timings API:
|
||||
&VIDIOC-ENUM-DV-TIMINGS;, &VIDIOC-QUERY-DV-TIMINGS; and
|
||||
&VIDIOC-DV-TIMINGS-CAP;.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>V4L2 in Linux 3.5</title>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Added integer menus, the new type will be
|
||||
V4L2_CTRL_TYPE_INTEGER_MENU.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Added selection API for V4L2 subdev interface:
|
||||
&VIDIOC-SUBDEV-G-SELECTION; and
|
||||
&VIDIOC-SUBDEV-S-SELECTION;.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> Added <constant>V4L2_COLORFX_ANTIQUE</constant>,
|
||||
<constant>V4L2_COLORFX_ART_FREEZE</constant>,
|
||||
<constant>V4L2_COLORFX_AQUA</constant>,
|
||||
<constant>V4L2_COLORFX_SILHOUETTE</constant>,
|
||||
<constant>V4L2_COLORFX_SOLARIZATION</constant>,
|
||||
<constant>V4L2_COLORFX_VIVID</constant> and
|
||||
<constant>V4L2_COLORFX_ARBITRARY_CBCR</constant> menu items
|
||||
to the <constant>V4L2_CID_COLORFX</constant> control.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> Added <constant>V4L2_CID_COLORFX_CBCR</constant> control.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> Added camera controls <constant>V4L2_CID_AUTO_EXPOSURE_BIAS</constant>,
|
||||
<constant>V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE</constant>,
|
||||
<constant>V4L2_CID_IMAGE_STABILIZATION</constant>,
|
||||
<constant>V4L2_CID_ISO_SENSITIVITY</constant>,
|
||||
<constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>,
|
||||
<constant>V4L2_CID_EXPOSURE_METERING</constant>,
|
||||
<constant>V4L2_CID_SCENE_MODE</constant>,
|
||||
<constant>V4L2_CID_3A_LOCK</constant>,
|
||||
<constant>V4L2_CID_AUTO_FOCUS_START</constant>,
|
||||
<constant>V4L2_CID_AUTO_FOCUS_STOP</constant>,
|
||||
<constant>V4L2_CID_AUTO_FOCUS_STATUS</constant> and
|
||||
<constant>V4L2_CID_AUTO_FOCUS_RANGE</constant>.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
|
||||
|
@ -2505,6 +2553,10 @@ and may change in the future.</para>
|
|||
</listitem>
|
||||
<listitem>
|
||||
<para>&VIDIOC-ENCODER-CMD; and &VIDIOC-TRY-ENCODER-CMD;
|
||||
ioctls.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>&VIDIOC-DECODER-CMD; and &VIDIOC-TRY-DECODER-CMD;
|
||||
ioctls.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
@ -2514,6 +2566,10 @@ ioctls.</para>
|
|||
<listitem>
|
||||
<para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>&VIDIOC-ENUM-DV-TIMINGS;, &VIDIOC-QUERY-DV-TIMINGS; and
|
||||
&VIDIOC-DV-TIMINGS-CAP; ioctls.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Flash API. <xref linkend="flash-controls" /></para>
|
||||
</listitem>
|
||||
|
@ -2523,6 +2579,14 @@ ioctls.</para>
|
|||
<listitem>
|
||||
<para>Selection API. <xref linkend="selection-api" /></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Sub-device selection API: &VIDIOC-SUBDEV-G-SELECTION;
|
||||
and &VIDIOC-SUBDEV-S-SELECTION; ioctls.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><link linkend="v4l2-auto-focus-area"><constant>
|
||||
V4L2_CID_AUTO_FOCUS_AREA</constant></link> control.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
@ -2538,6 +2602,17 @@ interfaces and should not be implemented in new drivers.</para>
|
|||
<constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls,
|
||||
<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>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><constant>VIDIOC_SUBDEV_G_CROP</constant> and
|
||||
<constant>VIDIOC_SUBDEV_S_CROP</constant> ioctls. Use
|
||||
<constant>VIDIOC_SUBDEV_G_SELECTION</constant> and
|
||||
<constant>VIDIOC_SUBDEV_S_SELECTION</constant>, <xref
|
||||
linkend="vidioc-subdev-g-selection" />.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -285,18 +285,92 @@ minimum value disables backlight compensation.</entry>
|
|||
<row id="v4l2-colorfx">
|
||||
<entry><constant>V4L2_CID_COLORFX</constant></entry>
|
||||
<entry>enum</entry>
|
||||
<entry>Selects a color effect. Possible values for
|
||||
<constant>enum v4l2_colorfx</constant> are:
|
||||
<constant>V4L2_COLORFX_NONE</constant> (0),
|
||||
<constant>V4L2_COLORFX_BW</constant> (1),
|
||||
<constant>V4L2_COLORFX_SEPIA</constant> (2),
|
||||
<constant>V4L2_COLORFX_NEGATIVE</constant> (3),
|
||||
<constant>V4L2_COLORFX_EMBOSS</constant> (4),
|
||||
<constant>V4L2_COLORFX_SKETCH</constant> (5),
|
||||
<constant>V4L2_COLORFX_SKY_BLUE</constant> (6),
|
||||
<constant>V4L2_COLORFX_GRASS_GREEN</constant> (7),
|
||||
<constant>V4L2_COLORFX_SKIN_WHITEN</constant> (8) and
|
||||
<constant>V4L2_COLORFX_VIVID</constant> (9).</entry>
|
||||
<entry>Selects a color effect. The following values are defined:
|
||||
</entry>
|
||||
</row><row>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_NONE</constant> </entry>
|
||||
<entry>Color effect is disabled.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_ANTIQUE</constant> </entry>
|
||||
<entry>An aging (old photo) effect.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_ART_FREEZE</constant> </entry>
|
||||
<entry>Frost color effect.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_AQUA</constant> </entry>
|
||||
<entry>Water color, cool tone.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_BW</constant> </entry>
|
||||
<entry>Black and white.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_EMBOSS</constant> </entry>
|
||||
<entry>Emboss, the highlights and shadows replace light/dark boundaries
|
||||
and low contrast areas are set to a gray background.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_GRASS_GREEN</constant> </entry>
|
||||
<entry>Grass green.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_NEGATIVE</constant> </entry>
|
||||
<entry>Negative.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_SEPIA</constant> </entry>
|
||||
<entry>Sepia tone.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_SKETCH</constant> </entry>
|
||||
<entry>Sketch.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_SKIN_WHITEN</constant> </entry>
|
||||
<entry>Skin whiten.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_SKY_BLUE</constant> </entry>
|
||||
<entry>Sky blue.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_SOLARIZATION</constant> </entry>
|
||||
<entry>Solarization, the image is partially reversed in tone,
|
||||
only color values above or below a certain threshold are inverted.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_SILHOUETTE</constant> </entry>
|
||||
<entry>Silhouette (outline).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_VIVID</constant> </entry>
|
||||
<entry>Vivid colors.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_COLORFX_SET_CBCR</constant> </entry>
|
||||
<entry>The Cb and Cr chroma components are replaced by fixed
|
||||
coefficients determined by <constant>V4L2_CID_COLORFX_CBCR</constant>
|
||||
control.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CID_COLORFX_CBCR</constant></entry>
|
||||
<entry>integer</entry>
|
||||
<entry>Determines the Cb and Cr coefficients for <constant>V4L2_COLORFX_SET_CBCR</constant>
|
||||
color effect. Bits [7:0] of the supplied 32 bit value are interpreted as
|
||||
Cr component, bits [15:8] as Cb component and bits [31:16] must be zero.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CID_ROTATE</constant></entry>
|
||||
|
@ -2774,6 +2848,51 @@ remain constant.</entry>
|
|||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_EXPOSURE_BIAS</constant> </entry>
|
||||
<entry>integer menu</entry>
|
||||
</row><row><entry spanname="descr"> Determines the automatic
|
||||
exposure compensation, it is effective only when <constant>V4L2_CID_EXPOSURE_AUTO</constant>
|
||||
control is set to <constant>AUTO</constant>, <constant>SHUTTER_PRIORITY </constant>
|
||||
or <constant>APERTURE_PRIORITY</constant>.
|
||||
It is expressed in terms of EV, drivers should interpret the values as 0.001 EV
|
||||
units, where the value 1000 stands for +1 EV.
|
||||
<para>Increasing the exposure compensation value is equivalent to decreasing
|
||||
the exposure value (EV) and will increase the amount of light at the image
|
||||
sensor. The camera performs the exposure compensation by adjusting absolute
|
||||
exposure time and/or aperture.</para></entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row id="v4l2-exposure-metering">
|
||||
<entry spanname="id"><constant>V4L2_CID_EXPOSURE_METERING</constant> </entry>
|
||||
<entry>enum v4l2_exposure_metering</entry>
|
||||
</row><row><entry spanname="descr">Determines how the camera measures
|
||||
the amount of light available for the frame exposure. Possible values are:</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_EXPOSURE_METERING_AVERAGE</constant> </entry>
|
||||
<entry>Use the light information coming from the entire frame
|
||||
and average giving no weighting to any particular portion of the metered area.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_EXPOSURE_METERING_CENTER_WEIGHTED</constant> </entry>
|
||||
<entry>Average the light information coming from the entire frame
|
||||
giving priority to the center of the metered area.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_EXPOSURE_METERING_SPOT</constant> </entry>
|
||||
<entry>Measure only very small area at the center of the frame.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant> </entry>
|
||||
<entry>integer</entry>
|
||||
|
@ -2857,12 +2976,106 @@ negative values towards infinity. This is a write-only control.</entry>
|
|||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_FOCUS_AUTO</constant> </entry>
|
||||
<entry>boolean</entry>
|
||||
</row><row><entry spanname="descr">Enables automatic focus
|
||||
adjustments. The effect of manual focus adjustments while this feature
|
||||
</row><row><entry spanname="descr">Enables continuous automatic
|
||||
focus adjustments. The effect of manual focus adjustments while this feature
|
||||
is enabled is undefined, drivers should ignore such requests.</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_AUTO_FOCUS_START</constant> </entry>
|
||||
<entry>button</entry>
|
||||
</row><row><entry spanname="descr">Starts single auto focus process.
|
||||
The effect of setting this control when <constant>V4L2_CID_FOCUS_AUTO</constant>
|
||||
is set to <constant>TRUE</constant> (1) is undefined, drivers should ignore
|
||||
such requests.</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_AUTO_FOCUS_STOP</constant> </entry>
|
||||
<entry>button</entry>
|
||||
</row><row><entry spanname="descr">Aborts automatic focusing
|
||||
started with <constant>V4L2_CID_AUTO_FOCUS_START</constant> control. It is
|
||||
effective only when the continuous autofocus is disabled, that is when
|
||||
<constant>V4L2_CID_FOCUS_AUTO</constant> control is set to <constant>FALSE
|
||||
</constant> (0).</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row id="v4l2-auto-focus-status">
|
||||
<entry spanname="id">
|
||||
<constant>V4L2_CID_AUTO_FOCUS_STATUS</constant> </entry>
|
||||
<entry>bitmask</entry>
|
||||
</row>
|
||||
<row><entry spanname="descr">The automatic focus status. This is a read-only
|
||||
control.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_AUTO_FOCUS_STATUS_IDLE</constant> </entry>
|
||||
<entry>Automatic focus is not active.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_AUTO_FOCUS_STATUS_BUSY</constant> </entry>
|
||||
<entry>Automatic focusing is in progress.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_AUTO_FOCUS_STATUS_REACHED</constant> </entry>
|
||||
<entry>Focus has been reached.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_AUTO_FOCUS_STATUS_FAILED</constant> </entry>
|
||||
<entry>Automatic focus has failed, the driver will not
|
||||
transition from this state until another action is
|
||||
performed by an application.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
<row><entry spanname="descr">
|
||||
Setting <constant>V4L2_LOCK_FOCUS</constant> lock bit of the <constant>V4L2_CID_3A_LOCK
|
||||
</constant> control may stop updates of the <constant>V4L2_CID_AUTO_FOCUS_STATUS</constant>
|
||||
control value.</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row id="v4l2-auto-focus-range">
|
||||
<entry spanname="id">
|
||||
<constant>V4L2_CID_AUTO_FOCUS_RANGE</constant> </entry>
|
||||
<entry>enum v4l2_auto_focus_range</entry>
|
||||
</row>
|
||||
<row><entry spanname="descr">Determines auto focus distance range
|
||||
for which lens may be adjusted. </entry>
|
||||
</row>
|
||||
<row>
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_AUTO_FOCUS_RANGE_AUTO</constant> </entry>
|
||||
<entry>The camera automatically selects the focus range.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_AUTO_FOCUS_RANGE_NORMAL</constant> </entry>
|
||||
<entry>Normal distance range, limited for best automatic focus
|
||||
performance.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_AUTO_FOCUS_RANGE_MACRO</constant> </entry>
|
||||
<entry>Macro (close-up) auto focus. The camera will
|
||||
use its minimum possible distance for auto focus.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_AUTO_FOCUS_RANGE_INFINITY</constant> </entry>
|
||||
<entry>The lens is set to focus on an object at infinite distance.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_ZOOM_ABSOLUTE</constant> </entry>
|
||||
<entry>integer</entry>
|
||||
|
@ -2932,6 +3145,295 @@ camera sensor on or off, or specify its strength. Such band-stop filters can
|
|||
be used, for example, to filter out the fluorescent light component.</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row id="v4l2-auto-n-preset-white-balance">
|
||||
<entry spanname="id"><constant>V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE</constant> </entry>
|
||||
<entry>enum v4l2_auto_n_preset_white_balance</entry>
|
||||
</row><row><entry spanname="descr">Sets white balance to automatic,
|
||||
manual or a preset. The presets determine color temperature of the light as
|
||||
a hint to the camera for white balance adjustments resulting in most accurate
|
||||
color representation. The following white balance presets are listed in order
|
||||
of increasing color temperature.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_MANUAL</constant> </entry>
|
||||
<entry>Manual white balance.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_AUTO</constant> </entry>
|
||||
<entry>Automatic white balance adjustments.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_INCANDESCENT</constant> </entry>
|
||||
<entry>White balance setting for incandescent (tungsten) lighting.
|
||||
It generally cools down the colors and corresponds approximately to 2500...3500 K
|
||||
color temperature range.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_FLUORESCENT</constant> </entry>
|
||||
<entry>White balance preset for fluorescent lighting.
|
||||
It corresponds approximately to 4000...5000 K color temperature.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_FLUORESCENT_H</constant> </entry>
|
||||
<entry>With this setting the camera will compensate for
|
||||
fluorescent H lighting.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_HORIZON</constant> </entry>
|
||||
<entry>White balance setting for horizon daylight.
|
||||
It corresponds approximately to 5000 K color temperature.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_DAYLIGHT</constant> </entry>
|
||||
<entry>White balance preset for daylight (with clear sky).
|
||||
It corresponds approximately to 5000...6500 K color temperature.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_FLASH</constant> </entry>
|
||||
<entry>With this setting the camera will compensate for the flash
|
||||
light. It slightly warms up the colors and corresponds roughly to 5000...5500 K
|
||||
color temperature.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_CLOUDY</constant> </entry>
|
||||
<entry>White balance preset for moderately overcast sky.
|
||||
This option corresponds approximately to 6500...8000 K color temperature
|
||||
range.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_WHITE_BALANCE_SHADE</constant> </entry>
|
||||
<entry>White balance preset for shade or heavily overcast
|
||||
sky. It corresponds approximately to 9000...10000 K color temperature.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row id="v4l2-wide-dynamic-range">
|
||||
<entry spanname="id"><constant>V4L2_CID_WIDE_DYNAMIC_RANGE</constant></entry>
|
||||
<entry>boolean</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Enables or disables the camera's wide dynamic
|
||||
range feature. This feature allows to obtain clear images in situations where
|
||||
intensity of the illumination varies significantly throughout the scene, i.e.
|
||||
there are simultaneously very dark and very bright areas. It is most commonly
|
||||
realized in cameras by combining two subsequent frames with different exposure
|
||||
times. <footnote id="ctypeconv"><para> This control may be changed to a menu
|
||||
control in the future, if more options are required.</para></footnote></entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row id="v4l2-image-stabilization">
|
||||
<entry spanname="id"><constant>V4L2_CID_IMAGE_STABILIZATION</constant></entry>
|
||||
<entry>boolean</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Enables or disables image stabilization.
|
||||
<footnoteref linkend="ctypeconv"/></entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY</constant> </entry>
|
||||
<entry>integer menu</entry>
|
||||
</row><row><entry spanname="descr">Determines ISO equivalent of an
|
||||
image sensor indicating the sensor's sensitivity to light. The numbers are
|
||||
expressed in arithmetic scale, as per <xref linkend="iso12232" /> standard,
|
||||
where doubling the sensor sensitivity is represented by doubling the numerical
|
||||
ISO value. Applications should interpret the values as standard ISO values
|
||||
multiplied by 1000, e.g. control value 800 stands for ISO 0.8. Drivers will
|
||||
usually support only a subset of standard ISO values. The effect of setting
|
||||
this control while the <constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>
|
||||
control is set to a value other than <constant>V4L2_CID_ISO_SENSITIVITY_MANUAL
|
||||
</constant> is undefined, drivers should ignore such requests.</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row id="v4l2-iso-sensitivity-auto-type">
|
||||
<entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant> </entry>
|
||||
<entry>enum v4l2_iso_sensitivity_type</entry>
|
||||
</row><row><entry spanname="descr">Enables or disables automatic ISO
|
||||
sensitivity adjustments.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_CID_ISO_SENSITIVITY_MANUAL</constant> </entry>
|
||||
<entry>Manual ISO sensitivity.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant> </entry>
|
||||
<entry>Automatic ISO sensitivity adjustments.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row id="v4l2-scene-mode">
|
||||
<entry spanname="id"><constant>V4L2_CID_SCENE_MODE</constant> </entry>
|
||||
<entry>enum v4l2_scene_mode</entry>
|
||||
</row><row><entry spanname="descr">This control allows to select
|
||||
scene programs as the camera automatic modes optimized for common shooting
|
||||
scenes. Within these modes the camera determines best exposure, aperture,
|
||||
focusing, light metering, white balance and equivalent sensitivity. The
|
||||
controls of those parameters are influenced by the scene mode control.
|
||||
An exact behavior in each mode is subject to the camera specification.
|
||||
|
||||
<para>When the scene mode feature is not used, this control should be set to
|
||||
<constant>V4L2_SCENE_MODE_NONE</constant> to make sure the other possibly
|
||||
related controls are accessible. The following scene programs are defined:
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_NONE</constant> </entry>
|
||||
<entry>The scene mode feature is disabled.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_BACKLIGHT</constant> </entry>
|
||||
<entry>Backlight. Compensates for dark shadows when light is
|
||||
coming from behind a subject, also by automatically turning
|
||||
on the flash.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_BEACH_SNOW</constant> </entry>
|
||||
<entry>Beach and snow. This mode compensates for all-white or
|
||||
bright scenes, which tend to look gray and low contrast, when camera's automatic
|
||||
exposure is based on an average scene brightness. To compensate, this mode
|
||||
automatically slightly overexposes the frames. The white balance may also be
|
||||
adjusted to compensate for the fact that reflected snow looks bluish rather
|
||||
than white.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_CANDLELIGHT</constant> </entry>
|
||||
<entry>Candle light. The camera generally raises the ISO
|
||||
sensitivity and lowers the shutter speed. This mode compensates for relatively
|
||||
close subject in the scene. The flash is disabled in order to preserve the
|
||||
ambiance of the light.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_DAWN_DUSK</constant> </entry>
|
||||
<entry>Dawn and dusk. Preserves the colors seen in low
|
||||
natural light before dusk and after down. The camera may turn off the flash,
|
||||
and automatically focus at infinity. It will usually boost saturation and
|
||||
lower the shutter speed.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_FALL_COLORS</constant> </entry>
|
||||
<entry>Fall colors. Increases saturation and adjusts white
|
||||
balance for color enhancement. Pictures of autumn leaves get saturated reds
|
||||
and yellows.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_FIREWORKS</constant> </entry>
|
||||
<entry>Fireworks. Long exposure times are used to capture
|
||||
the expanding burst of light from a firework. The camera may invoke image
|
||||
stabilization.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_LANDSCAPE</constant> </entry>
|
||||
<entry>Landscape. The camera may choose a small aperture to
|
||||
provide deep depth of field and long exposure duration to help capture detail
|
||||
in dim light conditions. The focus is fixed at infinity. Suitable for distant
|
||||
and wide scenery.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_NIGHT</constant> </entry>
|
||||
<entry>Night, also known as Night Landscape. Designed for low
|
||||
light conditions, it preserves detail in the dark areas without blowing out bright
|
||||
objects. The camera generally sets itself to a medium-to-high ISO sensitivity,
|
||||
with a relatively long exposure time, and turns flash off. As such, there will be
|
||||
increased image noise and the possibility of blurred image.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_PARTY_INDOOR</constant> </entry>
|
||||
<entry>Party and indoor. Designed to capture indoor scenes
|
||||
that are lit by indoor background lighting as well as the flash. The camera
|
||||
usually increases ISO sensitivity, and adjusts exposure for the low light
|
||||
conditions.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_PORTRAIT</constant> </entry>
|
||||
<entry>Portrait. The camera adjusts the aperture so that the
|
||||
depth of field is reduced, which helps to isolate the subject against a smooth
|
||||
background. Most cameras recognize the presence of faces in the scene and focus
|
||||
on them. The color hue is adjusted to enhance skin tones. The intensity of the
|
||||
flash is often reduced.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_SPORTS</constant> </entry>
|
||||
<entry>Sports. Significantly increases ISO and uses a fast
|
||||
shutter speed to freeze motion of rapidly-moving subjects. Increased image
|
||||
noise may be seen in this mode.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_SUNSET</constant> </entry>
|
||||
<entry>Sunset. Preserves deep hues seen in sunsets and
|
||||
sunrises. It bumps up the saturation.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SCENE_MODE_TEXT</constant> </entry>
|
||||
<entry>Text. It applies extra contrast and sharpness, it is
|
||||
typically a black-and-white mode optimized for readability. Automatic focus
|
||||
may be switched to close-up mode and this setting may also involve some
|
||||
lens-distortion correction.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_3A_LOCK</constant></entry>
|
||||
<entry>bitmask</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">This control locks or unlocks the automatic
|
||||
focus, exposure and white balance. The automatic adjustments can be paused
|
||||
independently by setting the corresponding lock bit to 1. The camera then retains
|
||||
the settings until the lock bit is cleared. The following lock bits are defined:
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_LOCK_EXPOSURE</constant></entry>
|
||||
<entry>Automatic exposure adjustments lock.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_LOCK_WHITE_BALANCE</constant></entry>
|
||||
<entry>Automatic white balance adjustments lock.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_LOCK_FOCUS</constant></entry>
|
||||
<entry>Automatic focus lock.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
<row><entry spanname="descr">
|
||||
When a given algorithm is not enabled, drivers should ignore requests
|
||||
to lock it and should return no error. An example might be an application
|
||||
setting bit <constant>V4L2_LOCK_WHITE_BALANCE</constant> when the
|
||||
<constant>V4L2_CID_AUTO_WHITE_BALANCE</constant> control is set to
|
||||
<constant>FALSE</constant>. The value of this control may be changed
|
||||
by exposure, white balance or focus controls.</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
@ -3476,7 +3978,7 @@ interface and may change in the future.</para>
|
|||
<entry spanname="id"><constant>V4L2_CID_JPEG_CHROMA_SUBSAMPLING</constant></entry>
|
||||
<entry>menu</entry>
|
||||
</row>
|
||||
<row id="jpeg-chroma-subsampling-control">
|
||||
<row id="v4l2-jpeg-chroma-subsampling">
|
||||
<entry spanname="descr">The chroma subsampling factors describe how
|
||||
each component of an input image is sampled, in respect to maximum
|
||||
sample rate in each spatial dimension. See <xref linkend="itu-t81"/>,
|
||||
|
@ -3486,7 +3988,7 @@ interface and may change in the future.</para>
|
|||
from RGB to Y'CbCr color space.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<row id = "v4l2-jpeg-chroma-subsampling">
|
||||
<entrytbl spanname="descr" cols="2">
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
|
@ -3538,12 +4040,12 @@ interface and may change in the future.</para>
|
|||
</entry>
|
||||
</row>
|
||||
<row id="jpeg-quality-control">
|
||||
<entry spanname="id"><constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant></entry>
|
||||
<entry spanname="id"><constant>V4L2_CID_JPEG_COMPRESSION_QUALITY</constant></entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">
|
||||
<constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control
|
||||
<constant>V4L2_CID_JPEG_COMPRESSION_QUALITY</constant> control
|
||||
determines trade-off between image quality and size.
|
||||
It provides simpler method for applications to control image quality,
|
||||
without a need for direct reconfiguration of luminance and chrominance
|
||||
|
@ -3551,7 +4053,7 @@ interface and may change in the future.</para>
|
|||
|
||||
In cases where a driver uses quantization tables configured directly
|
||||
by an application, using interfaces defined elsewhere, <constant>
|
||||
V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control should be set
|
||||
V4L2_CID_JPEG_COMPRESSION_QUALITY</constant> control should be set
|
||||
by driver to 0.
|
||||
|
||||
<para>The value range of this control is driver-specific. Only
|
||||
|
@ -3599,4 +4101,172 @@ interface and may change in the future.</para>
|
|||
to <xref linkend="itu-t81"/>, <xref linkend="jfif"/>,
|
||||
<xref linkend="w3c-jpeg-jfif"/>.</para>
|
||||
</section>
|
||||
|
||||
<section id="image-source-controls">
|
||||
<title>Image Source Control Reference</title>
|
||||
|
||||
<note>
|
||||
<title>Experimental</title>
|
||||
|
||||
<para>This is an <link
|
||||
linkend="experimental">experimental</link> interface and may
|
||||
change in the future.</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
The Image Source control class is intended for low-level
|
||||
control of image source devices such as image sensors. The
|
||||
devices feature an analogue to digital converter and a bus
|
||||
transmitter to transmit the image data out of the device.
|
||||
</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="image-source-control-id">
|
||||
<title>Image Source 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_IMAGE_SOURCE_CLASS</constant></entry>
|
||||
<entry>class</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">The IMAGE_SOURCE class descriptor.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_VBLANK</constant></entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Vertical blanking. The idle period
|
||||
after every frame during which no image data is produced.
|
||||
The unit of vertical blanking is a line. Every line has
|
||||
length of the image width plus horizontal blanking at the
|
||||
pixel rate defined by
|
||||
<constant>V4L2_CID_PIXEL_RATE</constant> control in the
|
||||
same sub-device.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_HBLANK</constant></entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Horizontal blanking. The idle
|
||||
period after every line of image data during which no
|
||||
image data is produced. The unit of horizontal blanking is
|
||||
pixels.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_ANALOGUE_GAIN</constant></entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Analogue gain is gain affecting
|
||||
all colour components in the pixel matrix. The gain
|
||||
operation is performed in the analogue domain before A/D
|
||||
conversion.
|
||||
</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="image-process-controls">
|
||||
<title>Image Process Control Reference</title>
|
||||
|
||||
<note>
|
||||
<title>Experimental</title>
|
||||
|
||||
<para>This is an <link
|
||||
linkend="experimental">experimental</link> interface and may
|
||||
change in the future.</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
The Image Source control class is intended for low-level control of
|
||||
image processing functions. Unlike
|
||||
<constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant>, the controls in
|
||||
this class affect processing the image, and do not control capturing
|
||||
of it.
|
||||
</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="image-process-control-id">
|
||||
<title>Image Source 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_IMAGE_PROC_CLASS</constant></entry>
|
||||
<entry>class</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">The IMAGE_PROC class descriptor.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_LINK_FREQ</constant></entry>
|
||||
<entry>integer menu</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Data bus frequency. Together with the
|
||||
media bus pixel code, bus type (clock cycles per sample), the
|
||||
data bus frequency defines the pixel rate
|
||||
(<constant>V4L2_CID_PIXEL_RATE</constant>) in the
|
||||
pixel array (or possibly elsewhere, if the device is not an
|
||||
image sensor). The frame rate can be calculated from the pixel
|
||||
clock, image width and height and horizontal and vertical
|
||||
blanking. While the pixel rate control may be defined elsewhere
|
||||
than in the subdev containing the pixel array, the frame rate
|
||||
cannot be obtained from that information. This is because only
|
||||
on the pixel array it can be assumed that the vertical and
|
||||
horizontal blanking information is exact: no other blanking is
|
||||
allowed in the pixel array. The selection of frame rate is
|
||||
performed by selecting the desired horizontal and vertical
|
||||
blanking. The unit of this control is Hz. </entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_PIXEL_RATE</constant></entry>
|
||||
<entry>64-bit integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Pixel rate in the source pads of
|
||||
the subdev. This control is read-only and its unit is
|
||||
pixels / second.
|
||||
</entry>
|
||||
</row>
|
||||
<row><entry></entry></row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
@ -76,11 +76,12 @@
|
|||
<wordasword>format</wordasword> means the combination of media bus data
|
||||
format, frame width and frame height.</para></note>
|
||||
|
||||
<para>Image formats are typically negotiated on video capture and output
|
||||
devices using the <link linkend="crop">cropping and scaling</link> ioctls.
|
||||
The driver is responsible for configuring every block in the video pipeline
|
||||
according to the requested format at the pipeline input and/or
|
||||
output.</para>
|
||||
<para>Image formats are typically negotiated on video capture and
|
||||
output devices using the format and <link
|
||||
linkend="vidioc-subdev-g-selection">selection</link> ioctls. The
|
||||
driver is responsible for configuring every block in the video
|
||||
pipeline according to the requested format at the pipeline input
|
||||
and/or output.</para>
|
||||
|
||||
<para>For complex devices, such as often found in embedded systems,
|
||||
identical image sizes at the output of a pipeline can be achieved using
|
||||
|
@ -276,11 +277,11 @@
|
|||
</section>
|
||||
|
||||
<section>
|
||||
<title>Cropping and scaling</title>
|
||||
<title>Selections: cropping, scaling and composition</title>
|
||||
|
||||
<para>Many sub-devices support cropping frames on their input or output
|
||||
pads (or possible even on both). Cropping is used to select the area of
|
||||
interest in an image, typically on a video sensor or video decoder. It can
|
||||
interest in an image, typically on an image sensor or a video decoder. It can
|
||||
also be used as part of digital zoom implementations to select the area of
|
||||
the image that will be scaled up.</para>
|
||||
|
||||
|
@ -288,26 +289,179 @@
|
|||
&v4l2-rect; by the coordinates of the top left corner and the rectangle
|
||||
size. Both the coordinates and sizes are expressed in pixels.</para>
|
||||
|
||||
<para>The crop rectangle is retrieved and set using the
|
||||
&VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad
|
||||
formats, drivers store try and active crop rectangles. The format
|
||||
negotiation mechanism applies to crop settings as well.</para>
|
||||
<para>As for pad formats, drivers store try and active
|
||||
rectangles for the selection targets of ACTUAL type <xref
|
||||
linkend="v4l2-subdev-selection-targets">.</xref></para>
|
||||
|
||||
<para>On input pads, cropping is applied relatively to the current pad
|
||||
format. The pad format represents the image size as received by the
|
||||
sub-device from the previous block in the pipeline, and the crop rectangle
|
||||
represents the sub-image that will be transmitted further inside the
|
||||
sub-device for processing. The crop rectangle be entirely containted
|
||||
inside the input image size.</para>
|
||||
<para>On sink pads, cropping is applied relative to the
|
||||
current pad format. The pad format represents the image size as
|
||||
received by the sub-device from the previous block in the
|
||||
pipeline, and the crop rectangle represents the sub-image that
|
||||
will be transmitted further inside the sub-device for
|
||||
processing.</para>
|
||||
|
||||
<para>Input crop rectangle are reset to their default value when the input
|
||||
image format is modified. Drivers should use the input image size as the
|
||||
crop rectangle default value, but hardware requirements may prevent this.
|
||||
</para>
|
||||
<para>The scaling operation changes the size of the image by
|
||||
scaling it to new dimensions. The scaling ratio isn't specified
|
||||
explicitly, but is implied from the original and scaled image
|
||||
sizes. Both sizes are represented by &v4l2-rect;.</para>
|
||||
|
||||
<para>Cropping behaviour on output pads is not defined.</para>
|
||||
<para>Scaling support is optional. When supported by a subdev,
|
||||
the crop rectangle on the subdev's sink pad is scaled to the
|
||||
size configured using the &VIDIOC-SUBDEV-S-SELECTION; IOCTL
|
||||
using <constant>V4L2_SUBDEV_SEL_COMPOSE_ACTUAL</constant>
|
||||
selection target on the same pad. If the subdev supports scaling
|
||||
but not composing, the top and left values are not used and must
|
||||
always be set to zero.</para>
|
||||
|
||||
<para>On source pads, cropping is similar to sink pads, with the
|
||||
exception that the source size from which the cropping is
|
||||
performed, is the COMPOSE rectangle on the sink pad. In both
|
||||
sink and source pads, the crop rectangle must be entirely
|
||||
contained inside the source image size for the crop
|
||||
operation.</para>
|
||||
|
||||
<para>The drivers should always use the closest possible
|
||||
rectangle the user requests on all selection targets, unless
|
||||
specifically told otherwise.
|
||||
<constant>V4L2_SUBDEV_SEL_FLAG_SIZE_GE</constant> and
|
||||
<constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant> flags may be
|
||||
used to round the image size either up or down. <xref
|
||||
linkend="v4l2-subdev-selection-flags"></xref></para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Types of selection targets</title>
|
||||
|
||||
<section>
|
||||
<title>ACTUAL targets</title>
|
||||
|
||||
<para>ACTUAL targets reflect the actual hardware configuration
|
||||
at any point of time. There is a BOUNDS target
|
||||
corresponding to every ACTUAL.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>BOUNDS targets</title>
|
||||
|
||||
<para>BOUNDS targets is the smallest rectangle that contains
|
||||
all valid ACTUAL rectangles. It may not be possible to set the
|
||||
ACTUAL rectangle as large as the BOUNDS rectangle, however.
|
||||
This may be because e.g. a sensor's pixel array is not
|
||||
rectangular but cross-shaped or round. The maximum size may
|
||||
also be smaller than the BOUNDS rectangle.</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Order of configuration and format propagation</title>
|
||||
|
||||
<para>Inside subdevs, the order of image processing steps will
|
||||
always be from the sink pad towards the source pad. This is also
|
||||
reflected in the order in which the configuration must be
|
||||
performed by the user: the changes made will be propagated to
|
||||
any subsequent stages. If this behaviour is not desired, the
|
||||
user must set
|
||||
<constant>V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG</constant> flag. This
|
||||
flag causes no propagation of the changes are allowed in any
|
||||
circumstances. This may also cause the accessed rectangle to be
|
||||
adjusted by the driver, depending on the properties of the
|
||||
underlying hardware.</para>
|
||||
|
||||
<para>The coordinates to a step always refer to the actual size
|
||||
of the previous step. The exception to this rule is the source
|
||||
compose rectangle, which refers to the sink compose bounds
|
||||
rectangle --- if it is supported by the hardware.</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>Sink pad format. The user configures the sink pad
|
||||
format. This format defines the parameters of the image the
|
||||
entity receives through the pad for further processing.</listitem>
|
||||
|
||||
<listitem>Sink pad actual crop selection. The sink pad crop
|
||||
defines the crop performed to the sink pad format.</listitem>
|
||||
|
||||
<listitem>Sink pad actual compose selection. The size of the
|
||||
sink pad compose rectangle defines the scaling ratio compared
|
||||
to the size of the sink pad crop rectangle. The location of
|
||||
the compose rectangle specifies the location of the actual
|
||||
sink compose rectangle in the sink compose bounds
|
||||
rectangle.</listitem>
|
||||
|
||||
<listitem>Source pad actual crop selection. Crop on the source
|
||||
pad defines crop performed to the image in the sink compose
|
||||
bounds rectangle.</listitem>
|
||||
|
||||
<listitem>Source pad format. The source pad format defines the
|
||||
output pixel format of the subdev, as well as the other
|
||||
parameters with the exception of the image width and height.
|
||||
Width and height are defined by the size of the source pad
|
||||
actual crop selection.</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>Accessing any of the above rectangles not supported by the
|
||||
subdev will return <constant>EINVAL</constant>. Any rectangle
|
||||
referring to a previous unsupported rectangle coordinates will
|
||||
instead refer to the previous supported rectangle. For example,
|
||||
if sink crop is not supported, the compose selection will refer
|
||||
to the sink pad format dimensions instead.</para>
|
||||
|
||||
<figure id="subdev-image-processing-crop">
|
||||
<title>Image processing in subdevs: simple crop example</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="subdev-image-processing-crop.svg"
|
||||
format="SVG" scale="200" />
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
|
||||
<para>In the above example, the subdev supports cropping on its
|
||||
sink pad. To configure it, the user sets the media bus format on
|
||||
the subdev's sink pad. Now the actual crop rectangle can be set
|
||||
on the sink pad --- the location and size of this rectangle
|
||||
reflect the location and size of a rectangle to be cropped from
|
||||
the sink format. The size of the sink crop rectangle will also
|
||||
be the size of the format of the subdev's source pad.</para>
|
||||
|
||||
<figure id="subdev-image-processing-scaling-multi-source">
|
||||
<title>Image processing in subdevs: scaling with multiple sources</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="subdev-image-processing-scaling-multi-source.svg"
|
||||
format="SVG" scale="200" />
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
|
||||
<para>In this example, the subdev is capable of first cropping,
|
||||
then scaling and finally cropping for two source pads
|
||||
individually from the resulting scaled image. The location of
|
||||
the scaled image in the cropped image is ignored in sink compose
|
||||
target. Both of the locations of the source crop rectangles
|
||||
refer to the sink scaling rectangle, independently cropping an
|
||||
area at location specified by the source crop rectangle from
|
||||
it.</para>
|
||||
|
||||
<figure id="subdev-image-processing-full">
|
||||
<title>Image processing in subdevs: scaling and composition
|
||||
with multiple sinks and sources</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="subdev-image-processing-full.svg"
|
||||
format="SVG" scale="200" />
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
|
||||
<para>The subdev driver supports two sink pads and two source
|
||||
pads. The images from both of the sink pads are individually
|
||||
cropped, then scaled and further composed on the composition
|
||||
bounds rectangle. From that, two independent streams are cropped
|
||||
and sent out of the subdev from the source pads.</para>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
&sub-subdev-formats;
|
||||
|
|
|
@ -543,12 +543,13 @@ and can range from zero to the number of buffers allocated
|
|||
with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-buf-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>Type of the buffer, same as &v4l2-format;
|
||||
<structfield>type</structfield> or &v4l2-requestbuffers;
|
||||
<structfield>type</structfield>, set by the application.</entry>
|
||||
<structfield>type</structfield>, set by the application. See <xref
|
||||
linkend="v4l2-buf-type" /></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
@ -568,7 +569,7 @@ refers to an input stream, applications when an output stream.</entry>
|
|||
linkend="buffer-flags" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-field;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>field</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>Indicates the field order of the image in the
|
||||
|
@ -630,11 +631,12 @@ bandwidth. These devices identify by not enumerating any video
|
|||
standards, see <xref linkend="standard" />.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-memory;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>memory</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>This field must be set by applications and/or drivers
|
||||
in accordance with the selected I/O method.</entry>
|
||||
in accordance with the selected I/O method. See <xref linkend="v4l2-memory"
|
||||
/></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>union</entry>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<refentry>
|
||||
<refentry id="pixfmt-srggb10">
|
||||
<refmeta>
|
||||
<refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'),
|
||||
V4L2_PIX_FMT_SGRBG10 ('BA10'),
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<refentry id="pixfmt-srggb10dpcm8">
|
||||
<refmeta>
|
||||
<refentrytitle>
|
||||
V4L2_PIX_FMT_SBGGR10DPCM8 ('bBA8'),
|
||||
V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'),
|
||||
V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'),
|
||||
V4L2_PIX_FMT_SRGGB10DPCM8 ('bRA8'),
|
||||
</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname id="V4L2-PIX-FMT-SBGGR10DPCM8"><constant>V4L2_PIX_FMT_SBGGR10DPCM8</constant></refname>
|
||||
<refname id="V4L2-PIX-FMT-SGBRG10DPCM8"><constant>V4L2_PIX_FMT_SGBRG10DPCM8</constant></refname>
|
||||
<refname id="V4L2-PIX-FMT-SGRBG10DPCM8"><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></refname>
|
||||
<refname id="V4L2-PIX-FMT-SRGGB10DPCM8"><constant>V4L2_PIX_FMT_SRGGB10DPCM8</constant></refname>
|
||||
<refpurpose>10-bit Bayer formats compressed to 8 bits</refpurpose>
|
||||
</refnamediv>
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>The following four pixel formats are raw sRGB / Bayer formats
|
||||
with 10 bits per colour compressed to 8 bits each, using DPCM
|
||||
compression. DPCM, differential pulse-code modulation, is lossy.
|
||||
Each colour component consumes 8 bits of memory. In other respects
|
||||
this format is similar to <xref
|
||||
linkend="pixfmt-srggb10">.</xref></para>
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
|
@ -673,6 +673,7 @@ access the palette, this must be done with ioctls of the Linux framebuffer API.<
|
|||
&sub-srggb8;
|
||||
&sub-sbggr16;
|
||||
&sub-srggb10;
|
||||
&sub-srggb10dpcm8;
|
||||
&sub-srggb12;
|
||||
</section>
|
||||
|
||||
|
@ -876,11 +877,6 @@ kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm
|
|||
<entry>'S561'</entry>
|
||||
<entry>Compressed GBRG Bayer format used by the gspca driver.</entry>
|
||||
</row>
|
||||
<row id="V4L2-PIX-FMT-SGRBG10DPCM8">
|
||||
<entry><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></entry>
|
||||
<entry>'DB10'</entry>
|
||||
<entry>10 bit raw Bayer DPCM compressed to 8 bits.</entry>
|
||||
</row>
|
||||
<row id="V4L2-PIX-FMT-PAC207">
|
||||
<entry><constant>V4L2_PIX_FMT_PAC207</constant></entry>
|
||||
<entry>'P207'</entry>
|
||||
|
|
|
@ -0,0 +1,614 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
|
||||
<dia:diagramdata>
|
||||
<dia:attribute name="background">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pagebreak">
|
||||
<dia:color val="#000099"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="paper">
|
||||
<dia:composite type="paper">
|
||||
<dia:attribute name="name">
|
||||
<dia:string>#A4#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="tmargin">
|
||||
<dia:real val="2.8222000598907471"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="bmargin">
|
||||
<dia:real val="2.8222000598907471"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="lmargin">
|
||||
<dia:real val="2.8222000598907471"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="rmargin">
|
||||
<dia:real val="2.8222000598907471"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="is_portrait">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="scaling">
|
||||
<dia:real val="0.49000000953674316"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fitto">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="grid">
|
||||
<dia:composite type="grid">
|
||||
<dia:attribute name="width_x">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="width_y">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_x">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="visible_y">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:composite type="color"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#d8e5e5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="guides">
|
||||
<dia:composite type="guides">
|
||||
<dia:attribute name="hguides"/>
|
||||
<dia:attribute name="vguides"/>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
</dia:diagramdata>
|
||||
<dia:layer name="Background" visible="true" active="true">
|
||||
<dia:object type="Standard - Box" version="0" id="O0">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="-0.4,6.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="-0.45,6.45;23.1387,16.2"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="-0.4,6.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="23.48871579904775"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="9.6500000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="border_width">
|
||||
<dia:real val="0.10000000149011612"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O1">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="0.225,9.45"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="0.175,9.4;8.225,14.7"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="0.225,9.45"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="7.9499999999999975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="5.1999999999999975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="border_width">
|
||||
<dia:real val="0.10000000149011612"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="border_color">
|
||||
<dia:color val="#a52a2a"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O2">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="3.175,10.55"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.125,10.5;7.925,14.45"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="3.175,10.55"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="4.6999999999999975"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.8499999999999979"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="border_width">
|
||||
<dia:real val="0.10000000149011612"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="border_color">
|
||||
<dia:color val="#0000ff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O3">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="3.725,11.3875"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.725,10.7925;6.6025,13.14"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#sink
|
||||
crop
|
||||
selection#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="3.725,11.3875"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#0000ff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O4">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="1.475,7.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="1.475,7.305;1.475,8.0525"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>##</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="1.475,7.9"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O5">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="0.426918,7.89569"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="0.426918,7.30069;3.90942,8.84819"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#sink media
|
||||
bus format#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="0.426918,7.89569"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#a52a2a"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O6">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="17.4887,7.75"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="17.4887,7.155;21.8112,8.7025"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#source media
|
||||
bus format#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="17.4887,7.75"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#8b6914"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Box" version="0" id="O7">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="17.5244,9.5417"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="17.4744,9.4917;22.2387,13.35"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="17.5244,9.5417"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="4.6643157990477508"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="3.758300000000002"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="border_width">
|
||||
<dia:real val="0.10000000149011612"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="border_color">
|
||||
<dia:color val="#8b6914"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O8">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="17.5244,13.3"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.12132,13.2463;17.5781,14.4537"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="17.5244,13.3"/>
|
||||
<dia:point val="3.175,14.4"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_color">
|
||||
<dia:color val="#e60505"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_style">
|
||||
<dia:enum val="4"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O7" connection="5"/>
|
||||
<dia:connection handle="1" to="O2" connection="5"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O9">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="17.5244,9.5417"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="3.12162,9.48832;17.5778,10.6034"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="17.5244,9.5417"/>
|
||||
<dia:point val="3.175,10.55"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_color">
|
||||
<dia:color val="#e60505"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_style">
|
||||
<dia:enum val="4"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O7" connection="0"/>
|
||||
<dia:connection handle="1" to="O2" connection="0"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O10">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="22.1887,13.3"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="7.82132,13.2463;22.2424,14.4537"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="22.1887,13.3"/>
|
||||
<dia:point val="7.875,14.4"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_color">
|
||||
<dia:color val="#e60505"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_style">
|
||||
<dia:enum val="4"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O7" connection="7"/>
|
||||
<dia:connection handle="1" to="O2" connection="7"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O11">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="22.1887,9.5417"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="7.82161,9.48831;22.2421,10.6034"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="22.1887,9.5417"/>
|
||||
<dia:point val="7.875,10.55"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_color">
|
||||
<dia:color val="#e60505"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_style">
|
||||
<dia:enum val="4"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O7" connection="2"/>
|
||||
<dia:connection handle="1" to="O2" connection="2"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Geometric - Perfect Circle" version="1" id="O12">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="23.23,10.5742"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="23.18,10.5242;24.13,11.4742"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="meta">
|
||||
<dia:composite type="dict"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="23.23,10.5742"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="0.84999999999999787"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="0.84999999999999787"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_width">
|
||||
<dia:real val="0.10000000000000001"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_colour">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fill_colour">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_style">
|
||||
<dia:enum val="0"/>
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="flip_horizontal">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="flip_vertical">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="subscale">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O13">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="24.08,10.9992"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="24.03,10.6388;32.4953,11.3624"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="24.08,10.9992"/>
|
||||
<dia:point val="32.3835,11.0007"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow">
|
||||
<dia:enum val="22"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow_length">
|
||||
<dia:real val="0.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow_width">
|
||||
<dia:real val="0.5"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="0" to="O12" connection="3"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O14">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="25.3454,10.49"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="25.3454,9.895;29.9904,10.6425"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#pad 1 (source)#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="25.3454,10.49"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Geometric - Perfect Circle" version="1" id="O15">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="-1.44491,11.6506"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="-1.49491,11.6006;-0.54491,12.5506"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="meta">
|
||||
<dia:composite type="dict"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_corner">
|
||||
<dia:point val="-1.44491,11.6506"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_width">
|
||||
<dia:real val="0.84999999999999787"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="elem_height">
|
||||
<dia:real val="0.84999999999999787"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_width">
|
||||
<dia:real val="0.10000000000000001"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_colour">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="fill_colour">
|
||||
<dia:color val="#ffffff"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="show_background">
|
||||
<dia:boolean val="true"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="line_style">
|
||||
<dia:enum val="0"/>
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="flip_horizontal">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="flip_vertical">
|
||||
<dia:boolean val="false"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="subscale">
|
||||
<dia:real val="1"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Line" version="0" id="O16">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="-9.61991,12.09"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="-9.67,11.7149;-1.33311,12.4385"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="conn_endpoints">
|
||||
<dia:point val="-9.61991,12.09"/>
|
||||
<dia:point val="-1.44491,12.0756"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="numcp">
|
||||
<dia:int val="1"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow">
|
||||
<dia:enum val="22"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow_length">
|
||||
<dia:real val="0.5"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="end_arrow_width">
|
||||
<dia:real val="0.5"/>
|
||||
</dia:attribute>
|
||||
<dia:connections>
|
||||
<dia:connection handle="1" to="O15" connection="2"/>
|
||||
</dia:connections>
|
||||
</dia:object>
|
||||
<dia:object type="Standard - Text" version="1" id="O17">
|
||||
<dia:attribute name="obj_pos">
|
||||
<dia:point val="-7.39291,11.49"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="obj_bb">
|
||||
<dia:rectangle val="-7.39291,10.895;-3.58791,11.6425"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="text">
|
||||
<dia:composite type="text">
|
||||
<dia:attribute name="string">
|
||||
<dia:string>#pad 0 (sink)#</dia:string>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="font">
|
||||
<dia:font family="sans" style="0" name="Helvetica"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="height">
|
||||
<dia:real val="0.80000000000000004"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="pos">
|
||||
<dia:point val="-7.39291,11.49"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="color">
|
||||
<dia:color val="#000000"/>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="alignment">
|
||||
<dia:enum val="0"/>
|
||||
</dia:attribute>
|
||||
</dia:composite>
|
||||
</dia:attribute>
|
||||
<dia:attribute name="valign">
|
||||
<dia:enum val="3"/>
|
||||
</dia:attribute>
|
||||
</dia:object>
|
||||
</dia:layer>
|
||||
</dia:diagram>
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
|
||||
<svg width="43cm" height="10cm" viewBox="-194 128 844 196" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="-8" y="130" width="469.774" height="193"/>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="4.5" y="189" width="159" height="104"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a52a2a" x="4.5" y="189" width="159" height="104"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="63.5" y="211" width="94" height="77"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x="63.5" y="211" width="94" height="77"/>
|
||||
</g>
|
||||
<text style="fill: #0000ff;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="74.5" y="227.75">
|
||||
<tspan x="74.5" y="227.75">sink</tspan>
|
||||
<tspan x="74.5" y="243.75">crop</tspan>
|
||||
<tspan x="74.5" y="259.75">selection</tspan>
|
||||
</text>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="29.5" y="158">
|
||||
<tspan x="29.5" y="158"></tspan>
|
||||
</text>
|
||||
<text style="fill: #a52a2a;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="8.53836" y="157.914">
|
||||
<tspan x="8.53836" y="157.914">sink media</tspan>
|
||||
<tspan x="8.53836" y="173.914">bus format</tspan>
|
||||
</text>
|
||||
<text style="fill: #8b6914;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="349.774" y="155">
|
||||
<tspan x="349.774" y="155">source media</tspan>
|
||||
<tspan x="349.774" y="171">bus format</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="350.488" y="190.834" width="93.2863" height="75.166"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="350.488" y="190.834" width="93.2863" height="75.166"/>
|
||||
</g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="350.488" y1="266" x2="63.5" y2="288"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="350.488" y1="190.834" x2="63.5" y2="211"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="443.774" y1="266" x2="157.5" y2="288"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="443.774" y1="190.834" x2="157.5" y2="211"/>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="473.1" cy="219.984" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="473.1" cy="219.984" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="473.1" cy="219.984" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="481.6" y1="219.984" x2="637.934" y2="220.012"/>
|
||||
<polygon style="fill: #000000" points="645.434,220.014 635.433,225.012 637.934,220.012 635.435,215.012 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="645.434,220.014 635.433,225.012 637.934,220.012 635.435,215.012 "/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="506.908" y="209.8">
|
||||
<tspan x="506.908" y="209.8">pad 1 (source)</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="-192.398" y1="241.8" x2="-38.6343" y2="241.529"/>
|
||||
<polygon style="fill: #000000" points="-31.1343,241.516 -41.1254,246.534 -38.6343,241.529 -41.1431,236.534 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="-31.1343,241.516 -41.1254,246.534 -38.6343,241.529 -41.1431,236.534 "/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="-147.858" y="229.8">
|
||||
<tspan x="-147.858" y="229.8">pad 0 (sink)</tspan>
|
||||
</text>
|
||||
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
|
||||
<svg width="59cm" height="18cm" viewBox="-186 71 1178 346" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="318.9" y="129" width="208.1" height="249"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff765a" x="318.9" y="129" width="208.1" height="249"/>
|
||||
</g>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="-2" y="73" width="806" height="343"/>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="-12.5" cy="166.712" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-12.5" cy="166.712" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-12.5" cy="166.712" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="815.232" cy="205.184" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="815.232" cy="205.184" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="815.232" cy="205.184" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="-184.5" y1="167" x2="-30.7361" y2="166.729"/>
|
||||
<polygon style="fill: #000000" points="-23.2361,166.716 -33.2272,171.734 -30.7361,166.729 -33.2449,161.734 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="-23.2361,166.716 -33.2272,171.734 -30.7361,166.729 -33.2449,161.734 "/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="823.732" y1="205.184" x2="980.066" y2="205.212"/>
|
||||
<polygon style="fill: #000000" points="987.566,205.214 977.565,210.212 980.066,205.212 977.567,200.212 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="987.566,205.214 977.565,210.212 980.066,205.212 977.567,200.212 "/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="-139.96" y="155">
|
||||
<tspan x="-139.96" y="155">pad 0 (sink)</tspan>
|
||||
</text>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="849.04" y="195">
|
||||
<tspan x="849.04" y="195">pad 2 (source)</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="5.5" y="120" width="159" height="104"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a52a2a" x="5.5" y="120" width="159" height="104"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="62.5" y="136" width="94" height="77"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x="62.5" y="136" width="94" height="77"/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="30.5" y="89">
|
||||
<tspan x="30.5" y="89"></tspan>
|
||||
</text>
|
||||
<text style="fill: #a52a2a;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="9.53836" y="88.9138">
|
||||
<tspan x="9.53836" y="88.9138">sink media</tspan>
|
||||
<tspan x="9.53836" y="104.914">bus format</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="333.644" y="185.65" width="165.2" height="172.478"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" x="333.644" y="185.65" width="165.2" height="172.478"/>
|
||||
</g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="333.644" y1="358.128" x2="62.5" y2="213"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="333.644" y1="185.65" x2="62.5" y2="136"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="498.844" y1="358.128" x2="156.5" y2="213"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="498.844" y1="185.65" x2="156.5" y2="136"/>
|
||||
<text style="fill: #00ff00;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="334.704" y="149.442">
|
||||
<tspan x="334.704" y="149.442">sink compose</tspan>
|
||||
<tspan x="334.704" y="165.442">selection (scaling)</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="409.322" y="194.565" width="100.186" height="71.4523"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x="409.322" y="194.565" width="100.186" height="71.4523"/>
|
||||
</g>
|
||||
<text style="fill: #8b6914;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="689.5" y="105.128">
|
||||
<tspan x="689.5" y="105.128">source media</tspan>
|
||||
<tspan x="689.5" y="121.128">bus format</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="688.488" y="173.834" width="100.186" height="71.4523"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="688.488" y="173.834" width="100.186" height="71.4523"/>
|
||||
</g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="688.488" y1="245.286" x2="409.322" y2="266.018"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="688.488" y1="173.834" x2="409.322" y2="194.565"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="788.674" y1="245.286" x2="509.508" y2="266.018"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="788.674" y1="173.834" x2="509.508" y2="194.565"/>
|
||||
<text style="fill: #ff765a;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="325" y="103">
|
||||
<tspan x="325" y="103">sink compose</tspan>
|
||||
<tspan x="325" y="119">bounds selection</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="-12.0982" cy="341.512" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-12.0982" cy="341.512" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-12.0982" cy="341.512" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="-184.098" y1="341.8" x2="-30.3343" y2="341.529"/>
|
||||
<polygon style="fill: #000000" points="-22.8343,341.516 -32.8254,346.534 -30.3343,341.529 -32.8431,336.534 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="-22.8343,341.516 -32.8254,346.534 -30.3343,341.529 -32.8431,336.534 "/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="-139" y="329">
|
||||
<tspan x="-139" y="329">pad 1 (sink)</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="7.80824" y="292.8" width="112.092" height="82.2"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a52a2a" x="7.80824" y="292.8" width="112.092" height="82.2"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="52.9" y="314.8" width="58.1" height="50.2"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x="52.9" y="314.8" width="58.1" height="50.2"/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="31.9" y="259.8">
|
||||
<tspan x="31.9" y="259.8"></tspan>
|
||||
</text>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="358.9" y1="251.9" x2="52.9" y2="314.8"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="358.9" y1="316" x2="52.9" y2="365"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="434" y1="316" x2="111" y2="365"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="434" y1="251.9" x2="111" y2="314.8"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" x="358.9" y="251.9" width="75.1" height="64.1"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x="443.262" y="284.466" width="64.738" height="48.534"/>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="693.428" y="324.734" width="63.572" height="49.266"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="693.428" y="324.734" width="63.572" height="49.266"/>
|
||||
</g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="693.428" y1="374" x2="443.262" y2="333"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="693.428" y1="324.734" x2="443.262" y2="284.466"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="757" y1="374" x2="508" y2="333"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="757" y1="324.734" x2="508" y2="284.466"/>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="815.44" cy="343.984" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="815.44" cy="343.984" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="815.44" cy="343.984" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="823.94" y1="343.984" x2="980.274" y2="344.012"/>
|
||||
<polygon style="fill: #000000" points="987.774,344.014 977.773,349.012 980.274,344.012 977.775,339.012 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="987.774,344.014 977.773,349.012 980.274,344.012 977.775,339.012 "/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="849.248" y="333.8">
|
||||
<tspan x="849.248" y="333.8">pad 3 (source)</tspan>
|
||||
</text>
|
||||
<text style="fill: #0000ff;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="197" y="91">
|
||||
<tspan x="197" y="91">sink</tspan>
|
||||
<tspan x="197" y="107">crop</tspan>
|
||||
<tspan x="197" y="123">selection</tspan>
|
||||
</text>
|
||||
<text style="fill: #a020f0;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="553" y="95">
|
||||
<tspan x="553" y="95">source</tspan>
|
||||
<tspan x="553" y="111">crop</tspan>
|
||||
<tspan x="553" y="127">selection</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x1="211" y1="132" x2="166.21" y2="135.287"/>
|
||||
<polygon style="fill: #0000ff" points="158.73,135.836 168.337,130.118 166.21,135.287 169.069,140.091 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" points="158.73,135.836 168.337,130.118 166.21,135.287 169.069,140.091 "/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x1="209" y1="131" x2="115.581" y2="306.209"/>
|
||||
<polygon style="fill: #0000ff" points="112.052,312.827 112.345,301.65 115.581,306.209 121.169,306.355 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" points="112.052,312.827 112.345,301.65 115.581,306.209 121.169,306.355 "/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x1="550.492" y1="133.214" x2="514.916" y2="186.469"/>
|
||||
<polygon style="fill: #a020f0" points="510.75,192.706 512.147,181.613 514.916,186.469 520.463,187.168 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" points="510.75,192.706 512.147,181.613 514.916,186.469 520.463,187.168 "/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x1="550.072" y1="133.787" x2="510.618" y2="275.089"/>
|
||||
<polygon style="fill: #a020f0" points="508.601,282.312 506.475,271.336 510.618,275.089 516.106,274.025 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" points="508.601,282.312 506.475,271.336 510.618,275.089 516.106,274.025 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,116 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
|
||||
<svg width="59cm" height="17cm" viewBox="-194 128 1179 330" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="-8" y="130" width="806" height="327"/>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="4.5" y="189" width="159" height="104"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a52a2a" x="4.5" y="189" width="159" height="104"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="49.5" y="204" width="94" height="77"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #0000ff" x="49.5" y="204" width="94" height="77"/>
|
||||
</g>
|
||||
<text style="fill: #0000ff;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="60" y="224">
|
||||
<tspan x="60" y="224">sink</tspan>
|
||||
<tspan x="60" y="240">crop</tspan>
|
||||
<tspan x="60" y="256">selection</tspan>
|
||||
</text>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="29.5" y="158">
|
||||
<tspan x="29.5" y="158"></tspan>
|
||||
</text>
|
||||
<text style="fill: #a52a2a;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="8.53836" y="157.914">
|
||||
<tspan x="8.53836" y="157.914">sink media</tspan>
|
||||
<tspan x="8.53836" y="173.914">bus format</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="333.644" y="185.65" width="165.2" height="172.478"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #00ff00" x="333.644" y="185.65" width="165.2" height="172.478"/>
|
||||
</g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="333.644" y1="358.128" x2="49.5" y2="281"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="333.644" y1="185.65" x2="49.5" y2="204"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="498.844" y1="358.128" x2="143.5" y2="281"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="498.844" y1="185.65" x2="143.5" y2="204"/>
|
||||
<text style="fill: #00ff00;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="334.704" y="149.442">
|
||||
<tspan x="334.704" y="149.442">sink compose</tspan>
|
||||
<tspan x="334.704" y="165.442">selection (scaling)</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="382.322" y="199.565" width="100.186" height="71.4523"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x="382.322" y="199.565" width="100.186" height="71.4523"/>
|
||||
</g>
|
||||
<text style="fill: #a020f0;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="543.322" y="149.442">
|
||||
<tspan x="543.322" y="149.442">source</tspan>
|
||||
<tspan x="543.322" y="165.442">crop</tspan>
|
||||
<tspan x="543.322" y="181.442">selection</tspan>
|
||||
</text>
|
||||
<text style="fill: #8b6914;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="691.5" y="157.128">
|
||||
<tspan x="691.5" y="157.128">source media</tspan>
|
||||
<tspan x="691.5" y="173.128">bus format</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="690.488" y="225.834" width="100.186" height="71.4523"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="690.488" y="225.834" width="100.186" height="71.4523"/>
|
||||
</g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="690.488" y1="297.286" x2="382.322" y2="271.018"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="690.488" y1="225.834" x2="382.322" y2="199.565"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="790.674" y1="297.286" x2="482.508" y2="271.018"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="790.674" y1="225.834" x2="482.508" y2="199.565"/>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="808.1" cy="249.984" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="808.1" cy="249.984" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="808.1" cy="249.984" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="816.6" y1="249.984" x2="972.934" y2="250.012"/>
|
||||
<polygon style="fill: #000000" points="980.434,250.014 970.433,255.012 972.934,250.012 970.435,245.012 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="980.434,250.014 970.433,255.012 972.934,250.012 970.435,245.012 "/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="841.908" y="239.8">
|
||||
<tspan x="841.908" y="239.8">pad 1 (source)</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="-20.3982" cy="241.512" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="-192.398" y1="241.8" x2="-38.6343" y2="241.529"/>
|
||||
<polygon style="fill: #000000" points="-31.1343,241.516 -41.1254,246.534 -38.6343,241.529 -41.1431,236.534 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="-31.1343,241.516 -41.1254,246.534 -38.6343,241.529 -41.1431,236.534 "/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="-147.858" y="229.8">
|
||||
<tspan x="-147.858" y="229.8">pad 0 (sink)</tspan>
|
||||
</text>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x="389.822" y="276.666" width="100.186" height="71.4523"/>
|
||||
<g>
|
||||
<rect style="fill: #ffffff" x="689.988" y="345.934" width="100.186" height="71.4523"/>
|
||||
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #8b6914" x="689.988" y="345.934" width="100.186" height="71.4523"/>
|
||||
</g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="689.988" y1="417.386" x2="389.822" y2="348.118"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="689.988" y1="345.934" x2="389.822" y2="276.666"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="790.174" y1="417.386" x2="490.008" y2="348.118"/>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 4; stroke: #e60505" x1="790.174" y1="345.934" x2="490.008" y2="276.666"/>
|
||||
<g>
|
||||
<ellipse style="fill: #ffffff" cx="805.6" cy="384.084" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="805.6" cy="384.084" rx="8.5" ry="8.5"/>
|
||||
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="805.6" cy="384.084" rx="8.5" ry="8.5"/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x1="814.1" y1="384.084" x2="970.434" y2="384.112"/>
|
||||
<polygon style="fill: #000000" points="977.934,384.114 967.933,389.112 970.434,384.112 967.935,379.112 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="977.934,384.114 967.933,389.112 970.434,384.112 967.935,379.112 "/>
|
||||
</g>
|
||||
<text style="fill: #000000;text-anchor:start;font-size:12.8;font-family:sanserif;font-style:normal;font-weight:normal" x="839.408" y="373.9">
|
||||
<tspan x="839.408" y="373.9">pad 2 (source)</tspan>
|
||||
</text>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x1="546" y1="191" x2="492.157" y2="198.263"/>
|
||||
<polygon style="fill: #a020f0" points="484.724,199.266 493.966,192.974 492.157,198.263 495.303,202.884 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" points="484.724,199.266 493.966,192.974 492.157,198.263 495.303,202.884 "/>
|
||||
</g>
|
||||
<g>
|
||||
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" x1="546.908" y1="190.725" x2="495.383" y2="268.548"/>
|
||||
<polygon style="fill: #a020f0" points="491.242,274.802 492.594,263.703 495.383,268.548 500.932,269.224 "/>
|
||||
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #a020f0" points="491.242,274.802 492.594,263.703 495.383,268.548 500.932,269.224 "/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.8 KiB |
|
@ -28,8 +28,8 @@ documentation.</contrib>
|
|||
<firstname>Hans</firstname>
|
||||
<surname>Verkuil</surname>
|
||||
<contrib>Designed and documented the VIDIOC_LOG_STATUS ioctl,
|
||||
the extended control ioctls and major parts of the sliced VBI
|
||||
API.</contrib>
|
||||
the extended control ioctls, major parts of the sliced VBI API, the
|
||||
MPEG encoder and decoder APIs and the DV Timings API.</contrib>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>hverkuil@xs4all.nl</email>
|
||||
|
@ -96,6 +96,17 @@ Remote Controller chapter.</contrib>
|
|||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
|
||||
<author>
|
||||
<firstname>Sakari</firstname>
|
||||
<surname>Ailus</surname>
|
||||
<contrib>Subdev selections API.</contrib>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>sakari.ailus@iki.fi</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
|
@ -112,6 +123,7 @@ Remote Controller chapter.</contrib>
|
|||
<year>2009</year>
|
||||
<year>2010</year>
|
||||
<year>2011</year>
|
||||
<year>2012</year>
|
||||
<holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
|
||||
Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
|
||||
Pawel Osciak</holder>
|
||||
|
@ -127,6 +139,28 @@ 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.5</revnumber>
|
||||
<date>2012-05-07</date>
|
||||
<authorinitials>sa, sn</authorinitials>
|
||||
<revremark>Added V4L2_CTRL_TYPE_INTEGER_MENU and V4L2 subdev
|
||||
selections API. Improved the description of V4L2_CID_COLORFX
|
||||
control, added V4L2_CID_COLORFX_CBCR control.
|
||||
Added camera controls V4L2_CID_AUTO_EXPOSURE_BIAS,
|
||||
V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, V4L2_CID_IMAGE_STABILIZATION,
|
||||
V4L2_CID_ISO_SENSITIVITY, V4L2_CID_ISO_SENSITIVITY_AUTO,
|
||||
V4L2_CID_EXPOSURE_METERING, V4L2_CID_SCENE_MODE,
|
||||
V4L2_CID_3A_LOCK, V4L2_CID_AUTO_FOCUS_START,
|
||||
V4L2_CID_AUTO_FOCUS_STOP, V4L2_CID_AUTO_FOCUS_STATUS
|
||||
and V4L2_CID_AUTO_FOCUS_RANGE.
|
||||
</revremark>
|
||||
<date>2012-05-01</date>
|
||||
<authorinitials>hv</authorinitials>
|
||||
<revremark>Added VIDIOC_ENUM_DV_TIMINGS, VIDIOC_QUERY_DV_TIMINGS and
|
||||
VIDIOC_DV_TIMINGS_CAP.
|
||||
</revremark>
|
||||
</revision>
|
||||
|
||||
<revision>
|
||||
<revnumber>3.4</revnumber>
|
||||
<date>2012-01-25</date>
|
||||
|
@ -433,7 +467,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||
</partinfo>
|
||||
|
||||
<title>Video for Linux Two API Specification</title>
|
||||
<subtitle>Revision 3.3</subtitle>
|
||||
<subtitle>Revision 3.5</subtitle>
|
||||
|
||||
<chapter id="common">
|
||||
&sub-common;
|
||||
|
@ -491,10 +525,12 @@ and discussions on the V4L mailing list.</revremark>
|
|||
&sub-dbg-g-register;
|
||||
&sub-decoder-cmd;
|
||||
&sub-dqevent;
|
||||
&sub-dv-timings-cap;
|
||||
&sub-encoder-cmd;
|
||||
&sub-enumaudio;
|
||||
&sub-enumaudioout;
|
||||
&sub-enum-dv-presets;
|
||||
&sub-enum-dv-timings;
|
||||
&sub-enum-fmt;
|
||||
&sub-enum-framesizes;
|
||||
&sub-enum-frameintervals;
|
||||
|
@ -529,6 +565,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||
&sub-querycap;
|
||||
&sub-queryctrl;
|
||||
&sub-query-dv-preset;
|
||||
&sub-query-dv-timings;
|
||||
&sub-querystd;
|
||||
&sub-prepare-buf;
|
||||
&sub-reqbufs;
|
||||
|
@ -540,6 +577,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||
&sub-subdev-g-crop;
|
||||
&sub-subdev-g-fmt;
|
||||
&sub-subdev-g-frame-interval;
|
||||
&sub-subdev-g-selection;
|
||||
&sub-subscribe-event;
|
||||
<!-- End of ioctls. -->
|
||||
&sub-mmap;
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
<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>This ioctl is used to create buffers for <link linkend="mmap">memory
|
||||
mapped</link> or <link linkend="userp">user pointer</link>
|
||||
I/O. It can be used as an alternative or in addition to the
|
||||
|
@ -94,16 +100,18 @@ information.</para>
|
|||
<entry>The number of buffers requested or granted.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-memory;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>memory</structfield></entry>
|
||||
<entry>Applications set this field to
|
||||
<constant>V4L2_MEMORY_MMAP</constant> or
|
||||
<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
|
||||
<constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory"
|
||||
/></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-format;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>format</structfield></entry>
|
||||
<entry>Filled in by the application, preserved by the driver.</entry>
|
||||
<entry>Filled in by the application, preserved by the driver.
|
||||
See <xref linkend="v4l2-format" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
|
|
@ -65,7 +65,7 @@ output.</para>
|
|||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>&v4l2-buf-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>Type of the data stream, set by the application.
|
||||
Only these types are valid here:
|
||||
|
@ -73,7 +73,7 @@ Only these types are valid here:
|
|||
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
|
||||
<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
|
||||
defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
|
||||
and higher.</entry>
|
||||
and higher. See <xref linkend="v4l2-buf-type" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
<refentry id="vidioc-dv-timings-cap">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_DV_TIMINGS_CAP</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>VIDIOC_DV_TIMINGS_CAP</refname>
|
||||
<refpurpose>The capabilities of the Digital Video receiver/transmitter</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_timings_cap *<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_DV_TIMINGS_CAP</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>To query the available timings, applications initialize the
|
||||
<structfield>index</structfield> field and zero the reserved array of &v4l2-dv-timings-cap;
|
||||
and call the <constant>VIDIOC_DV_TIMINGS_CAP</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 supported DV timings,
|
||||
applications shall begin at index zero, incrementing by one until the
|
||||
driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a
|
||||
different set of DV timings after switching the video input or
|
||||
output.</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-bt-timings-cap">
|
||||
<title>struct <structname>v4l2_bt_timings_cap</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>min_width</structfield></entry>
|
||||
<entry>Minimum width of the active video in pixels.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>max_width</structfield></entry>
|
||||
<entry>Maximum width of the active video in pixels.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>min_height</structfield></entry>
|
||||
<entry>Minimum height of the active video in lines.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>max_height</structfield></entry>
|
||||
<entry>Maximum height of the active video in lines.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u64</entry>
|
||||
<entry><structfield>min_pixelclock</structfield></entry>
|
||||
<entry>Minimum pixelclock frequency in Hz.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u64</entry>
|
||||
<entry><structfield>max_pixelclock</structfield></entry>
|
||||
<entry>Maximum pixelclock frequency in Hz.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>standards</structfield></entry>
|
||||
<entry>The video standard(s) supported by the hardware.
|
||||
See <xref linkend="dv-bt-standards"/> for a list of standards.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>capabilities</structfield></entry>
|
||||
<entry>Several flags giving more information about the capabilities.
|
||||
See <xref linkend="dv-bt-cap-capabilities"/> for a description of the flags.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved</structfield>[16]</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-dv-timings-cap">
|
||||
<title>struct <structname>v4l2_dv_timings_cap</structname></title>
|
||||
<tgroup cols="4">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>Type of DV timings as listed in <xref linkend="dv-timing-types"/>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved</structfield>[3]</entry>
|
||||
<entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>union</entry>
|
||||
<entry><structfield></structfield></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>&v4l2-bt-timings-cap;</entry>
|
||||
<entry><structfield>bt</structfield></entry>
|
||||
<entry>BT.656/1120 timings capabilities of the hardware.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>raw_data</structfield>[32]</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table pgwide="1" frame="none" id="dv-bt-cap-capabilities">
|
||||
<title>DV BT Timing capabilities</title>
|
||||
<tgroup cols="2">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>Flag</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_CAP_INTERLACED</entry>
|
||||
<entry>Interlaced formats are supported.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_CAP_PROGRESSIVE</entry>
|
||||
<entry>Progressive formats are supported.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_CAP_REDUCED_BLANKING</entry>
|
||||
<entry>CVT/GTF specific: the timings can make use of reduced blanking (CVT)
|
||||
or the 'Secondary GTF' curve (GTF).
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_CAP_CUSTOM</entry>
|
||||
<entry>Can support non-standard timings, i.e. timings not belonging to the
|
||||
standards set in the <structfield>standards</structfield> field.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
&return-value;
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: "v4l2.sgml"
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
-->
|
|
@ -48,6 +48,10 @@
|
|||
<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
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
<refentry id="vidioc-enum-dv-timings">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_ENUM_DV_TIMINGS</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>VIDIOC_ENUM_DV_TIMINGS</refname>
|
||||
<refpurpose>Enumerate supported Digital Video timings</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_enum_dv_timings *<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_TIMINGS</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>While some DV receivers or transmitters support a wide range of timings, others
|
||||
support only a limited number of timings. With this ioctl applications can enumerate a list
|
||||
of known supported timings. Call &VIDIOC-DV-TIMINGS-CAP; to check if it also supports other
|
||||
standards or even custom timings that are not in this list.</para>
|
||||
|
||||
<para>To query the available timings, applications initialize the
|
||||
<structfield>index</structfield> field and zero the reserved array of &v4l2-enum-dv-timings;
|
||||
and call the <constant>VIDIOC_ENUM_DV_TIMINGS</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 supported DV timings,
|
||||
applications shall begin at index zero, incrementing by one until the
|
||||
driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a
|
||||
different set of DV timings after switching the video input or
|
||||
output.</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-enum-dv-timings">
|
||||
<title>struct <structname>v4l2_enum_dv_timings</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>index</structfield></entry>
|
||||
<entry>Number of the DV timings, set by the
|
||||
application.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved</structfield>[3]</entry>
|
||||
<entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-dv-timings;</entry>
|
||||
<entry><structfield>timings</structfield></entry>
|
||||
<entry>The timings.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
&return-value;
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><errorcode>EINVAL</errorcode></term>
|
||||
<listitem>
|
||||
<para>The &v4l2-enum-dv-timings; <structfield>index</structfield>
|
||||
is out of bounds.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: "v4l2.sgml"
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
-->
|
|
@ -71,7 +71,7 @@ the application. This is in no way related to the <structfield>
|
|||
pixelformat</structfield> field.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-buf-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>Type of the data stream, set by the application.
|
||||
Only these types are valid here:
|
||||
|
@ -81,7 +81,7 @@ Only these types are valid here:
|
|||
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>,
|
||||
<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
|
||||
defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
|
||||
and higher.</entry>
|
||||
and higher. See <xref linkend="v4l2-buf-type" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
|
|
@ -285,7 +285,7 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
|
|||
<row>
|
||||
<entry><constant>V4L2_IN_CAP_CUSTOM_TIMINGS</constant></entry>
|
||||
<entry>0x00000002</entry>
|
||||
<entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
|
||||
<entry>This input supports setting video timings by using VIDIOC_S_DV_TIMINGS.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_IN_CAP_STD</constant></entry>
|
||||
|
|
|
@ -170,7 +170,7 @@ input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
|
|||
<row>
|
||||
<entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
|
||||
<entry>0x00000002</entry>
|
||||
<entry>This output supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
|
||||
<entry>This output supports setting video timings by using VIDIOC_S_DV_TIMINGS.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_OUT_CAP_STD</constant></entry>
|
||||
|
|
|
@ -100,14 +100,14 @@ changed and <constant>VIDIOC_S_CROP</constant> returns the
|
|||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>&v4l2-buf-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>Type of the data stream, set by the application.
|
||||
Only these types are valid here: <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
|
||||
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
|
||||
<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
|
||||
defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
|
||||
and higher.</entry>
|
||||
and higher. See <xref linkend="v4l2-buf-type" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-rect;</entry>
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
|
||||
<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.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<refnamediv>
|
||||
<refname>VIDIOC_G_DV_TIMINGS</refname>
|
||||
<refname>VIDIOC_S_DV_TIMINGS</refname>
|
||||
<refpurpose>Get or set custom DV timings for input or output</refpurpose>
|
||||
<refpurpose>Get or set DV timings for input or output</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
|
@ -48,12 +48,15 @@
|
|||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
<para>To set custom DV timings for the input or output, applications use the
|
||||
<constant>VIDIOC_S_DV_TIMINGS</constant> ioctl and to get the current custom timings,
|
||||
<para>To set DV timings for the input or output, applications use the
|
||||
<constant>VIDIOC_S_DV_TIMINGS</constant> ioctl and to get the current timings,
|
||||
applications use the <constant>VIDIOC_G_DV_TIMINGS</constant> ioctl. The detailed timing
|
||||
information is filled in using the structure &v4l2-dv-timings;. These ioctls take
|
||||
a pointer to the &v4l2-dv-timings; structure as argument. If the ioctl is not supported
|
||||
or the timing values are not correct, the driver returns &EINVAL;.</para>
|
||||
<para>The <filename>linux/v4l2-dv-timings.h</filename> header can be used to get the
|
||||
timings of the formats in the <xref linkend="cea861" /> and <xref linkend="vesadmt" />
|
||||
standards.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
@ -83,12 +86,13 @@ or the timing values are not correct, the driver returns &EINVAL;.</para>
|
|||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>width</structfield></entry>
|
||||
<entry>Width of the active video in pixels</entry>
|
||||
<entry>Width of the active video in pixels.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>height</structfield></entry>
|
||||
<entry>Height of the active video in lines</entry>
|
||||
<entry>Height of the active video frame in lines. So for interlaced formats the
|
||||
height of the active video in each field is <structfield>height</structfield>/2.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
@ -125,32 +129,52 @@ bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_H
|
|||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>vfrontporch</structfield></entry>
|
||||
<entry>Vertical front porch in lines</entry>
|
||||
<entry>Vertical front porch in lines. For interlaced formats this refers to the
|
||||
odd field (aka field 1).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>vsync</structfield></entry>
|
||||
<entry>Vertical sync length in lines</entry>
|
||||
<entry>Vertical sync length in lines. For interlaced formats this refers to the
|
||||
odd field (aka field 1).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>vbackporch</structfield></entry>
|
||||
<entry>Vertical back porch in lines</entry>
|
||||
<entry>Vertical back porch in lines. For interlaced formats this refers to the
|
||||
odd field (aka field 1).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>il_vfrontporch</structfield></entry>
|
||||
<entry>Vertical front porch in lines for bottom field of interlaced field formats</entry>
|
||||
<entry>Vertical front porch in lines for the even field (aka field 2) of
|
||||
interlaced field formats.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>il_vsync</structfield></entry>
|
||||
<entry>Vertical sync length in lines for bottom field of interlaced field formats</entry>
|
||||
<entry>Vertical sync length in lines for the even field (aka field 2) of
|
||||
interlaced field formats.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>il_vbackporch</structfield></entry>
|
||||
<entry>Vertical back porch in lines for bottom field of interlaced field formats</entry>
|
||||
<entry>Vertical back porch in lines for the even field (aka field 2) of
|
||||
interlaced field formats.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>standards</structfield></entry>
|
||||
<entry>The video standard(s) this format belongs to. This will be filled in by
|
||||
the driver. Applications must set this to 0. See <xref linkend="dv-bt-standards"/>
|
||||
for a list of standards.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>flags</structfield></entry>
|
||||
<entry>Several flags giving more information about the format.
|
||||
See <xref linkend="dv-bt-flags"/> for a description of the flags.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
|
@ -211,6 +235,90 @@ bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_H
|
|||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<table pgwide="1" frame="none" id="dv-bt-standards">
|
||||
<title>DV BT Timing standards</title>
|
||||
<tgroup cols="2">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>Timing standard</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_STD_CEA861</entry>
|
||||
<entry>The timings follow the CEA-861 Digital TV Profile standard</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_STD_DMT</entry>
|
||||
<entry>The timings follow the VESA Discrete Monitor Timings standard</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_STD_CVT</entry>
|
||||
<entry>The timings follow the VESA Coordinated Video Timings standard</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_STD_GTF</entry>
|
||||
<entry>The timings follow the VESA Generalized Timings Formula standard</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<table pgwide="1" frame="none" id="dv-bt-flags">
|
||||
<title>DV BT Timing flags</title>
|
||||
<tgroup cols="2">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>Flag</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_FL_REDUCED_BLANKING</entry>
|
||||
<entry>CVT/GTF specific: the timings use reduced blanking (CVT) or the 'Secondary
|
||||
GTF' curve (GTF). In both cases the horizontal and/or vertical blanking
|
||||
intervals are reduced, allowing a higher resolution over the same
|
||||
bandwidth. This is a read-only flag, applications must not set this.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_FL_CAN_REDUCE_FPS</entry>
|
||||
<entry>CEA-861 specific: set for CEA-861 formats with a framerate that is a multiple
|
||||
of six. These formats can be optionally played at 1 / 1.001 speed to
|
||||
be compatible with 60 Hz based standards such as NTSC and PAL-M that use a framerate of
|
||||
29.97 frames per second. If the transmitter can't generate such frequencies, then the
|
||||
flag will also be cleared. This is a read-only flag, applications must not set this.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_FL_REDUCED_FPS</entry>
|
||||
<entry>CEA-861 specific: only valid for video transmitters, the flag is cleared
|
||||
by receivers. It is also only valid for formats with the V4L2_DV_FL_CAN_REDUCE_FPS flag
|
||||
set, for other formats the flag will be cleared by the driver.
|
||||
|
||||
If the application sets this flag, then the pixelclock used to set up the transmitter is
|
||||
divided by 1.001 to make it compatible with NTSC framerates. If the transmitter
|
||||
can't generate such frequencies, then the flag will also be cleared.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_FL_HALF_LINE</entry>
|
||||
<entry>Specific to interlaced formats: if set, then field 1 (aka the odd field)
|
||||
is really one half-line longer and field 2 (aka the even field) is really one half-line
|
||||
shorter, so each field has exactly the same number of half-lines. Whether half-lines can be
|
||||
detected or used depends on the hardware.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
&return-value;
|
||||
|
|
|
@ -265,6 +265,32 @@ These controls are described in <xref
|
|||
These controls are described in <xref
|
||||
linkend="flash-controls" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CTRL_CLASS_JPEG</constant></entry>
|
||||
<entry>0x9d0000</entry>
|
||||
<entry>The class containing JPEG compression controls.
|
||||
These controls are described in <xref
|
||||
linkend="jpeg-controls" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CTRL_CLASS_IMAGE_SOURCE</constant></entry>
|
||||
<entry>0x9e0000</entry> <entry>The class containing image
|
||||
source controls. These controls are described in <xref
|
||||
linkend="image-source-controls" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CTRL_CLASS_IMAGE_PROC</constant></entry>
|
||||
<entry>0x9f0000</entry> <entry>The class containing image
|
||||
processing controls. These controls are described in <xref
|
||||
linkend="image-process-controls" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CTRL_CLASS_JPEG</constant></entry>
|
||||
<entry>0x9d0000</entry>
|
||||
<entry>The class containing JPEG compression controls.
|
||||
These controls are described in <xref
|
||||
linkend="jpeg-controls" />.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
|
|
@ -116,7 +116,7 @@ this ioctl.</para>
|
|||
<colspec colname="c4" />
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>&v4l2-buf-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>Type of the data stream, see <xref
|
||||
|
|
|
@ -95,14 +95,14 @@ the &v4l2-output; <structfield>modulator</structfield> field and the
|
|||
&v4l2-modulator; <structfield>index</structfield> field.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-tuner-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>The tuner type. This is the same value as in the
|
||||
&v4l2-tuner; <structfield>type</structfield> field. The type must be set
|
||||
&v4l2-tuner; <structfield>type</structfield> field. See The type must be set
|
||||
to <constant>V4L2_TUNER_RADIO</constant> for <filename>/dev/radioX</filename>
|
||||
device nodes, and to <constant>V4L2_TUNER_ANALOG_TV</constant>
|
||||
for all others. The field is not applicable to modulators, &ie; ignored
|
||||
by drivers.</entry>
|
||||
by drivers. See <xref linkend="v4l2-tuner-type" /></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
|
|
@ -75,11 +75,12 @@ devices.</para>
|
|||
&cs-ustr;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>&v4l2-buf-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>The buffer (stream) type, same as &v4l2-format;
|
||||
<structfield>type</structfield>, set by the application.</entry>
|
||||
<structfield>type</structfield>, set by the application. See <xref
|
||||
linkend="v4l2-buf-type" /></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>union</entry>
|
||||
|
|
|
@ -148,7 +148,7 @@ using the &VIDIOC-S-FMT; ioctl as described in <xref
|
|||
<structfield>service_lines</structfield>[1][0] to zero.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-buf-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>Type of the data stream, see <xref
|
||||
linkend="v4l2-buf-type" />. Should be
|
||||
|
|
|
@ -107,7 +107,7 @@ user.<!-- FIXME Video inputs already have a name, the purpose of this
|
|||
field is not quite clear.--></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-tuner-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry spanname="hspan">Type of the tuner, see <xref
|
||||
linkend="v4l2-tuner-type" />.</entry>
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
<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>Applications can optionally call the
|
||||
<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
|
||||
to the driver before actually enqueuing it, using the
|
||||
|
|
|
@ -49,6 +49,10 @@ input</refpurpose>
|
|||
<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
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
<refentry id="vidioc-query-dv-timings">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_QUERY_DV_TIMINGS</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>VIDIOC_QUERY_DV_TIMINGS</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_timings *<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_TIMINGS</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>The hardware may be able to detect the current DV timings
|
||||
automatically, similar to sensing the video standard. To do so, applications
|
||||
call <constant>VIDIOC_QUERY_DV_TIMINGS</constant> with a pointer to a
|
||||
&v4l2-dv-timings;. Once the hardware detects the timings, it will fill in the
|
||||
timings structure.
|
||||
|
||||
If the timings could not be detected because there was no signal, then
|
||||
<errorcode>ENOLINK</errorcode> is returned. If a signal was detected, but
|
||||
it was unstable and the receiver could not lock to the signal, then
|
||||
<errorcode>ENOLCK</errorcode> is returned. If the receiver could lock to the signal,
|
||||
but the format is unsupported (e.g. because the pixelclock is out of range
|
||||
of the hardware capabilities), then the driver fills in whatever timings it
|
||||
could find and returns <errorcode>ERANGE</errorcode>. In that case the application
|
||||
can call &VIDIOC-DV-TIMINGS-CAP; to compare the found timings with the hardware's
|
||||
capabilities in order to give more precise feedback to the user.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
&return-value;
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><errorcode>ENOLINK</errorcode></term>
|
||||
<listitem>
|
||||
<para>No timings could be detected because no signal was found.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><errorcode>ENOLCK</errorcode></term>
|
||||
<listitem>
|
||||
<para>The signal was unstable and the hardware could not lock on to it.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><errorcode>ERANGE</errorcode></term>
|
||||
<listitem>
|
||||
<para>Timings were found, but they are out of range of the hardware
|
||||
capabilities.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
|
@ -127,7 +127,7 @@ the first control with a higher ID. Drivers which do not support this
|
|||
flag yet always return an &EINVAL;.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-ctrl-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>Type of control, see <xref
|
||||
linkend="v4l2-ctrl-type" />.</entry>
|
||||
|
@ -215,11 +215,12 @@ the array to zero.</entry>
|
|||
|
||||
<table pgwide="1" frame="none" id="v4l2-querymenu">
|
||||
<title>struct <structname>v4l2_querymenu</structname></title>
|
||||
<tgroup cols="3">
|
||||
<tgroup cols="4">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry></entry>
|
||||
<entry><structfield>id</structfield></entry>
|
||||
<entry>Identifies the control, set by the application
|
||||
from the respective &v4l2-queryctrl;
|
||||
|
@ -227,18 +228,38 @@ from the respective &v4l2-queryctrl;
|
|||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry></entry>
|
||||
<entry><structfield>index</structfield></entry>
|
||||
<entry>Index of the menu item, starting at zero, set by
|
||||
the application.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>union</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>__u8</entry>
|
||||
<entry><structfield>name</structfield>[32]</entry>
|
||||
<entry>Name of the menu item, a NUL-terminated ASCII
|
||||
string. This information is intended for the user.</entry>
|
||||
string. This information is intended for the user. This field is valid
|
||||
for <constant>V4L2_CTRL_FLAG_MENU</constant> type controls.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>__s64</entry>
|
||||
<entry><structfield>value</structfield></entry>
|
||||
<entry>
|
||||
Value of the integer menu item. This field is valid for
|
||||
<constant>V4L2_CTRL_FLAG_INTEGER_MENU</constant> type
|
||||
controls.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry></entry>
|
||||
<entry><structfield>reserved</structfield></entry>
|
||||
<entry>Reserved for future extensions. Drivers must set
|
||||
the array to zero.</entry>
|
||||
|
@ -291,6 +312,20 @@ values which are actually different on the hardware.</entry>
|
|||
the menu items can be enumerated with the
|
||||
<constant>VIDIOC_QUERYMENU</constant> ioctl.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CTRL_TYPE_INTEGER_MENU</constant></entry>
|
||||
<entry>≥ 0</entry>
|
||||
<entry>1</entry>
|
||||
<entry>N-1</entry>
|
||||
<entry>
|
||||
The control has a menu of N choices. The values of the
|
||||
menu items can be enumerated with the
|
||||
<constant>VIDIOC_QUERYMENU</constant> ioctl. This is
|
||||
similar to <constant>V4L2_CTRL_TYPE_MENU</constant>
|
||||
except that instead of strings, the menu items are
|
||||
signed 64-bit integers.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CTRL_TYPE_BITMASK</constant></entry>
|
||||
<entry>0</entry>
|
||||
|
|
|
@ -92,18 +92,19 @@ streamoff.--></para>
|
|||
<entry>The number of buffers requested or granted.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-buf-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>Type of the stream or buffers, this is the same
|
||||
as the &v4l2-format; <structfield>type</structfield> field. See <xref
|
||||
linkend="v4l2-buf-type" /> for valid values.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-memory;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>memory</structfield></entry>
|
||||
<entry>Applications set this field to
|
||||
<constant>V4L2_MEMORY_MMAP</constant> or
|
||||
<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
|
||||
<constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory"
|
||||
/>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
|
|
@ -73,10 +73,11 @@ same value as in the &v4l2-input; <structfield>tuner</structfield>
|
|||
field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-tuner-type;</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry>The tuner type. This is the same value as in the
|
||||
&v4l2-tuner; <structfield>type</structfield> field.</entry>
|
||||
&v4l2-tuner; <structfield>type</structfield> field. See <xref
|
||||
linkend="v4l2-tuner-type" /></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
|
|
@ -58,9 +58,12 @@
|
|||
<title>Description</title>
|
||||
|
||||
<note>
|
||||
<title>Experimental</title>
|
||||
<para>This is an <link linkend="experimental">experimental</link>
|
||||
interface and may change in the future.</para>
|
||||
<title>Obsolete</title>
|
||||
|
||||
<para>This is an <link linkend="obsolete">obsolete</link>
|
||||
interface and may be removed in the future. It is superseded by
|
||||
<link linkend="vidioc-subdev-g-selection">the selection
|
||||
API</link>.</para>
|
||||
</note>
|
||||
|
||||
<para>To retrieve the current crop rectangle applications set the
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
<refentry id="vidioc-subdev-g-selection">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>VIDIOC_SUBDEV_G_SELECTION</refname>
|
||||
<refname>VIDIOC_SUBDEV_S_SELECTION</refname>
|
||||
<refpurpose>Get or set selection rectangles on a subdev pad</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_subdev_selection *<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_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION</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>The selections are used to configure various image
|
||||
processing functionality performed by the subdevs which affect the
|
||||
image size. This currently includes cropping, scaling and
|
||||
composition.</para>
|
||||
|
||||
<para>The selection API replaces <link
|
||||
linkend="vidioc-subdev-g-crop">the old subdev crop API</link>. All
|
||||
the function of the crop API, and more, are supported by the
|
||||
selections API.</para>
|
||||
|
||||
<para>See <xref linkend="subdev"></xref> for
|
||||
more information on how each selection target affects the image
|
||||
processing pipeline inside the subdevice.</para>
|
||||
|
||||
<section>
|
||||
<title>Types of selection targets</title>
|
||||
|
||||
<para>There are two types of selection targets: actual and bounds.
|
||||
The ACTUAL targets are the targets which configure the hardware.
|
||||
The BOUNDS target will return a rectangle that contain all
|
||||
possible ACTUAL rectangles.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Discovering supported features</title>
|
||||
|
||||
<para>To discover which targets are supported, the user can
|
||||
perform <constant>VIDIOC_SUBDEV_G_SELECTION</constant> on them.
|
||||
Any unsupported target will return
|
||||
<constant>EINVAL</constant>.</para>
|
||||
</section>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-subdev-selection-targets">
|
||||
<title>V4L2 subdev selection targets</title>
|
||||
<tgroup cols="3">
|
||||
&cs-def;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL</constant></entry>
|
||||
<entry>0x0000</entry>
|
||||
<entry>Actual crop. Defines the cropping
|
||||
performed by the processing step.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS</constant></entry>
|
||||
<entry>0x0002</entry>
|
||||
<entry>Bounds of the crop rectangle.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL</constant></entry>
|
||||
<entry>0x0100</entry>
|
||||
<entry>Actual compose rectangle. Used to configure scaling
|
||||
on sink pads and composition on source pads.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS</constant></entry>
|
||||
<entry>0x0102</entry>
|
||||
<entry>Bounds of the compose rectangle.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-subdev-selection-flags">
|
||||
<title>V4L2 subdev selection flags</title>
|
||||
<tgroup cols="3">
|
||||
&cs-def;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_SUBDEV_SEL_FLAG_SIZE_GE</constant></entry>
|
||||
<entry>(1 << 0)</entry> <entry>Suggest the driver it
|
||||
should choose greater or equal rectangle (in size) than
|
||||
was requested. Albeit the driver may choose a lesser size,
|
||||
it will only do so due to hardware limitations. Without
|
||||
this flag (and
|
||||
<constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant>) the
|
||||
behaviour is to choose the closest possible
|
||||
rectangle.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant></entry>
|
||||
<entry>(1 << 1)</entry> <entry>Suggest the driver it
|
||||
should choose lesser or equal rectangle (in size) than was
|
||||
requested. Albeit the driver may choose a greater size, it
|
||||
will only do so due to hardware limitations.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG</constant></entry>
|
||||
<entry>(1 << 2)</entry>
|
||||
<entry>The configuration should not be propagated to any
|
||||
further processing steps. If this flag is not given, the
|
||||
configuration is propagated inside the subdevice to all
|
||||
further processing steps.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-subdev-selection">
|
||||
<title>struct <structname>v4l2_subdev_selection</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>which</structfield></entry>
|
||||
<entry>Active or try selection, from
|
||||
&v4l2-subdev-format-whence;.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>pad</structfield></entry>
|
||||
<entry>Pad number as reported by the media framework.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>target</structfield></entry>
|
||||
<entry>Target selection rectangle. See
|
||||
<xref linkend="v4l2-subdev-selection-targets">.</xref>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>flags</structfield></entry>
|
||||
<entry>Flags. See
|
||||
<xref linkend="v4l2-subdev-selection-flags">.</xref></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-rect;</entry>
|
||||
<entry><structfield>rect</structfield></entry>
|
||||
<entry>Selection rectangle, in pixels.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved</structfield>[8]</entry>
|
||||
<entry>Reserved for future extensions. Applications and drivers must
|
||||
set the array to zero.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
&return-value;
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><errorcode>EBUSY</errorcode></term>
|
||||
<listitem>
|
||||
<para>The selection rectangle can't be changed because the
|
||||
pad is currently busy. This can be caused, for instance, by
|
||||
an active video stream on the pad. The ioctl must not be
|
||||
retried without performing another action to fix the problem
|
||||
first. Only returned by
|
||||
<constant>VIDIOC_SUBDEV_S_SELECTION</constant></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><errorcode>EINVAL</errorcode></term>
|
||||
<listitem>
|
||||
<para>The &v4l2-subdev-selection;
|
||||
<structfield>pad</structfield> references a non-existing
|
||||
pad, the <structfield>which</structfield> field references a
|
||||
non-existing format, or the selection target is not
|
||||
supported on the given subdev pad.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
|
@ -28,7 +28,8 @@ use IO::Handle;
|
|||
"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
|
||||
"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
|
||||
"lme2510c_s7395_old", "drxk", "drxk_terratec_h5",
|
||||
"drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137");
|
||||
"drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137",
|
||||
"drxk_pctv");
|
||||
|
||||
# Check args
|
||||
syntax() if (scalar(@ARGV) != 1);
|
||||
|
@ -730,6 +731,23 @@ sub tda10071 {
|
|||
"$fwfile";
|
||||
}
|
||||
|
||||
sub drxk_pctv {
|
||||
my $sourcefile = "PCTV_460e_reference.zip";
|
||||
my $url = "ftp://ftp.pctvsystems.com/TV/driver/PCTV%2070e%2080e%20100e%20320e%20330e%20800e/";
|
||||
my $hash = "4403de903bf2593464c8d74bbc200a57";
|
||||
my $fwfile = "dvb-demod-drxk-pctv.fw";
|
||||
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
|
||||
|
||||
checkstandard();
|
||||
|
||||
wgetfile($sourcefile, $url . $sourcefile);
|
||||
verify($sourcefile, $hash);
|
||||
unzip($sourcefile, $tmpdir);
|
||||
extract("$tmpdir/PCTV\ 70e\ 80e\ 100e\ 320e\ 330e\ 800e/32\ bit/emOEM.sys", 0x72b80, 42692, $fwfile);
|
||||
|
||||
"$fwfile";
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Utilities
|
||||
|
||||
|
|
|
@ -549,6 +549,15 @@ Who: Sasikantha Babu <sasikanth.v19@gmail.com>
|
|||
|
||||
----------------------------
|
||||
|
||||
What: remove bogus DV presets V4L2_DV_1080I29_97, V4L2_DV_1080I30 and
|
||||
V4L2_DV_1080I25
|
||||
When: 3.6
|
||||
Why: These HDTV formats do not exist and were added by a confused mind
|
||||
(that was me, to be precise...)
|
||||
Who: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
|
||||
----------------------------
|
||||
|
||||
What: V4L2_CID_HCENTER, V4L2_CID_VCENTER V4L2 controls
|
||||
When: 3.7
|
||||
Why: The V4L2_CID_VCENTER, V4L2_CID_HCENTER controls have been deprecated
|
||||
|
|
|
@ -335,6 +335,9 @@ the media_entity pipe field.
|
|||
Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must
|
||||
be identical for all nested calls to the function.
|
||||
|
||||
media_entity_pipeline_start() may return an error. In that case, it will
|
||||
clean up any the changes it did by itself.
|
||||
|
||||
When stopping the stream, drivers must notify the entities with
|
||||
|
||||
media_entity_pipeline_stop(struct media_entity *entity);
|
||||
|
@ -351,3 +354,19 @@ If other operations need to be disallowed on streaming entities (such as
|
|||
changing entities configuration parameters) drivers can explicitly check the
|
||||
media_entity stream_count field to find out if an entity is streaming. This
|
||||
operation must be done with the media_device graph_mutex held.
|
||||
|
||||
|
||||
Link validation
|
||||
---------------
|
||||
|
||||
Link validation is performed by media_entity_pipeline_start() for any
|
||||
entity which has sink pads in the pipeline. The
|
||||
media_entity::link_validate() callback is used for that purpose. In
|
||||
link_validate() callback, entity driver should check that the properties of
|
||||
the source pad of the connected entity and its own sink pad match. It is up
|
||||
to the type of the entity (and in the end, the properties of the hardware)
|
||||
what matching actually means.
|
||||
|
||||
Subsystems should facilitate link validation by providing subsystem specific
|
||||
helper functions to provide easy access for commonly needed information, and
|
||||
in the end provide a way to use driver-specific callbacks.
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
Guidelines for Linux4Linux pixel format 4CCs
|
||||
============================================
|
||||
|
||||
Guidelines for Video4Linux 4CC codes defined using v4l2_fourcc() are
|
||||
specified in this document. First of the characters defines the nature of
|
||||
the pixel format, compression and colour space. The interpretation of the
|
||||
other three characters depends on the first one.
|
||||
|
||||
Existing 4CCs may not obey these guidelines.
|
||||
|
||||
Formats
|
||||
=======
|
||||
|
||||
Raw bayer
|
||||
---------
|
||||
|
||||
The following first characters are used by raw bayer formats:
|
||||
|
||||
B: raw bayer, uncompressed
|
||||
b: raw bayer, DPCM compressed
|
||||
a: A-law compressed
|
||||
u: u-law compressed
|
||||
|
||||
2nd character: pixel order
|
||||
B: BGGR
|
||||
G: GBRG
|
||||
g: GRBG
|
||||
R: RGGB
|
||||
|
||||
3rd character: uncompressed bits-per-pixel 0--9, A--
|
||||
|
||||
4th character: compressed bits-per-pixel 0--9, A--
|
|
@ -276,6 +276,7 @@ pac7302 093a:2622 Genius Eye 312
|
|||
pac7302 093a:2624 PAC7302
|
||||
pac7302 093a:2625 Genius iSlim 310
|
||||
pac7302 093a:2626 Labtec 2200
|
||||
pac7302 093a:2627 Genius FaceCam 300
|
||||
pac7302 093a:2628 Genius iLook 300
|
||||
pac7302 093a:2629 Genious iSlim 300
|
||||
pac7302 093a:262a Webcam 300k
|
||||
|
|
|
@ -130,8 +130,18 @@ Menu controls are added by calling v4l2_ctrl_new_std_menu:
|
|||
const struct v4l2_ctrl_ops *ops,
|
||||
u32 id, s32 max, s32 skip_mask, s32 def);
|
||||
|
||||
Or alternatively for integer menu controls, by calling v4l2_ctrl_new_int_menu:
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops,
|
||||
u32 id, s32 max, s32 def, const s64 *qmenu_int);
|
||||
|
||||
These functions are typically called right after the v4l2_ctrl_handler_init:
|
||||
|
||||
static const s64 exp_bias_qmenu[] = {
|
||||
-2, -1, 0, 1, 2
|
||||
};
|
||||
|
||||
v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
|
||||
v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
|
||||
V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
|
||||
|
@ -141,6 +151,11 @@ These functions are typically called right after the v4l2_ctrl_handler_init:
|
|||
V4L2_CID_POWER_LINE_FREQUENCY,
|
||||
V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
|
||||
V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
|
||||
v4l2_ctrl_new_int_menu(&foo->ctrl_handler, &foo_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE_BIAS,
|
||||
ARRAY_SIZE(exp_bias_qmenu) - 1,
|
||||
ARRAY_SIZE(exp_bias_qmenu) / 2 - 1,
|
||||
exp_bias_qmenu);
|
||||
...
|
||||
if (foo->ctrl_handler.error) {
|
||||
int err = foo->ctrl_handler.error;
|
||||
|
@ -164,6 +179,12 @@ controls. There is no min argument since that is always 0 for menu controls,
|
|||
and instead of a step there is a skip_mask argument: if bit X is 1, then menu
|
||||
item X is skipped.
|
||||
|
||||
The v4l2_ctrl_new_int_menu function creates a new standard integer menu
|
||||
control with driver-specific items in the menu. It differs from
|
||||
v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and takes
|
||||
as the last argument an array of signed 64-bit integers that form an exact
|
||||
menu item list.
|
||||
|
||||
Note that if something fails, the function will return NULL or an error and
|
||||
set ctrl_handler->error to the error code. If ctrl_handler->error was already
|
||||
set, then it will just return and do nothing. This is also true for
|
||||
|
|
|
@ -182,11 +182,11 @@ static int __devinit drv_probe(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
If you have multiple device nodes then it can be difficult to know when it is
|
||||
safe to unregister v4l2_device. For this purpose v4l2_device has refcounting
|
||||
support. The refcount is increased whenever video_register_device is called and
|
||||
it is decreased whenever that device node is released. When the refcount reaches
|
||||
zero, then the v4l2_device release() callback is called. You can do your final
|
||||
cleanup there.
|
||||
safe to unregister v4l2_device for hotpluggable devices. For this purpose
|
||||
v4l2_device has refcounting support. The refcount is increased whenever
|
||||
video_register_device is called and it is decreased whenever that device node
|
||||
is released. When the refcount reaches zero, then the v4l2_device release()
|
||||
callback is called. You can do your final cleanup there.
|
||||
|
||||
If other device nodes (e.g. ALSA) are created, then you can increase and
|
||||
decrease the refcount manually as well by calling:
|
||||
|
@ -197,6 +197,10 @@ or:
|
|||
|
||||
int v4l2_device_put(struct v4l2_device *v4l2_dev);
|
||||
|
||||
Since the initial refcount is 1 you also need to call v4l2_device_put in the
|
||||
disconnect() callback (for USB devices) or in the remove() callback (for e.g.
|
||||
PCI devices), otherwise the refcount will never reach 0.
|
||||
|
||||
struct v4l2_subdev
|
||||
------------------
|
||||
|
||||
|
@ -262,11 +266,16 @@ struct v4l2_subdev_video_ops {
|
|||
...
|
||||
};
|
||||
|
||||
struct v4l2_subdev_pad_ops {
|
||||
...
|
||||
};
|
||||
|
||||
struct v4l2_subdev_ops {
|
||||
const struct v4l2_subdev_core_ops *core;
|
||||
const struct v4l2_subdev_tuner_ops *tuner;
|
||||
const struct v4l2_subdev_audio_ops *audio;
|
||||
const struct v4l2_subdev_video_ops *video;
|
||||
const struct v4l2_subdev_pad_ops *video;
|
||||
};
|
||||
|
||||
The core ops are common to all subdevs, the other categories are implemented
|
||||
|
@ -303,6 +312,22 @@ Don't forget to cleanup the media entity before the sub-device is destroyed:
|
|||
|
||||
media_entity_cleanup(&sd->entity);
|
||||
|
||||
If the subdev driver intends to process video and integrate with the media
|
||||
framework, it must implement format related functionality using
|
||||
v4l2_subdev_pad_ops instead of v4l2_subdev_video_ops.
|
||||
|
||||
In that case, the subdev driver may set the link_validate field to provide
|
||||
its own link validation function. The link validation function is called for
|
||||
every link in the pipeline where both of the ends of the links are V4L2
|
||||
sub-devices. The driver is still responsible for validating the correctness
|
||||
of the format configuration between sub-devices and video nodes.
|
||||
|
||||
If link_validate op is not set, the default function
|
||||
v4l2_subdev_link_validate_default() is used instead. This function ensures
|
||||
that width, height and the media bus pixel code are equal on both source and
|
||||
sink of the link. Subdev drivers are also free to use this function to
|
||||
perform the checks mentioned above in addition to their own checks.
|
||||
|
||||
A device (bridge) driver needs to register the v4l2_subdev with the
|
||||
v4l2_device:
|
||||
|
||||
|
@ -555,19 +580,25 @@ allocated memory.
|
|||
You should also set these fields:
|
||||
|
||||
- v4l2_dev: set to the v4l2_device parent device.
|
||||
|
||||
- name: set to something descriptive and unique.
|
||||
|
||||
- fops: set to the v4l2_file_operations struct.
|
||||
|
||||
- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
|
||||
(highly recommended to use this and it might become compulsory in the
|
||||
future!), then set this to your v4l2_ioctl_ops struct.
|
||||
|
||||
- lock: leave to NULL if you want to do all the locking in the driver.
|
||||
Otherwise you give it a pointer to a struct mutex_lock and before any
|
||||
of the v4l2_file_operations is called this lock will be taken by the
|
||||
core and released afterwards.
|
||||
Otherwise you give it a pointer to a struct mutex_lock and before the
|
||||
unlocked_ioctl file operation is called this lock will be taken by the
|
||||
core and released afterwards. See the next section for more details.
|
||||
|
||||
- prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY.
|
||||
If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device.
|
||||
If you want to have a separate priority state per (group of) device node(s),
|
||||
then you can point it to your own struct v4l2_prio_state.
|
||||
|
||||
- parent: you only set this if v4l2_device was registered with NULL as
|
||||
the parent device struct. This only happens in cases where one hardware
|
||||
device has multiple PCI devices that all share the same v4l2_device core.
|
||||
|
@ -577,6 +608,7 @@ You should also set these fields:
|
|||
(cx8802). Since the v4l2_device cannot be associated with a particular
|
||||
PCI device it is setup without a parent device. But when the struct
|
||||
video_device is setup you do know which parent PCI device to use.
|
||||
|
||||
- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
|
||||
handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
|
||||
v4l2_fh. Eventually this flag will disappear once all drivers use the core
|
||||
|
@ -587,6 +619,16 @@ in your v4l2_file_operations struct.
|
|||
|
||||
Do not use .ioctl! This is deprecated and will go away in the future.
|
||||
|
||||
In some cases you want to tell the core that a function you had specified in
|
||||
your v4l2_ioctl_ops should be ignored. You can mark such ioctls by calling this
|
||||
function before video_device_register is called:
|
||||
|
||||
void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd);
|
||||
|
||||
This tends to be needed if based on external factors (e.g. which card is
|
||||
being used) you want to turns off certain features in v4l2_ioctl_ops without
|
||||
having to make a new struct.
|
||||
|
||||
The v4l2_file_operations struct is a subset of file_operations. The main
|
||||
difference is that the inode argument is omitted since it is never used.
|
||||
|
||||
|
@ -609,8 +651,22 @@ v4l2_file_operations and locking
|
|||
--------------------------------
|
||||
|
||||
You can set a pointer to a mutex_lock in struct video_device. Usually this
|
||||
will be either a top-level mutex or a mutex per device node. If you want
|
||||
finer-grained locking then you have to set it to NULL and do you own locking.
|
||||
will be either a top-level mutex or a mutex per device node. By default this
|
||||
lock will be used for unlocked_ioctl, but you can disable locking for
|
||||
selected ioctls by calling:
|
||||
|
||||
void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd);
|
||||
|
||||
E.g.: v4l2_disable_ioctl_locking(vdev, VIDIOC_DQBUF);
|
||||
|
||||
You have to call this before you register the video_device.
|
||||
|
||||
Particularly with USB drivers where certain commands such as setting controls
|
||||
can take a long time you may want to do your own locking for the buffer queuing
|
||||
ioctls.
|
||||
|
||||
If you want still finer-grained locking then you have to set mutex_lock to NULL
|
||||
and do you own locking completely.
|
||||
|
||||
It is up to the driver developer to decide which method to use. However, if
|
||||
your driver has high-latency operations (for example, changing the exposure
|
||||
|
@ -618,7 +674,7 @@ of a USB webcam might take a long time), then you might be better off with
|
|||
doing your own locking if you want to allow the user to do other things with
|
||||
the device while waiting for the high-latency command to finish.
|
||||
|
||||
If a lock is specified then all file operations will be serialized on that
|
||||
If a lock is specified then all ioctl commands will be serialized on that
|
||||
lock. If you use videobuf then you must pass the same lock to the videobuf
|
||||
queue initialize function: if videobuf has to wait for a frame to arrive, then
|
||||
it will temporarily unlock the lock and relock it afterwards. If your driver
|
||||
|
@ -941,21 +997,35 @@ fast.
|
|||
|
||||
Useful functions:
|
||||
|
||||
- v4l2_event_queue()
|
||||
void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
|
||||
|
||||
Queue events to video device. The driver's only responsibility is to fill
|
||||
in the type and the data fields. The other fields will be filled in by
|
||||
V4L2.
|
||||
|
||||
- v4l2_event_subscribe()
|
||||
int v4l2_event_subscribe(struct v4l2_fh *fh,
|
||||
struct v4l2_event_subscription *sub, unsigned elems,
|
||||
const struct v4l2_subscribed_event_ops *ops)
|
||||
|
||||
The video_device->ioctl_ops->vidioc_subscribe_event must check the driver
|
||||
is able to produce events with specified event id. Then it calls
|
||||
v4l2_event_subscribe() to subscribe the event. The last argument is the
|
||||
size of the event queue for this event. If it is 0, then the framework
|
||||
will fill in a default value (this depends on the event type).
|
||||
v4l2_event_subscribe() to subscribe the event.
|
||||
|
||||
- v4l2_event_unsubscribe()
|
||||
The elems argument is the size of the event queue for this event. If it is 0,
|
||||
then the framework will fill in a default value (this depends on the event
|
||||
type).
|
||||
|
||||
The ops argument allows the driver to specify a number of callbacks:
|
||||
* add: called when a new listener gets added (subscribing to the same
|
||||
event twice will only cause this callback to get called once)
|
||||
* del: called when a listener stops listening
|
||||
* replace: replace event 'old' with event 'new'.
|
||||
* merge: merge event 'old' into event 'new'.
|
||||
All 4 callbacks are optional, if you don't want to specify any callbacks
|
||||
the ops argument itself maybe NULL.
|
||||
|
||||
int v4l2_event_unsubscribe(struct v4l2_fh *fh,
|
||||
struct v4l2_event_subscription *sub)
|
||||
|
||||
vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use
|
||||
v4l2_event_unsubscribe() directly unless it wants to be involved in
|
||||
|
@ -964,7 +1034,7 @@ Useful functions:
|
|||
The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The
|
||||
drivers may want to handle this in a special way.
|
||||
|
||||
- v4l2_event_pending()
|
||||
int v4l2_event_pending(struct v4l2_fh *fh)
|
||||
|
||||
Returns the number of pending events. Useful when implementing poll.
|
||||
|
||||
|
|
|
@ -2718,6 +2718,13 @@ S: Maintained
|
|||
F: Documentation/hwmon/f71805f
|
||||
F: drivers/hwmon/f71805f.c
|
||||
|
||||
FC0011 TUNER DRIVER
|
||||
M: Michael Buesch <m@bues.ch>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/common/tuners/fc0011.h
|
||||
F: drivers/media/common/tuners/fc0011.c
|
||||
|
||||
FANOTIFY
|
||||
M: Eric Paris <eparis@redhat.com>
|
||||
S: Maintained
|
||||
|
@ -7191,7 +7198,7 @@ F: include/linux/usb/usbnet.h
|
|||
|
||||
USB VIDEO CLASS
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
L: linux-uvc-devel@lists.berlios.de (subscribers-only)
|
||||
L: linux-uvc-devel@lists.sourceforge.net (subscribers-only)
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
|
||||
W: http://www.ideasonboard.org/uvc/
|
||||
|
|
|
@ -178,7 +178,7 @@ static struct soc_camera_link iclink_tvp5150 = {
|
|||
|
||||
static struct mx2_camera_platform_data visstrim_camera = {
|
||||
.flags = MX2_CAMERA_CCIR | MX2_CAMERA_CCIR_INTERLACE |
|
||||
MX2_CAMERA_SWAP16 | MX2_CAMERA_PCLK_SAMPLE_RISING,
|
||||
MX2_CAMERA_PCLK_SAMPLE_RISING,
|
||||
.clk = 100000,
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#ifndef __MACH_MX2_CAM_H_
|
||||
#define __MACH_MX2_CAM_H_
|
||||
|
||||
#define MX2_CAMERA_SWAP16 (1 << 0)
|
||||
#define MX2_CAMERA_EXT_VSYNC (1 << 1)
|
||||
#define MX2_CAMERA_CCIR (1 << 2)
|
||||
#define MX2_CAMERA_CCIR_INTERLACE (1 << 3)
|
||||
|
@ -31,7 +30,6 @@
|
|||
#define MX2_CAMERA_GATED_CLOCK (1 << 5)
|
||||
#define MX2_CAMERA_INV_DATA (1 << 6)
|
||||
#define MX2_CAMERA_PCLK_SAMPLE_RISING (1 << 7)
|
||||
#define MX2_CAMERA_PACK_DIR_MSB (1 << 8)
|
||||
|
||||
/**
|
||||
* struct mx2_camera_platform_data - optional platform data for mx2_camera
|
||||
|
|
|
@ -31,8 +31,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include "fixp-arith.h"
|
||||
#include <linux/fixp-arith.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Anssi Hannula <anssi.hannula@gmail.com>");
|
||||
|
|
|
@ -198,7 +198,6 @@ static int fops_open(struct file *file)
|
|||
struct saa7146_dev *dev = video_drvdata(file);
|
||||
struct saa7146_fh *fh = NULL;
|
||||
int result = 0;
|
||||
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev));
|
||||
|
@ -227,11 +226,12 @@ static int fops_open(struct file *file)
|
|||
goto out;
|
||||
}
|
||||
|
||||
file->private_data = fh;
|
||||
fh->dev = dev;
|
||||
fh->type = type;
|
||||
v4l2_fh_init(&fh->fh, vdev);
|
||||
|
||||
if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
|
||||
file->private_data = &fh->fh;
|
||||
fh->dev = dev;
|
||||
|
||||
if (vdev->vfl_type == VFL_TYPE_VBI) {
|
||||
DEB_S("initializing vbi...\n");
|
||||
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
|
||||
result = saa7146_vbi_uops.open(dev,file);
|
||||
|
@ -252,6 +252,7 @@ static int fops_open(struct file *file)
|
|||
}
|
||||
|
||||
result = 0;
|
||||
v4l2_fh_add(&fh->fh);
|
||||
out:
|
||||
if (fh && result != 0) {
|
||||
kfree(fh);
|
||||
|
@ -263,6 +264,7 @@ out:
|
|||
|
||||
static int fops_release(struct file *file)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
struct saa7146_dev *dev = fh->dev;
|
||||
|
||||
|
@ -271,7 +273,7 @@ static int fops_release(struct file *file)
|
|||
if (mutex_lock_interruptible(&saa7146_devices_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
|
||||
if (vdev->vfl_type == VFL_TYPE_VBI) {
|
||||
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
|
||||
saa7146_vbi_uops.release(dev,file);
|
||||
if (dev->ext_vv_data->vbi_fops.release)
|
||||
|
@ -280,6 +282,8 @@ static int fops_release(struct file *file)
|
|||
saa7146_video_uops.release(dev,file);
|
||||
}
|
||||
|
||||
v4l2_fh_del(&fh->fh);
|
||||
v4l2_fh_exit(&fh->fh);
|
||||
module_put(dev->ext->module);
|
||||
file->private_data = NULL;
|
||||
kfree(fh);
|
||||
|
@ -291,19 +295,22 @@ static int fops_release(struct file *file)
|
|||
|
||||
static int fops_mmap(struct file *file, struct vm_area_struct * vma)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
struct videobuf_queue *q;
|
||||
|
||||
switch (fh->type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
|
||||
switch (vdev->vfl_type) {
|
||||
case VFL_TYPE_GRABBER: {
|
||||
DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",
|
||||
file, vma);
|
||||
q = &fh->video_q;
|
||||
break;
|
||||
}
|
||||
case V4L2_BUF_TYPE_VBI_CAPTURE: {
|
||||
case VFL_TYPE_VBI: {
|
||||
DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",
|
||||
file, vma);
|
||||
if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
|
||||
return -ENODEV;
|
||||
q = &fh->vbi_q;
|
||||
break;
|
||||
}
|
||||
|
@ -317,15 +324,19 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
|
|||
|
||||
static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
struct videobuf_buffer *buf = NULL;
|
||||
struct videobuf_queue *q;
|
||||
unsigned int res = v4l2_ctrl_poll(file, wait);
|
||||
|
||||
DEB_EE("file:%p, poll:%p\n", file, wait);
|
||||
|
||||
if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
|
||||
if (vdev->vfl_type == VFL_TYPE_VBI) {
|
||||
if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
|
||||
return res | POLLOUT | POLLWRNORM;
|
||||
if( 0 == fh->vbi_q.streaming )
|
||||
return videobuf_poll_stream(file, &fh->vbi_q, wait);
|
||||
return res | videobuf_poll_stream(file, &fh->vbi_q, wait);
|
||||
q = &fh->vbi_q;
|
||||
} else {
|
||||
DEB_D("using video queue\n");
|
||||
|
@ -337,31 +348,32 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
|
|||
|
||||
if (!buf) {
|
||||
DEB_D("buf == NULL!\n");
|
||||
return POLLERR;
|
||||
return res | POLLERR;
|
||||
}
|
||||
|
||||
poll_wait(file, &buf->done, wait);
|
||||
if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) {
|
||||
DEB_D("poll succeeded!\n");
|
||||
return POLLIN|POLLRDNORM;
|
||||
return res | POLLIN | POLLRDNORM;
|
||||
}
|
||||
|
||||
DEB_D("nothing to poll for, buf->state:%d\n", buf->state);
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
|
||||
switch (fh->type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
||||
switch (vdev->vfl_type) {
|
||||
case VFL_TYPE_GRABBER:
|
||||
/*
|
||||
DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun",
|
||||
file, data, (unsigned long)count);
|
||||
*/
|
||||
return saa7146_video_uops.read(file,data,count,ppos);
|
||||
case V4L2_BUF_TYPE_VBI_CAPTURE:
|
||||
case VFL_TYPE_VBI:
|
||||
/*
|
||||
DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n",
|
||||
file, data, (unsigned long)count);
|
||||
|
@ -377,12 +389,13 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
|
|||
|
||||
static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
|
||||
switch (fh->type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
||||
switch (vdev->vfl_type) {
|
||||
case VFL_TYPE_GRABBER:
|
||||
return -EINVAL;
|
||||
case V4L2_BUF_TYPE_VBI_CAPTURE:
|
||||
case VFL_TYPE_VBI:
|
||||
if (fh->dev->ext_vv_data->vbi_fops.write)
|
||||
return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
|
||||
else
|
||||
|
@ -429,8 +442,15 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
|
|||
}
|
||||
}
|
||||
|
||||
static const struct v4l2_ctrl_ops saa7146_ctrl_ops = {
|
||||
.s_ctrl = saa7146_s_ctrl,
|
||||
};
|
||||
|
||||
int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
|
||||
{
|
||||
struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
|
||||
struct v4l2_pix_format *fmt;
|
||||
struct v4l2_vbi_format *vbi;
|
||||
struct saa7146_vv *vv;
|
||||
int err;
|
||||
|
||||
|
@ -438,12 +458,32 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
v4l2_ctrl_handler_init(hdl, 6);
|
||||
v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
|
||||
V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
|
||||
v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
|
||||
V4L2_CID_CONTRAST, 0, 127, 1, 64);
|
||||
v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
|
||||
V4L2_CID_SATURATION, 0, 127, 1, 64);
|
||||
v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
|
||||
V4L2_CID_VFLIP, 0, 1, 1, 0);
|
||||
v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
|
||||
V4L2_CID_HFLIP, 0, 1, 1, 0);
|
||||
if (hdl->error) {
|
||||
err = hdl->error;
|
||||
v4l2_ctrl_handler_free(hdl);
|
||||
return err;
|
||||
}
|
||||
dev->v4l2_dev.ctrl_handler = hdl;
|
||||
|
||||
vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
|
||||
if (vv == NULL) {
|
||||
ERR("out of memory. aborting.\n");
|
||||
v4l2_ctrl_handler_free(hdl);
|
||||
return -ENOMEM;
|
||||
}
|
||||
ext_vv->ops = saa7146_video_ioctl_ops;
|
||||
ext_vv->vid_ops = saa7146_video_ioctl_ops;
|
||||
ext_vv->vbi_ops = saa7146_vbi_ioctl_ops;
|
||||
ext_vv->core_ops = &saa7146_video_ioctl_ops;
|
||||
|
||||
DEB_EE("dev:%p\n", dev);
|
||||
|
@ -463,6 +503,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
|
|||
if( NULL == vv->d_clipping.cpu_addr ) {
|
||||
ERR("out of memory. aborting.\n");
|
||||
kfree(vv);
|
||||
v4l2_ctrl_handler_free(hdl);
|
||||
return -1;
|
||||
}
|
||||
memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
|
||||
|
@ -471,6 +512,39 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
|
|||
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
|
||||
saa7146_vbi_uops.init(dev,vv);
|
||||
|
||||
fmt = &vv->ov_fb.fmt;
|
||||
fmt->width = vv->standard->h_max_out;
|
||||
fmt->height = vv->standard->v_max_out;
|
||||
fmt->pixelformat = V4L2_PIX_FMT_RGB565;
|
||||
fmt->bytesperline = 2 * fmt->width;
|
||||
fmt->sizeimage = fmt->bytesperline * fmt->height;
|
||||
fmt->colorspace = V4L2_COLORSPACE_SRGB;
|
||||
|
||||
fmt = &vv->video_fmt;
|
||||
fmt->width = 384;
|
||||
fmt->height = 288;
|
||||
fmt->pixelformat = V4L2_PIX_FMT_BGR24;
|
||||
fmt->field = V4L2_FIELD_ANY;
|
||||
fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
fmt->bytesperline = 3 * fmt->width;
|
||||
fmt->sizeimage = fmt->bytesperline * fmt->height;
|
||||
|
||||
vbi = &vv->vbi_fmt;
|
||||
vbi->sampling_rate = 27000000;
|
||||
vbi->offset = 248; /* todo */
|
||||
vbi->samples_per_line = 720 * 2;
|
||||
vbi->sample_format = V4L2_PIX_FMT_GREY;
|
||||
|
||||
/* fixme: this only works for PAL */
|
||||
vbi->start[0] = 5;
|
||||
vbi->count[0] = 16;
|
||||
vbi->start[1] = 312;
|
||||
vbi->count[1] = 16;
|
||||
|
||||
init_timer(&vv->vbi_read_timeout);
|
||||
|
||||
vv->ov_fb.capability = V4L2_FBUF_CAP_LIST_CLIPPING;
|
||||
vv->ov_fb.flags = V4L2_FBUF_FLAG_PRIMARY;
|
||||
dev->vv_data = vv;
|
||||
dev->vv_callback = &vv_callback;
|
||||
|
||||
|
@ -486,6 +560,7 @@ int saa7146_vv_release(struct saa7146_dev* dev)
|
|||
|
||||
v4l2_device_unregister(&dev->v4l2_dev);
|
||||
pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
|
||||
v4l2_ctrl_handler_free(&dev->ctrl_handler);
|
||||
kfree(vv);
|
||||
dev->vv_data = NULL;
|
||||
dev->vv_callback = NULL;
|
||||
|
@ -509,10 +584,19 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
|
|||
return -ENOMEM;
|
||||
|
||||
vfd->fops = &video_fops;
|
||||
vfd->ioctl_ops = &dev->ext_vv_data->ops;
|
||||
if (type == VFL_TYPE_GRABBER)
|
||||
vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;
|
||||
else
|
||||
vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
|
||||
vfd->release = video_device_release;
|
||||
/* Locking in file operations other than ioctl should be done by
|
||||
the driver, not the V4L2 core.
|
||||
This driver needs auditing so that this flag can be removed. */
|
||||
set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
|
||||
vfd->lock = &dev->v4l2_lock;
|
||||
vfd->v4l2_dev = &dev->v4l2_dev;
|
||||
vfd->tvnorms = 0;
|
||||
set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
|
||||
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
|
||||
vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
|
||||
strlcpy(vfd->name, name, sizeof(vfd->name));
|
||||
|
|
|
@ -343,9 +343,9 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa
|
|||
struct saa7146_vv *vv = dev->vv_data;
|
||||
__le32 *clipping = vv->d_clipping.cpu_addr;
|
||||
|
||||
int width = fh->ov.win.w.width;
|
||||
int height = fh->ov.win.w.height;
|
||||
int clipcount = fh->ov.nclips;
|
||||
int width = vv->ov.win.w.width;
|
||||
int height = vv->ov.win.w.height;
|
||||
int clipcount = vv->ov.nclips;
|
||||
|
||||
u32 line_list[32];
|
||||
u32 pixel_list[32];
|
||||
|
@ -365,10 +365,10 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa
|
|||
for(i = 0; i < clipcount; i++) {
|
||||
int l = 0, r = 0, t = 0, b = 0;
|
||||
|
||||
x[i] = fh->ov.clips[i].c.left;
|
||||
y[i] = fh->ov.clips[i].c.top;
|
||||
w[i] = fh->ov.clips[i].c.width;
|
||||
h[i] = fh->ov.clips[i].c.height;
|
||||
x[i] = vv->ov.clips[i].c.left;
|
||||
y[i] = vv->ov.clips[i].c.top;
|
||||
w[i] = vv->ov.clips[i].c.width;
|
||||
h[i] = vv->ov.clips[i].c.height;
|
||||
|
||||
if( w[i] < 0) {
|
||||
x[i] += w[i]; w[i] = -w[i];
|
||||
|
@ -485,13 +485,14 @@ static void saa7146_disable_clipping(struct saa7146_dev *dev)
|
|||
static void saa7146_set_clipping_rect(struct saa7146_fh *fh)
|
||||
{
|
||||
struct saa7146_dev *dev = fh->dev;
|
||||
enum v4l2_field field = fh->ov.win.field;
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
enum v4l2_field field = vv->ov.win.field;
|
||||
struct saa7146_video_dma vdma2;
|
||||
u32 clip_format;
|
||||
u32 arbtr_ctrl;
|
||||
|
||||
/* check clipcount, disable clipping if clipcount == 0*/
|
||||
if( fh->ov.nclips == 0 ) {
|
||||
if (vv->ov.nclips == 0) {
|
||||
saa7146_disable_clipping(dev);
|
||||
return;
|
||||
}
|
||||
|
@ -651,8 +652,8 @@ int saa7146_enable_overlay(struct saa7146_fh *fh)
|
|||
struct saa7146_dev *dev = fh->dev;
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
|
||||
saa7146_set_window(dev, fh->ov.win.w.width, fh->ov.win.w.height, fh->ov.win.field);
|
||||
saa7146_set_position(dev, fh->ov.win.w.left, fh->ov.win.w.top, fh->ov.win.w.height, fh->ov.win.field, vv->ov_fmt->pixelformat);
|
||||
saa7146_set_window(dev, vv->ov.win.w.width, vv->ov.win.w.height, vv->ov.win.field);
|
||||
saa7146_set_position(dev, vv->ov.win.w.left, vv->ov.win.w.top, vv->ov.win.w.height, vv->ov.win.field, vv->ov_fmt->pixelformat);
|
||||
saa7146_set_output_format(dev, vv->ov_fmt->trans);
|
||||
saa7146_set_clipping_rect(fh);
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ static int buffer_activate(struct saa7146_dev *dev,
|
|||
DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next);
|
||||
saa7146_set_vbi_capture(dev,buf,next);
|
||||
|
||||
mod_timer(&vv->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
|
||||
mod_timer(&vv->vbi_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
|
||||
|
||||
DEB_VBI("vb:%p\n", vb);
|
||||
saa7146_buffer_queue(dev,&vv->vbi_q,buf);
|
||||
saa7146_buffer_queue(dev, &vv->vbi_dmaq, buf);
|
||||
}
|
||||
|
||||
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
|
@ -335,16 +335,15 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file)
|
|||
/* shut down dma 3 transfers */
|
||||
saa7146_write(dev, MC1, MASK_20);
|
||||
|
||||
if (vv->vbi_q.curr) {
|
||||
saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
|
||||
}
|
||||
if (vv->vbi_dmaq.curr)
|
||||
saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
|
||||
|
||||
videobuf_queue_cancel(&fh->vbi_q);
|
||||
|
||||
vv->vbi_streaming = NULL;
|
||||
|
||||
del_timer(&vv->vbi_q.timeout);
|
||||
del_timer(&fh->vbi_read_timeout);
|
||||
del_timer(&vv->vbi_dmaq.timeout);
|
||||
del_timer(&vv->vbi_read_timeout);
|
||||
|
||||
spin_unlock_irqrestore(&dev->slock, flags);
|
||||
}
|
||||
|
@ -364,12 +363,12 @@ static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
|
|||
{
|
||||
DEB_VBI("dev:%p\n", dev);
|
||||
|
||||
INIT_LIST_HEAD(&vv->vbi_q.queue);
|
||||
INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
|
||||
|
||||
init_timer(&vv->vbi_q.timeout);
|
||||
vv->vbi_q.timeout.function = saa7146_buffer_timeout;
|
||||
vv->vbi_q.timeout.data = (unsigned long)(&vv->vbi_q);
|
||||
vv->vbi_q.dev = dev;
|
||||
init_timer(&vv->vbi_dmaq.timeout);
|
||||
vv->vbi_dmaq.timeout.function = saa7146_buffer_timeout;
|
||||
vv->vbi_dmaq.timeout.data = (unsigned long)(&vv->vbi_dmaq);
|
||||
vv->vbi_dmaq.dev = dev;
|
||||
|
||||
init_waitqueue_head(&vv->vbi_wq);
|
||||
}
|
||||
|
@ -377,6 +376,7 @@ static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
|
|||
static int vbi_open(struct saa7146_dev *dev, struct file *file)
|
||||
{
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
struct saa7146_vv *vv = fh->dev->vv_data;
|
||||
|
||||
u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
|
||||
int ret = 0;
|
||||
|
@ -395,19 +395,6 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
|
|||
saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
|
||||
saa7146_write(dev, MC2, (MASK_04|MASK_20));
|
||||
|
||||
memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
|
||||
|
||||
fh->vbi_fmt.sampling_rate = 27000000;
|
||||
fh->vbi_fmt.offset = 248; /* todo */
|
||||
fh->vbi_fmt.samples_per_line = vbi_pixel_to_capture;
|
||||
fh->vbi_fmt.sample_format = V4L2_PIX_FMT_GREY;
|
||||
|
||||
/* fixme: this only works for PAL */
|
||||
fh->vbi_fmt.start[0] = 5;
|
||||
fh->vbi_fmt.count[0] = 16;
|
||||
fh->vbi_fmt.start[1] = 312;
|
||||
fh->vbi_fmt.count[1] = 16;
|
||||
|
||||
videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
|
||||
&dev->pci->dev, &dev->slock,
|
||||
V4L2_BUF_TYPE_VBI_CAPTURE,
|
||||
|
@ -415,9 +402,8 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
|
|||
sizeof(struct saa7146_buf),
|
||||
file, &dev->v4l2_lock);
|
||||
|
||||
init_timer(&fh->vbi_read_timeout);
|
||||
fh->vbi_read_timeout.function = vbi_read_timeout;
|
||||
fh->vbi_read_timeout.data = (unsigned long)file;
|
||||
vv->vbi_read_timeout.function = vbi_read_timeout;
|
||||
vv->vbi_read_timeout.data = (unsigned long)file;
|
||||
|
||||
/* initialize the brs */
|
||||
if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
|
||||
|
@ -453,16 +439,16 @@ static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
|
|||
struct saa7146_vv *vv = dev->vv_data;
|
||||
spin_lock(&dev->slock);
|
||||
|
||||
if (vv->vbi_q.curr) {
|
||||
DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_q.curr);
|
||||
if (vv->vbi_dmaq.curr) {
|
||||
DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_dmaq.curr);
|
||||
/* this must be += 2, one count for each field */
|
||||
vv->vbi_fieldcount+=2;
|
||||
vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
|
||||
saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
|
||||
vv->vbi_dmaq.curr->vb.field_count = vv->vbi_fieldcount;
|
||||
saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
|
||||
} else {
|
||||
DEB_VBI("dev:%p\n", dev);
|
||||
}
|
||||
saa7146_buffer_next(dev,&vv->vbi_q,1);
|
||||
saa7146_buffer_next(dev, &vv->vbi_dmaq, 1);
|
||||
|
||||
spin_unlock(&dev->slock);
|
||||
}
|
||||
|
@ -488,7 +474,7 @@ static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
mod_timer(&fh->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
|
||||
mod_timer(&vv->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
|
||||
ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
/*
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <media/saa7146_vv.h>
|
||||
#include <media/v4l2-chip-ident.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static int max_memory = 32;
|
||||
|
@ -112,8 +114,8 @@ int saa7146_start_preview(struct saa7146_fh *fh)
|
|||
|
||||
DEB_EE("dev:%p, fh:%p\n", dev, fh);
|
||||
|
||||
/* check if we have overlay informations */
|
||||
if( NULL == fh->ov.fh ) {
|
||||
/* check if we have overlay information */
|
||||
if (vv->ov.fh == NULL) {
|
||||
DEB_D("no overlay data available. try S_FMT first.\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
@ -139,19 +141,18 @@ int saa7146_start_preview(struct saa7146_fh *fh)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
fmt.fmt.win = fh->ov.win;
|
||||
fmt.fmt.win = vv->ov.win;
|
||||
err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
|
||||
if (0 != err) {
|
||||
saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
|
||||
return -EBUSY;
|
||||
}
|
||||
fh->ov.win = fmt.fmt.win;
|
||||
vv->ov_data = &fh->ov;
|
||||
vv->ov.win = fmt.fmt.win;
|
||||
|
||||
DEB_D("%dx%d+%d+%d %s field=%s\n",
|
||||
fh->ov.win.w.width, fh->ov.win.w.height,
|
||||
fh->ov.win.w.left, fh->ov.win.w.top,
|
||||
vv->ov_fmt->name, v4l2_field_names[fh->ov.win.field]);
|
||||
vv->ov.win.w.width, vv->ov.win.w.height,
|
||||
vv->ov.win.w.left, vv->ov.win.w.top,
|
||||
vv->ov_fmt->name, v4l2_field_names[vv->ov.win.field]);
|
||||
|
||||
if (0 != (ret = saa7146_enable_overlay(fh))) {
|
||||
DEB_D("enabling overlay failed: %d\n", ret);
|
||||
|
@ -201,65 +202,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(saa7146_stop_preview);
|
||||
|
||||
/********************************************************************************/
|
||||
/* device controls */
|
||||
|
||||
static struct v4l2_queryctrl controls[] = {
|
||||
{
|
||||
.id = V4L2_CID_BRIGHTNESS,
|
||||
.name = "Brightness",
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
.default_value = 128,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.flags = V4L2_CTRL_FLAG_SLIDER,
|
||||
},{
|
||||
.id = V4L2_CID_CONTRAST,
|
||||
.name = "Contrast",
|
||||
.minimum = 0,
|
||||
.maximum = 127,
|
||||
.step = 1,
|
||||
.default_value = 64,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.flags = V4L2_CTRL_FLAG_SLIDER,
|
||||
},{
|
||||
.id = V4L2_CID_SATURATION,
|
||||
.name = "Saturation",
|
||||
.minimum = 0,
|
||||
.maximum = 127,
|
||||
.step = 1,
|
||||
.default_value = 64,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.flags = V4L2_CTRL_FLAG_SLIDER,
|
||||
},{
|
||||
.id = V4L2_CID_VFLIP,
|
||||
.name = "Vertical Flip",
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
},{
|
||||
.id = V4L2_CID_HFLIP,
|
||||
.name = "Horizontal Flip",
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
},
|
||||
};
|
||||
static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl);
|
||||
|
||||
#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 0)
|
||||
|
||||
static struct v4l2_queryctrl* ctrl_by_id(int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_CONTROLS; i++)
|
||||
if (controls[i].id == id)
|
||||
return controls+i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************************************************/
|
||||
/* common pagetable functions */
|
||||
|
||||
|
@ -413,7 +355,7 @@ static int video_begin(struct saa7146_fh *fh)
|
|||
}
|
||||
}
|
||||
|
||||
fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
|
||||
/* we need to have a valid format set here */
|
||||
BUG_ON(NULL == fmt);
|
||||
|
||||
|
@ -465,7 +407,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
|
||||
/* we need to have a valid format set here */
|
||||
BUG_ON(NULL == fmt);
|
||||
|
||||
|
@ -504,18 +446,25 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
|
|||
|
||||
static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
|
||||
strcpy((char *)cap->driver, "saa7146 v4l2");
|
||||
strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
|
||||
sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
|
||||
cap->version = SAA7146_VERSION_CODE;
|
||||
cap->capabilities =
|
||||
cap->device_caps =
|
||||
V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_VIDEO_OVERLAY |
|
||||
V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING;
|
||||
cap->capabilities |= dev->ext_vv_data->capabilities;
|
||||
cap->device_caps |= dev->ext_vv_data->capabilities;
|
||||
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||
if (vdev->vfl_type == VFL_TYPE_GRABBER)
|
||||
cap->device_caps &=
|
||||
~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
|
||||
else
|
||||
cap->device_caps &=
|
||||
~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -526,6 +475,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
|
|||
|
||||
*fb = vv->ov_fb;
|
||||
fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
|
||||
fb->flags = V4L2_FBUF_FLAG_PRIMARY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -579,135 +529,58 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtd
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
|
||||
int saa7146_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
const struct v4l2_queryctrl *ctrl;
|
||||
|
||||
if ((c->id < V4L2_CID_BASE ||
|
||||
c->id >= V4L2_CID_LASTP1) &&
|
||||
(c->id < V4L2_CID_PRIVATE_BASE ||
|
||||
c->id >= V4L2_CID_PRIVATE_LASTP1))
|
||||
return -EINVAL;
|
||||
|
||||
ctrl = ctrl_by_id(c->id);
|
||||
if (ctrl == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
DEB_EE("VIDIOC_QUERYCTRL: id:%d\n", c->id);
|
||||
*c = *ctrl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
|
||||
{
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
struct saa7146_dev *dev = container_of(ctrl->handler,
|
||||
struct saa7146_dev, ctrl_handler);
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
const struct v4l2_queryctrl *ctrl;
|
||||
u32 value = 0;
|
||||
u32 val;
|
||||
|
||||
ctrl = ctrl_by_id(c->id);
|
||||
if (NULL == ctrl)
|
||||
return -EINVAL;
|
||||
switch (c->id) {
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
value = saa7146_read(dev, BCS_CTRL);
|
||||
c->value = 0xff & (value >> 24);
|
||||
DEB_D("V4L2_CID_BRIGHTNESS: %d\n", c->value);
|
||||
val = saa7146_read(dev, BCS_CTRL);
|
||||
val &= 0x00ffffff;
|
||||
val |= (ctrl->val << 24);
|
||||
saa7146_write(dev, BCS_CTRL, val);
|
||||
saa7146_write(dev, MC2, MASK_22 | MASK_06);
|
||||
break;
|
||||
|
||||
case V4L2_CID_CONTRAST:
|
||||
value = saa7146_read(dev, BCS_CTRL);
|
||||
c->value = 0x7f & (value >> 16);
|
||||
DEB_D("V4L2_CID_CONTRAST: %d\n", c->value);
|
||||
val = saa7146_read(dev, BCS_CTRL);
|
||||
val &= 0xff00ffff;
|
||||
val |= (ctrl->val << 16);
|
||||
saa7146_write(dev, BCS_CTRL, val);
|
||||
saa7146_write(dev, MC2, MASK_22 | MASK_06);
|
||||
break;
|
||||
|
||||
case V4L2_CID_SATURATION:
|
||||
value = saa7146_read(dev, BCS_CTRL);
|
||||
c->value = 0x7f & (value >> 0);
|
||||
DEB_D("V4L2_CID_SATURATION: %d\n", c->value);
|
||||
break;
|
||||
case V4L2_CID_VFLIP:
|
||||
c->value = vv->vflip;
|
||||
DEB_D("V4L2_CID_VFLIP: %d\n", c->value);
|
||||
break;
|
||||
case V4L2_CID_HFLIP:
|
||||
c->value = vv->hflip;
|
||||
DEB_D("V4L2_CID_HFLIP: %d\n", c->value);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
|
||||
{
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
const struct v4l2_queryctrl *ctrl;
|
||||
|
||||
ctrl = ctrl_by_id(c->id);
|
||||
if (NULL == ctrl) {
|
||||
DEB_D("unknown control %d\n", c->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (ctrl->type) {
|
||||
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||
case V4L2_CTRL_TYPE_MENU:
|
||||
case V4L2_CTRL_TYPE_INTEGER:
|
||||
if (c->value < ctrl->minimum)
|
||||
c->value = ctrl->minimum;
|
||||
if (c->value > ctrl->maximum)
|
||||
c->value = ctrl->maximum;
|
||||
break;
|
||||
default:
|
||||
/* nothing */;
|
||||
}
|
||||
|
||||
switch (c->id) {
|
||||
case V4L2_CID_BRIGHTNESS: {
|
||||
u32 value = saa7146_read(dev, BCS_CTRL);
|
||||
value &= 0x00ffffff;
|
||||
value |= (c->value << 24);
|
||||
saa7146_write(dev, BCS_CTRL, value);
|
||||
val = saa7146_read(dev, BCS_CTRL);
|
||||
val &= 0xffffff00;
|
||||
val |= (ctrl->val << 0);
|
||||
saa7146_write(dev, BCS_CTRL, val);
|
||||
saa7146_write(dev, MC2, MASK_22 | MASK_06);
|
||||
break;
|
||||
}
|
||||
case V4L2_CID_CONTRAST: {
|
||||
u32 value = saa7146_read(dev, BCS_CTRL);
|
||||
value &= 0xff00ffff;
|
||||
value |= (c->value << 16);
|
||||
saa7146_write(dev, BCS_CTRL, value);
|
||||
saa7146_write(dev, MC2, MASK_22 | MASK_06);
|
||||
break;
|
||||
}
|
||||
case V4L2_CID_SATURATION: {
|
||||
u32 value = saa7146_read(dev, BCS_CTRL);
|
||||
value &= 0xffffff00;
|
||||
value |= (c->value << 0);
|
||||
saa7146_write(dev, BCS_CTRL, value);
|
||||
saa7146_write(dev, MC2, MASK_22 | MASK_06);
|
||||
break;
|
||||
}
|
||||
|
||||
case V4L2_CID_HFLIP:
|
||||
/* fixme: we can support changing VFLIP and HFLIP here... */
|
||||
if (IS_CAPTURE_ACTIVE(fh) != 0) {
|
||||
DEB_D("V4L2_CID_HFLIP while active capture\n");
|
||||
if ((vv->video_status & STATUS_CAPTURE))
|
||||
return -EBUSY;
|
||||
}
|
||||
vv->hflip = c->value;
|
||||
vv->hflip = ctrl->val;
|
||||
break;
|
||||
|
||||
case V4L2_CID_VFLIP:
|
||||
if (IS_CAPTURE_ACTIVE(fh) != 0) {
|
||||
DEB_D("V4L2_CID_VFLIP while active capture\n");
|
||||
if ((vv->video_status & STATUS_CAPTURE))
|
||||
return -EBUSY;
|
||||
}
|
||||
vv->vflip = c->value;
|
||||
vv->vflip = ctrl->val;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (IS_OVERLAY_ACTIVE(fh) != 0) {
|
||||
if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */
|
||||
struct saa7146_fh *fh = vv->video_fh;
|
||||
|
||||
saa7146_stop_preview(fh);
|
||||
saa7146_start_preview(fh);
|
||||
}
|
||||
|
@ -720,6 +593,8 @@ static int vidioc_g_parm(struct file *file, void *fh,
|
|||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
|
||||
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
parm->parm.capture.readbuffers = 1;
|
||||
v4l2_video_std_frame_period(vv->standard->id,
|
||||
&parm->parm.capture.timeperframe);
|
||||
|
@ -728,19 +603,28 @@ static int vidioc_g_parm(struct file *file, void *fh,
|
|||
|
||||
static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
|
||||
{
|
||||
f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt;
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
|
||||
f->fmt.pix = vv->video_fmt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
|
||||
{
|
||||
f->fmt.win = ((struct saa7146_fh *)fh)->ov.win;
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
|
||||
f->fmt.win = vv->ov.win;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
|
||||
{
|
||||
f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt;
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
|
||||
f->fmt.vbi = vv->vbi_fmt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -787,6 +671,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
|
|||
}
|
||||
|
||||
f->fmt.pix.field = field;
|
||||
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
if (f->fmt.pix.width > maxw)
|
||||
f->fmt.pix.width = maxw;
|
||||
if (f->fmt.pix.height > maxh)
|
||||
|
@ -883,9 +768,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_forma
|
|||
err = vidioc_try_fmt_vid_cap(file, fh, f);
|
||||
if (0 != err)
|
||||
return err;
|
||||
fh->video_fmt = f->fmt.pix;
|
||||
vv->video_fmt = f->fmt.pix;
|
||||
DEB_EE("set to pixelformat '%4.4s'\n",
|
||||
(char *)&fh->video_fmt.pixelformat);
|
||||
(char *)&vv->video_fmt.pixelformat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -900,17 +785,17 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_f
|
|||
err = vidioc_try_fmt_vid_overlay(file, fh, f);
|
||||
if (0 != err)
|
||||
return err;
|
||||
fh->ov.win = f->fmt.win;
|
||||
fh->ov.nclips = f->fmt.win.clipcount;
|
||||
if (fh->ov.nclips > 16)
|
||||
fh->ov.nclips = 16;
|
||||
if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
|
||||
sizeof(struct v4l2_clip) * fh->ov.nclips)) {
|
||||
vv->ov.win = f->fmt.win;
|
||||
vv->ov.nclips = f->fmt.win.clipcount;
|
||||
if (vv->ov.nclips > 16)
|
||||
vv->ov.nclips = 16;
|
||||
if (copy_from_user(vv->ov.clips, f->fmt.win.clips,
|
||||
sizeof(struct v4l2_clip) * vv->ov.nclips)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* fh->ov.fh is used to indicate that we have valid overlay informations, too */
|
||||
fh->ov.fh = fh;
|
||||
/* vv->ov.fh is used to indicate that we have valid overlay informations, too */
|
||||
vv->ov.fh = fh;
|
||||
|
||||
/* check if our current overlay is active */
|
||||
if (IS_OVERLAY_ACTIVE(fh) != 0) {
|
||||
|
@ -1111,10 +996,14 @@ static int vidioc_g_chip_ident(struct file *file, void *__fh,
|
|||
|
||||
chip->ident = V4L2_IDENT_NONE;
|
||||
chip->revision = 0;
|
||||
if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) {
|
||||
chip->ident = V4L2_IDENT_SAA7146;
|
||||
if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
|
||||
if (v4l2_chip_match_host(&chip->match))
|
||||
chip->ident = V4L2_IDENT_SAA7146;
|
||||
return 0;
|
||||
}
|
||||
if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
|
||||
chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
|
||||
return -EINVAL;
|
||||
return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
|
||||
core, g_chip_ident, chip);
|
||||
}
|
||||
|
@ -1129,7 +1018,6 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
|
|||
.vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
|
||||
.vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
|
||||
.vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
|
||||
.vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
|
||||
.vidioc_g_chip_ident = vidioc_g_chip_ident,
|
||||
|
||||
.vidioc_overlay = vidioc_overlay,
|
||||
|
@ -1141,12 +1029,29 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
|
|||
.vidioc_dqbuf = vidioc_dqbuf,
|
||||
.vidioc_g_std = vidioc_g_std,
|
||||
.vidioc_s_std = vidioc_s_std,
|
||||
.vidioc_queryctrl = vidioc_queryctrl,
|
||||
.vidioc_g_ctrl = vidioc_g_ctrl,
|
||||
.vidioc_s_ctrl = vidioc_s_ctrl,
|
||||
.vidioc_streamon = vidioc_streamon,
|
||||
.vidioc_streamoff = vidioc_streamoff,
|
||||
.vidioc_g_parm = vidioc_g_parm,
|
||||
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
|
||||
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
||||
};
|
||||
|
||||
const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
|
||||
.vidioc_querycap = vidioc_querycap,
|
||||
.vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
|
||||
.vidioc_g_chip_ident = vidioc_g_chip_ident,
|
||||
|
||||
.vidioc_reqbufs = vidioc_reqbufs,
|
||||
.vidioc_querybuf = vidioc_querybuf,
|
||||
.vidioc_qbuf = vidioc_qbuf,
|
||||
.vidioc_dqbuf = vidioc_dqbuf,
|
||||
.vidioc_g_std = vidioc_g_std,
|
||||
.vidioc_s_std = vidioc_s_std,
|
||||
.vidioc_streamon = vidioc_streamon,
|
||||
.vidioc_streamoff = vidioc_streamoff,
|
||||
.vidioc_g_parm = vidioc_g_parm,
|
||||
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
|
||||
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
||||
};
|
||||
|
||||
/*********************************************************************************/
|
||||
|
@ -1161,7 +1066,7 @@ static int buffer_activate (struct saa7146_dev *dev,
|
|||
buf->vb.state = VIDEOBUF_ACTIVE;
|
||||
saa7146_set_capture(dev,buf,next);
|
||||
|
||||
mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT);
|
||||
mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1185,44 +1090,44 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
DEB_CAP("vbuf:%p\n", vb);
|
||||
|
||||
/* sanity checks */
|
||||
if (fh->video_fmt.width < 48 ||
|
||||
fh->video_fmt.height < 32 ||
|
||||
fh->video_fmt.width > vv->standard->h_max_out ||
|
||||
fh->video_fmt.height > vv->standard->v_max_out) {
|
||||
if (vv->video_fmt.width < 48 ||
|
||||
vv->video_fmt.height < 32 ||
|
||||
vv->video_fmt.width > vv->standard->h_max_out ||
|
||||
vv->video_fmt.height > vv->standard->v_max_out) {
|
||||
DEB_D("w (%d) / h (%d) out of bounds\n",
|
||||
fh->video_fmt.width, fh->video_fmt.height);
|
||||
vv->video_fmt.width, vv->video_fmt.height);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size = fh->video_fmt.sizeimage;
|
||||
size = vv->video_fmt.sizeimage;
|
||||
if (0 != buf->vb.baddr && buf->vb.bsize < size) {
|
||||
DEB_D("size mismatch\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
|
||||
fh->video_fmt.width, fh->video_fmt.height,
|
||||
size, v4l2_field_names[fh->video_fmt.field]);
|
||||
if (buf->vb.width != fh->video_fmt.width ||
|
||||
buf->vb.bytesperline != fh->video_fmt.bytesperline ||
|
||||
buf->vb.height != fh->video_fmt.height ||
|
||||
vv->video_fmt.width, vv->video_fmt.height,
|
||||
size, v4l2_field_names[vv->video_fmt.field]);
|
||||
if (buf->vb.width != vv->video_fmt.width ||
|
||||
buf->vb.bytesperline != vv->video_fmt.bytesperline ||
|
||||
buf->vb.height != vv->video_fmt.height ||
|
||||
buf->vb.size != size ||
|
||||
buf->vb.field != field ||
|
||||
buf->vb.field != fh->video_fmt.field ||
|
||||
buf->fmt != &fh->video_fmt) {
|
||||
buf->vb.field != vv->video_fmt.field ||
|
||||
buf->fmt != &vv->video_fmt) {
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
}
|
||||
|
||||
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
|
||||
struct saa7146_format *sfmt;
|
||||
|
||||
buf->vb.bytesperline = fh->video_fmt.bytesperline;
|
||||
buf->vb.width = fh->video_fmt.width;
|
||||
buf->vb.height = fh->video_fmt.height;
|
||||
buf->vb.bytesperline = vv->video_fmt.bytesperline;
|
||||
buf->vb.width = vv->video_fmt.width;
|
||||
buf->vb.height = vv->video_fmt.height;
|
||||
buf->vb.size = size;
|
||||
buf->vb.field = field;
|
||||
buf->fmt = &fh->video_fmt;
|
||||
buf->vb.field = fh->video_fmt.field;
|
||||
buf->fmt = &vv->video_fmt;
|
||||
buf->vb.field = vv->video_fmt.field;
|
||||
|
||||
sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
|
@ -1258,11 +1163,12 @@ static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned
|
|||
{
|
||||
struct file *file = q->priv_data;
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
struct saa7146_vv *vv = fh->dev->vv_data;
|
||||
|
||||
if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
|
||||
*count = MAX_SAA7146_CAPTURE_BUFFERS;
|
||||
|
||||
*size = fh->video_fmt.sizeimage;
|
||||
*size = vv->video_fmt.sizeimage;
|
||||
|
||||
/* check if we exceed the "max_memory" parameter */
|
||||
if( (*count * *size) > (max_memory*1048576) ) {
|
||||
|
@ -1283,7 +1189,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
|||
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
|
||||
|
||||
DEB_CAP("vbuf:%p\n", vb);
|
||||
saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
|
||||
saa7146_buffer_queue(fh->dev, &vv->video_dmaq, buf);
|
||||
}
|
||||
|
||||
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
|
@ -1312,12 +1218,12 @@ static struct videobuf_queue_ops video_qops = {
|
|||
|
||||
static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
|
||||
{
|
||||
INIT_LIST_HEAD(&vv->video_q.queue);
|
||||
INIT_LIST_HEAD(&vv->video_dmaq.queue);
|
||||
|
||||
init_timer(&vv->video_q.timeout);
|
||||
vv->video_q.timeout.function = saa7146_buffer_timeout;
|
||||
vv->video_q.timeout.data = (unsigned long)(&vv->video_q);
|
||||
vv->video_q.dev = dev;
|
||||
init_timer(&vv->video_dmaq.timeout);
|
||||
vv->video_dmaq.timeout.function = saa7146_buffer_timeout;
|
||||
vv->video_dmaq.timeout.data = (unsigned long)(&vv->video_dmaq);
|
||||
vv->video_dmaq.dev = dev;
|
||||
|
||||
/* set some default values */
|
||||
vv->standard = &dev->ext_vv_data->stds[0];
|
||||
|
@ -1331,15 +1237,6 @@ static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
|
|||
static int video_open(struct saa7146_dev *dev, struct file *file)
|
||||
{
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
struct saa7146_format *sfmt;
|
||||
|
||||
fh->video_fmt.width = 384;
|
||||
fh->video_fmt.height = 288;
|
||||
fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
|
||||
fh->video_fmt.bytesperline = 0;
|
||||
fh->video_fmt.field = V4L2_FIELD_ANY;
|
||||
sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
|
||||
|
||||
videobuf_queue_sg_init(&fh->video_q, &video_qops,
|
||||
&dev->pci->dev, &dev->slock,
|
||||
|
@ -1371,7 +1268,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
|
|||
static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
|
||||
{
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
struct saa7146_dmaqueue *q = &vv->video_q;
|
||||
struct saa7146_dmaqueue *q = &vv->video_dmaq;
|
||||
|
||||
spin_lock(&dev->slock);
|
||||
DEB_CAP("called\n");
|
||||
|
|
|
@ -204,6 +204,27 @@ config MEDIA_TUNER_TDA18218
|
|||
help
|
||||
NXP TDA18218 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_FC0011
|
||||
tristate "Fitipower FC0011 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Fitipower FC0011 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_FC0012
|
||||
tristate "Fitipower FC0012 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Fitipower FC0012 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_FC0013
|
||||
tristate "Fitipower FC0013 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Fitipower FC0013 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_TDA18212
|
||||
tristate "NXP TDA18212 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
|
@ -211,4 +232,10 @@ config MEDIA_TUNER_TDA18212
|
|||
help
|
||||
NXP TDA18212 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_TUA9001
|
||||
tristate "Infineon TUA 9001 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Infineon TUA 9001 silicon tuner driver.
|
||||
endmenu
|
||||
|
|
|
@ -28,6 +28,10 @@ obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
|
|||
obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
|
||||
obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
|
||||
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
|
||||
|
|
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
* Fitipower FC0011 tuner driver
|
||||
*
|
||||
* Copyright (C) 2012 Michael Buesch <m@bues.ch>
|
||||
*
|
||||
* Derived from FC0012 tuner driver:
|
||||
* Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "fc0011.h"
|
||||
|
||||
|
||||
/* Tuner registers */
|
||||
enum {
|
||||
FC11_REG_0,
|
||||
FC11_REG_FA, /* FA */
|
||||
FC11_REG_FP, /* FP */
|
||||
FC11_REG_XINHI, /* XIN high 8 bit */
|
||||
FC11_REG_XINLO, /* XIN low 8 bit */
|
||||
FC11_REG_VCO, /* VCO */
|
||||
FC11_REG_VCOSEL, /* VCO select */
|
||||
FC11_REG_7, /* Unknown tuner reg 7 */
|
||||
FC11_REG_8, /* Unknown tuner reg 8 */
|
||||
FC11_REG_9,
|
||||
FC11_REG_10, /* Unknown tuner reg 10 */
|
||||
FC11_REG_11, /* Unknown tuner reg 11 */
|
||||
FC11_REG_12,
|
||||
FC11_REG_RCCAL, /* RC calibrate */
|
||||
FC11_REG_VCOCAL, /* VCO calibrate */
|
||||
FC11_REG_15,
|
||||
FC11_REG_16, /* Unknown tuner reg 16 */
|
||||
FC11_REG_17,
|
||||
|
||||
FC11_NR_REGS, /* Number of registers */
|
||||
};
|
||||
|
||||
enum FC11_REG_VCOSEL_bits {
|
||||
FC11_VCOSEL_2 = 0x08, /* VCO select 2 */
|
||||
FC11_VCOSEL_1 = 0x10, /* VCO select 1 */
|
||||
FC11_VCOSEL_CLKOUT = 0x20, /* Fix clock out */
|
||||
FC11_VCOSEL_BW7M = 0x40, /* 7MHz bw */
|
||||
FC11_VCOSEL_BW6M = 0x80, /* 6MHz bw */
|
||||
};
|
||||
|
||||
enum FC11_REG_RCCAL_bits {
|
||||
FC11_RCCAL_FORCE = 0x10, /* force */
|
||||
};
|
||||
|
||||
enum FC11_REG_VCOCAL_bits {
|
||||
FC11_VCOCAL_RUN = 0, /* VCO calibration run */
|
||||
FC11_VCOCAL_VALUEMASK = 0x3F, /* VCO calibration value mask */
|
||||
FC11_VCOCAL_OK = 0x40, /* VCO calibration Ok */
|
||||
FC11_VCOCAL_RESET = 0x80, /* VCO calibration reset */
|
||||
};
|
||||
|
||||
|
||||
struct fc0011_priv {
|
||||
struct i2c_adapter *i2c;
|
||||
u8 addr;
|
||||
|
||||
u32 frequency;
|
||||
u32 bandwidth;
|
||||
};
|
||||
|
||||
|
||||
static int fc0011_writereg(struct fc0011_priv *priv, u8 reg, u8 val)
|
||||
{
|
||||
u8 buf[2] = { reg, val };
|
||||
struct i2c_msg msg = { .addr = priv->addr,
|
||||
.flags = 0, .buf = buf, .len = 2 };
|
||||
|
||||
if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
|
||||
dev_err(&priv->i2c->dev,
|
||||
"I2C write reg failed, reg: %02x, val: %02x\n",
|
||||
reg, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val)
|
||||
{
|
||||
u8 dummy;
|
||||
struct i2c_msg msg[2] = {
|
||||
{ .addr = priv->addr,
|
||||
.flags = 0, .buf = ®, .len = 1 },
|
||||
{ .addr = priv->addr,
|
||||
.flags = I2C_M_RD, .buf = val ? : &dummy, .len = 1 },
|
||||
};
|
||||
|
||||
if (i2c_transfer(priv->i2c, msg, 2) != 2) {
|
||||
dev_err(&priv->i2c->dev,
|
||||
"I2C read failed, reg: %02x\n", reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0011_release(struct dvb_frontend *fe)
|
||||
{
|
||||
kfree(fe->tuner_priv);
|
||||
fe->tuner_priv = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0011_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct fc0011_priv *priv = fe->tuner_priv;
|
||||
int err;
|
||||
|
||||
if (WARN_ON(!fe->callback))
|
||||
return -EINVAL;
|
||||
|
||||
err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
|
||||
FC0011_FE_CALLBACK_POWER, priv->addr);
|
||||
if (err) {
|
||||
dev_err(&priv->i2c->dev, "Power-on callback failed\n");
|
||||
return err;
|
||||
}
|
||||
err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
|
||||
FC0011_FE_CALLBACK_RESET, priv->addr);
|
||||
if (err) {
|
||||
dev_err(&priv->i2c->dev, "Reset callback failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initiate VCO calibration */
|
||||
static int fc0011_vcocal_trigger(struct fc0011_priv *priv)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RESET);
|
||||
if (err)
|
||||
return err;
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read VCO calibration value */
|
||||
static int fc0011_vcocal_read(struct fc0011_priv *priv, u8 *value)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
|
||||
if (err)
|
||||
return err;
|
||||
usleep_range(10000, 20000);
|
||||
err = fc0011_readreg(priv, FC11_REG_VCOCAL, value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0011_set_params(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
struct fc0011_priv *priv = fe->tuner_priv;
|
||||
int err;
|
||||
unsigned int i, vco_retries;
|
||||
u32 freq = p->frequency / 1000;
|
||||
u32 bandwidth = p->bandwidth_hz / 1000;
|
||||
u32 fvco, xin, xdiv, xdivr;
|
||||
u16 frac;
|
||||
u8 fa, fp, vco_sel, vco_cal;
|
||||
u8 regs[FC11_NR_REGS] = { };
|
||||
|
||||
regs[FC11_REG_7] = 0x0F;
|
||||
regs[FC11_REG_8] = 0x3E;
|
||||
regs[FC11_REG_10] = 0xB8;
|
||||
regs[FC11_REG_11] = 0x80;
|
||||
regs[FC11_REG_RCCAL] = 0x04;
|
||||
err = fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
|
||||
if (err)
|
||||
return -EIO;
|
||||
|
||||
/* Set VCO freq and VCO div */
|
||||
if (freq < 54000) {
|
||||
fvco = freq * 64;
|
||||
regs[FC11_REG_VCO] = 0x82;
|
||||
} else if (freq < 108000) {
|
||||
fvco = freq * 32;
|
||||
regs[FC11_REG_VCO] = 0x42;
|
||||
} else if (freq < 216000) {
|
||||
fvco = freq * 16;
|
||||
regs[FC11_REG_VCO] = 0x22;
|
||||
} else if (freq < 432000) {
|
||||
fvco = freq * 8;
|
||||
regs[FC11_REG_VCO] = 0x12;
|
||||
} else {
|
||||
fvco = freq * 4;
|
||||
regs[FC11_REG_VCO] = 0x0A;
|
||||
}
|
||||
|
||||
/* Calc XIN. The PLL reference frequency is 18 MHz. */
|
||||
xdiv = fvco / 18000;
|
||||
frac = fvco - xdiv * 18000;
|
||||
frac = (frac << 15) / 18000;
|
||||
if (frac >= 16384)
|
||||
frac += 32786;
|
||||
if (!frac)
|
||||
xin = 0;
|
||||
else if (frac < 511)
|
||||
xin = 512;
|
||||
else if (frac < 65026)
|
||||
xin = frac;
|
||||
else
|
||||
xin = 65024;
|
||||
regs[FC11_REG_XINHI] = xin >> 8;
|
||||
regs[FC11_REG_XINLO] = xin;
|
||||
|
||||
/* Calc FP and FA */
|
||||
xdivr = xdiv;
|
||||
if (fvco - xdiv * 18000 >= 9000)
|
||||
xdivr += 1; /* round */
|
||||
fp = xdivr / 8;
|
||||
fa = xdivr - fp * 8;
|
||||
if (fa < 2) {
|
||||
fp -= 1;
|
||||
fa += 8;
|
||||
}
|
||||
if (fp > 0x1F) {
|
||||
fp &= 0x1F;
|
||||
fa &= 0xF;
|
||||
}
|
||||
if (fa >= fp) {
|
||||
dev_warn(&priv->i2c->dev,
|
||||
"fa %02X >= fp %02X, but trying to continue\n",
|
||||
(unsigned int)(u8)fa, (unsigned int)(u8)fp);
|
||||
}
|
||||
regs[FC11_REG_FA] = fa;
|
||||
regs[FC11_REG_FP] = fp;
|
||||
|
||||
/* Select bandwidth */
|
||||
switch (bandwidth) {
|
||||
case 8000:
|
||||
break;
|
||||
case 7000:
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW7M;
|
||||
break;
|
||||
default:
|
||||
dev_warn(&priv->i2c->dev, "Unsupported bandwidth %u kHz. "
|
||||
"Using 6000 kHz.\n",
|
||||
bandwidth);
|
||||
bandwidth = 6000;
|
||||
/* fallthrough */
|
||||
case 6000:
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW6M;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pre VCO select */
|
||||
if (fvco < 2320000) {
|
||||
vco_sel = 0;
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
} else if (fvco < 3080000) {
|
||||
vco_sel = 1;
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
|
||||
} else {
|
||||
vco_sel = 2;
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
|
||||
}
|
||||
|
||||
/* Fix for low freqs */
|
||||
if (freq < 45000) {
|
||||
regs[FC11_REG_FA] = 0x6;
|
||||
regs[FC11_REG_FP] = 0x11;
|
||||
}
|
||||
|
||||
/* Clock out fix */
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_CLKOUT;
|
||||
|
||||
/* Write the cached registers */
|
||||
for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++) {
|
||||
err = fc0011_writereg(priv, i, regs[i]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* VCO calibration */
|
||||
err = fc0011_vcocal_trigger(priv);
|
||||
if (err)
|
||||
return err;
|
||||
err = fc0011_vcocal_read(priv, &vco_cal);
|
||||
if (err)
|
||||
return err;
|
||||
vco_retries = 0;
|
||||
while (!(vco_cal & FC11_VCOCAL_OK) && vco_retries < 3) {
|
||||
/* Reset the tuner and try again */
|
||||
err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
|
||||
FC0011_FE_CALLBACK_RESET, priv->addr);
|
||||
if (err) {
|
||||
dev_err(&priv->i2c->dev, "Failed to reset tuner\n");
|
||||
return err;
|
||||
}
|
||||
/* Reinit tuner config */
|
||||
err = 0;
|
||||
for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++)
|
||||
err |= fc0011_writereg(priv, i, regs[i]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
|
||||
err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
|
||||
if (err)
|
||||
return -EIO;
|
||||
/* VCO calibration */
|
||||
err = fc0011_vcocal_trigger(priv);
|
||||
if (err)
|
||||
return err;
|
||||
err = fc0011_vcocal_read(priv, &vco_cal);
|
||||
if (err)
|
||||
return err;
|
||||
vco_retries++;
|
||||
}
|
||||
if (!(vco_cal & FC11_VCOCAL_OK)) {
|
||||
dev_err(&priv->i2c->dev,
|
||||
"Failed to read VCO calibration value (got %02X)\n",
|
||||
(unsigned int)vco_cal);
|
||||
return -EIO;
|
||||
}
|
||||
vco_cal &= FC11_VCOCAL_VALUEMASK;
|
||||
|
||||
switch (vco_sel) {
|
||||
case 0:
|
||||
if (vco_cal < 8) {
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOSEL,
|
||||
regs[FC11_REG_VCOSEL]);
|
||||
if (err)
|
||||
return err;
|
||||
err = fc0011_vcocal_trigger(priv);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOSEL,
|
||||
regs[FC11_REG_VCOSEL]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (vco_cal < 5) {
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOSEL,
|
||||
regs[FC11_REG_VCOSEL]);
|
||||
if (err)
|
||||
return err;
|
||||
err = fc0011_vcocal_trigger(priv);
|
||||
if (err)
|
||||
return err;
|
||||
} else if (vco_cal <= 48) {
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOSEL,
|
||||
regs[FC11_REG_VCOSEL]);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOSEL,
|
||||
regs[FC11_REG_VCOSEL]);
|
||||
if (err)
|
||||
return err;
|
||||
err = fc0011_vcocal_trigger(priv);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (vco_cal > 53) {
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOSEL,
|
||||
regs[FC11_REG_VCOSEL]);
|
||||
if (err)
|
||||
return err;
|
||||
err = fc0011_vcocal_trigger(priv);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
|
||||
regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
|
||||
err = fc0011_writereg(priv, FC11_REG_VCOSEL,
|
||||
regs[FC11_REG_VCOSEL]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
err = fc0011_vcocal_read(priv, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
usleep_range(10000, 50000);
|
||||
|
||||
err = fc0011_readreg(priv, FC11_REG_RCCAL, ®s[FC11_REG_RCCAL]);
|
||||
if (err)
|
||||
return err;
|
||||
regs[FC11_REG_RCCAL] |= FC11_RCCAL_FORCE;
|
||||
err = fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
|
||||
if (err)
|
||||
return err;
|
||||
err = fc0011_writereg(priv, FC11_REG_16, 0xB);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dev_dbg(&priv->i2c->dev, "Tuned to "
|
||||
"fa=%02X fp=%02X xin=%02X%02X vco=%02X vcosel=%02X "
|
||||
"vcocal=%02X(%u) bw=%u\n",
|
||||
(unsigned int)regs[FC11_REG_FA],
|
||||
(unsigned int)regs[FC11_REG_FP],
|
||||
(unsigned int)regs[FC11_REG_XINHI],
|
||||
(unsigned int)regs[FC11_REG_XINLO],
|
||||
(unsigned int)regs[FC11_REG_VCO],
|
||||
(unsigned int)regs[FC11_REG_VCOSEL],
|
||||
(unsigned int)vco_cal, vco_retries,
|
||||
(unsigned int)bandwidth);
|
||||
|
||||
priv->frequency = p->frequency;
|
||||
priv->bandwidth = p->bandwidth_hz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0011_get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
struct fc0011_priv *priv = fe->tuner_priv;
|
||||
|
||||
*frequency = priv->frequency;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0011_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
*frequency = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0011_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
|
||||
{
|
||||
struct fc0011_priv *priv = fe->tuner_priv;
|
||||
|
||||
*bandwidth = priv->bandwidth;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dvb_tuner_ops fc0011_tuner_ops = {
|
||||
.info = {
|
||||
.name = "Fitipower FC0011",
|
||||
|
||||
.frequency_min = 45000000,
|
||||
.frequency_max = 1000000000,
|
||||
},
|
||||
|
||||
.release = fc0011_release,
|
||||
.init = fc0011_init,
|
||||
|
||||
.set_params = fc0011_set_params,
|
||||
|
||||
.get_frequency = fc0011_get_frequency,
|
||||
.get_if_frequency = fc0011_get_if_frequency,
|
||||
.get_bandwidth = fc0011_get_bandwidth,
|
||||
};
|
||||
|
||||
struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
const struct fc0011_config *config)
|
||||
{
|
||||
struct fc0011_priv *priv;
|
||||
|
||||
priv = kzalloc(sizeof(struct fc0011_priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return NULL;
|
||||
|
||||
priv->i2c = i2c;
|
||||
priv->addr = config->i2c_address;
|
||||
|
||||
fe->tuner_priv = priv;
|
||||
fe->ops.tuner_ops = fc0011_tuner_ops;
|
||||
|
||||
dev_info(&priv->i2c->dev, "Fitipower FC0011 tuner attached\n");
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(fc0011_attach);
|
||||
|
||||
MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver");
|
||||
MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef LINUX_FC0011_H_
|
||||
#define LINUX_FC0011_H_
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
||||
/** struct fc0011_config - fc0011 hardware config
|
||||
*
|
||||
* @i2c_address: I2C bus address.
|
||||
*/
|
||||
struct fc0011_config {
|
||||
u8 i2c_address;
|
||||
};
|
||||
|
||||
/** enum fc0011_fe_callback_commands - Frontend callbacks
|
||||
*
|
||||
* @FC0011_FE_CALLBACK_POWER: Power on tuner hardware.
|
||||
* @FC0011_FE_CALLBACK_RESET: Request a tuner reset.
|
||||
*/
|
||||
enum fc0011_fe_callback_commands {
|
||||
FC0011_FE_CALLBACK_POWER,
|
||||
FC0011_FE_CALLBACK_RESET,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_MEDIA_TUNER_FC0011) ||\
|
||||
defined(CONFIG_MEDIA_TUNER_FC0011_MODULE)
|
||||
struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
const struct fc0011_config *config);
|
||||
#else
|
||||
static inline
|
||||
struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
const struct fc0011_config *config)
|
||||
{
|
||||
dev_err(&i2c->dev, "fc0011 driver disabled in Kconfig\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LINUX_FC0011_H_ */
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Fitipower FC0012 tuner driver - private includes
|
||||
*
|
||||
* Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _FC0012_PRIV_H_
|
||||
#define _FC0012_PRIV_H_
|
||||
|
||||
#define LOG_PREFIX "fc0012"
|
||||
|
||||
#undef err
|
||||
#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef info
|
||||
#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef warn
|
||||
#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
|
||||
|
||||
struct fc0012_priv {
|
||||
struct i2c_adapter *i2c;
|
||||
u8 addr;
|
||||
u8 dual_master;
|
||||
u8 xtal_freq;
|
||||
|
||||
u32 frequency;
|
||||
u32 bandwidth;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* Fitipower FC0012 tuner driver
|
||||
*
|
||||
* Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "fc0012.h"
|
||||
#include "fc0012-priv.h"
|
||||
|
||||
static int fc0012_writereg(struct fc0012_priv *priv, u8 reg, u8 val)
|
||||
{
|
||||
u8 buf[2] = {reg, val};
|
||||
struct i2c_msg msg = {
|
||||
.addr = priv->addr, .flags = 0, .buf = buf, .len = 2
|
||||
};
|
||||
|
||||
if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
|
||||
err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val)
|
||||
{
|
||||
struct i2c_msg msg[2] = {
|
||||
{ .addr = priv->addr, .flags = 0, .buf = ®, .len = 1 },
|
||||
{ .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
|
||||
};
|
||||
|
||||
if (i2c_transfer(priv->i2c, msg, 2) != 2) {
|
||||
err("I2C read reg failed, reg: %02x", reg);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0012_release(struct dvb_frontend *fe)
|
||||
{
|
||||
kfree(fe->tuner_priv);
|
||||
fe->tuner_priv = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0012_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct fc0012_priv *priv = fe->tuner_priv;
|
||||
int i, ret = 0;
|
||||
unsigned char reg[] = {
|
||||
0x00, /* dummy reg. 0 */
|
||||
0x05, /* reg. 0x01 */
|
||||
0x10, /* reg. 0x02 */
|
||||
0x00, /* reg. 0x03 */
|
||||
0x00, /* reg. 0x04 */
|
||||
0x0f, /* reg. 0x05: may also be 0x0a */
|
||||
0x00, /* reg. 0x06: divider 2, VCO slow */
|
||||
0x00, /* reg. 0x07: may also be 0x0f */
|
||||
0xff, /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
|
||||
Loop Bw 1/8 */
|
||||
0x6e, /* reg. 0x09: Disable LoopThrough, Enable LoopThrough: 0x6f */
|
||||
0xb8, /* reg. 0x0a: Disable LO Test Buffer */
|
||||
0x82, /* reg. 0x0b: Output Clock is same as clock frequency,
|
||||
may also be 0x83 */
|
||||
0xfc, /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
|
||||
0x02, /* reg. 0x0d: AGC Not Forcing & LNA Forcing, 0x02 for DVB-T */
|
||||
0x00, /* reg. 0x0e */
|
||||
0x00, /* reg. 0x0f */
|
||||
0x00, /* reg. 0x10: may also be 0x0d */
|
||||
0x00, /* reg. 0x11 */
|
||||
0x1f, /* reg. 0x12: Set to maximum gain */
|
||||
0x08, /* reg. 0x13: Set to Middle Gain: 0x08,
|
||||
Low Gain: 0x00, High Gain: 0x10, enable IX2: 0x80 */
|
||||
0x00, /* reg. 0x14 */
|
||||
0x04, /* reg. 0x15: Enable LNA COMPS */
|
||||
};
|
||||
|
||||
switch (priv->xtal_freq) {
|
||||
case FC_XTAL_27_MHZ:
|
||||
case FC_XTAL_28_8_MHZ:
|
||||
reg[0x07] |= 0x20;
|
||||
break;
|
||||
case FC_XTAL_36_MHZ:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (priv->dual_master)
|
||||
reg[0x0c] |= 0x02;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
for (i = 1; i < sizeof(reg); i++) {
|
||||
ret = fc0012_writereg(priv, i, reg[i]);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
if (ret)
|
||||
err("fc0012_writereg failed: %d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fc0012_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
/* nothing to do here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0012_set_params(struct dvb_frontend *fe)
|
||||
{
|
||||
struct fc0012_priv *priv = fe->tuner_priv;
|
||||
int i, ret = 0;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 freq = p->frequency / 1000;
|
||||
u32 delsys = p->delivery_system;
|
||||
unsigned char reg[7], am, pm, multi, tmp;
|
||||
unsigned long f_vco;
|
||||
unsigned short xtal_freq_khz_2, xin, xdiv;
|
||||
int vco_select = false;
|
||||
|
||||
if (fe->callback) {
|
||||
ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
|
||||
FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (priv->xtal_freq) {
|
||||
case FC_XTAL_27_MHZ:
|
||||
xtal_freq_khz_2 = 27000 / 2;
|
||||
break;
|
||||
case FC_XTAL_36_MHZ:
|
||||
xtal_freq_khz_2 = 36000 / 2;
|
||||
break;
|
||||
case FC_XTAL_28_8_MHZ:
|
||||
default:
|
||||
xtal_freq_khz_2 = 28800 / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
/* select frequency divider and the frequency of VCO */
|
||||
if (freq < 37084) { /* freq * 96 < 3560000 */
|
||||
multi = 96;
|
||||
reg[5] = 0x82;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 55625) { /* freq * 64 < 3560000 */
|
||||
multi = 64;
|
||||
reg[5] = 0x82;
|
||||
reg[6] = 0x02;
|
||||
} else if (freq < 74167) { /* freq * 48 < 3560000 */
|
||||
multi = 48;
|
||||
reg[5] = 0x42;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 111250) { /* freq * 32 < 3560000 */
|
||||
multi = 32;
|
||||
reg[5] = 0x42;
|
||||
reg[6] = 0x02;
|
||||
} else if (freq < 148334) { /* freq * 24 < 3560000 */
|
||||
multi = 24;
|
||||
reg[5] = 0x22;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 222500) { /* freq * 16 < 3560000 */
|
||||
multi = 16;
|
||||
reg[5] = 0x22;
|
||||
reg[6] = 0x02;
|
||||
} else if (freq < 296667) { /* freq * 12 < 3560000 */
|
||||
multi = 12;
|
||||
reg[5] = 0x12;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 445000) { /* freq * 8 < 3560000 */
|
||||
multi = 8;
|
||||
reg[5] = 0x12;
|
||||
reg[6] = 0x02;
|
||||
} else if (freq < 593334) { /* freq * 6 < 3560000 */
|
||||
multi = 6;
|
||||
reg[5] = 0x0a;
|
||||
reg[6] = 0x00;
|
||||
} else {
|
||||
multi = 4;
|
||||
reg[5] = 0x0a;
|
||||
reg[6] = 0x02;
|
||||
}
|
||||
|
||||
f_vco = freq * multi;
|
||||
|
||||
if (f_vco >= 3060000) {
|
||||
reg[6] |= 0x08;
|
||||
vco_select = true;
|
||||
}
|
||||
|
||||
if (freq >= 45000) {
|
||||
/* From divided value (XDIV) determined the FA and FP value */
|
||||
xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
|
||||
if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
|
||||
xdiv++;
|
||||
|
||||
pm = (unsigned char)(xdiv / 8);
|
||||
am = (unsigned char)(xdiv - (8 * pm));
|
||||
|
||||
if (am < 2) {
|
||||
reg[1] = am + 8;
|
||||
reg[2] = pm - 1;
|
||||
} else {
|
||||
reg[1] = am;
|
||||
reg[2] = pm;
|
||||
}
|
||||
} else {
|
||||
/* fix for frequency less than 45 MHz */
|
||||
reg[1] = 0x06;
|
||||
reg[2] = 0x11;
|
||||
}
|
||||
|
||||
/* fix clock out */
|
||||
reg[6] |= 0x20;
|
||||
|
||||
/* From VCO frequency determines the XIN ( fractional part of Delta
|
||||
Sigma PLL) and divided value (XDIV) */
|
||||
xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
|
||||
xin = (xin << 15) / xtal_freq_khz_2;
|
||||
if (xin >= 16384)
|
||||
xin += 32768;
|
||||
|
||||
reg[3] = xin >> 8; /* xin with 9 bit resolution */
|
||||
reg[4] = xin & 0xff;
|
||||
|
||||
if (delsys == SYS_DVBT) {
|
||||
reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
|
||||
switch (p->bandwidth_hz) {
|
||||
case 6000000:
|
||||
reg[6] |= 0x80;
|
||||
break;
|
||||
case 7000000:
|
||||
reg[6] |= 0x40;
|
||||
break;
|
||||
case 8000000:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
err("%s: modulation type not supported!", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* modified for Realtek demod */
|
||||
reg[5] |= 0x07;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
for (i = 1; i <= 6; i++) {
|
||||
ret = fc0012_writereg(priv, i, reg[i]);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* VCO Calibration */
|
||||
ret = fc0012_writereg(priv, 0x0e, 0x80);
|
||||
if (!ret)
|
||||
ret = fc0012_writereg(priv, 0x0e, 0x00);
|
||||
|
||||
/* VCO Re-Calibration if needed */
|
||||
if (!ret)
|
||||
ret = fc0012_writereg(priv, 0x0e, 0x00);
|
||||
|
||||
if (!ret) {
|
||||
msleep(10);
|
||||
ret = fc0012_readreg(priv, 0x0e, &tmp);
|
||||
}
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* vco selection */
|
||||
tmp &= 0x3f;
|
||||
|
||||
if (vco_select) {
|
||||
if (tmp > 0x3c) {
|
||||
reg[6] &= ~0x08;
|
||||
ret = fc0012_writereg(priv, 0x06, reg[6]);
|
||||
if (!ret)
|
||||
ret = fc0012_writereg(priv, 0x0e, 0x80);
|
||||
if (!ret)
|
||||
ret = fc0012_writereg(priv, 0x0e, 0x00);
|
||||
}
|
||||
} else {
|
||||
if (tmp < 0x02) {
|
||||
reg[6] |= 0x08;
|
||||
ret = fc0012_writereg(priv, 0x06, reg[6]);
|
||||
if (!ret)
|
||||
ret = fc0012_writereg(priv, 0x0e, 0x80);
|
||||
if (!ret)
|
||||
ret = fc0012_writereg(priv, 0x0e, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
priv->frequency = p->frequency;
|
||||
priv->bandwidth = p->bandwidth_hz;
|
||||
|
||||
exit:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
if (ret)
|
||||
warn("%s: failed: %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fc0012_get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
struct fc0012_priv *priv = fe->tuner_priv;
|
||||
*frequency = priv->frequency;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0012_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
/* CHECK: always ? */
|
||||
*frequency = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0012_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
|
||||
{
|
||||
struct fc0012_priv *priv = fe->tuner_priv;
|
||||
*bandwidth = priv->bandwidth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define INPUT_ADC_LEVEL -8
|
||||
|
||||
static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
struct fc0012_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
unsigned char tmp;
|
||||
int int_temp, lna_gain, int_lna, tot_agc_gain, power;
|
||||
const int fc0012_lna_gain_table[] = {
|
||||
/* low gain */
|
||||
-63, -58, -99, -73,
|
||||
-63, -65, -54, -60,
|
||||
/* middle gain */
|
||||
71, 70, 68, 67,
|
||||
65, 63, 61, 58,
|
||||
/* high gain */
|
||||
197, 191, 188, 186,
|
||||
184, 182, 181, 179,
|
||||
};
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
ret = fc0012_writereg(priv, 0x12, 0x00);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = fc0012_readreg(priv, 0x12, &tmp);
|
||||
if (ret)
|
||||
goto err;
|
||||
int_temp = tmp;
|
||||
|
||||
ret = fc0012_readreg(priv, 0x13, &tmp);
|
||||
if (ret)
|
||||
goto err;
|
||||
lna_gain = tmp & 0x1f;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
if (lna_gain < ARRAY_SIZE(fc0012_lna_gain_table)) {
|
||||
int_lna = fc0012_lna_gain_table[lna_gain];
|
||||
tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
|
||||
(int_temp & 0x1f)) * 2;
|
||||
power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
|
||||
|
||||
if (power >= 45)
|
||||
*strength = 255; /* 100% */
|
||||
else if (power < -95)
|
||||
*strength = 0;
|
||||
else
|
||||
*strength = (power + 95) * 255 / 140;
|
||||
|
||||
*strength |= *strength << 8;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
goto exit;
|
||||
|
||||
err:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
exit:
|
||||
if (ret)
|
||||
warn("%s: failed: %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dvb_tuner_ops fc0012_tuner_ops = {
|
||||
.info = {
|
||||
.name = "Fitipower FC0012",
|
||||
|
||||
.frequency_min = 37000000, /* estimate */
|
||||
.frequency_max = 862000000, /* estimate */
|
||||
.frequency_step = 0,
|
||||
},
|
||||
|
||||
.release = fc0012_release,
|
||||
|
||||
.init = fc0012_init,
|
||||
.sleep = fc0012_sleep,
|
||||
|
||||
.set_params = fc0012_set_params,
|
||||
|
||||
.get_frequency = fc0012_get_frequency,
|
||||
.get_if_frequency = fc0012_get_if_frequency,
|
||||
.get_bandwidth = fc0012_get_bandwidth,
|
||||
|
||||
.get_rf_strength = fc0012_get_rf_strength,
|
||||
};
|
||||
|
||||
struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
|
||||
enum fc001x_xtal_freq xtal_freq)
|
||||
{
|
||||
struct fc0012_priv *priv = NULL;
|
||||
|
||||
priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
return NULL;
|
||||
|
||||
priv->i2c = i2c;
|
||||
priv->dual_master = dual_master;
|
||||
priv->addr = i2c_address;
|
||||
priv->xtal_freq = xtal_freq;
|
||||
|
||||
info("Fitipower FC0012 successfully attached.");
|
||||
|
||||
fe->tuner_priv = priv;
|
||||
|
||||
memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops,
|
||||
sizeof(struct dvb_tuner_ops));
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(fc0012_attach);
|
||||
|
||||
MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver");
|
||||
MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.6");
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Fitipower FC0012 tuner driver - include
|
||||
*
|
||||
* Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _FC0012_H_
|
||||
#define _FC0012_H_
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "fc001x-common.h"
|
||||
|
||||
#if defined(CONFIG_MEDIA_TUNER_FC0012) || \
|
||||
(defined(CONFIG_MEDIA_TUNER_FC0012_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
u8 i2c_address, int dual_master,
|
||||
enum fc001x_xtal_freq xtal_freq);
|
||||
#else
|
||||
static inline struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
u8 i2c_address, int dual_master,
|
||||
enum fc001x_xtal_freq xtal_freq)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Fitipower FC0013 tuner driver
|
||||
*
|
||||
* Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FC0013_PRIV_H_
|
||||
#define _FC0013_PRIV_H_
|
||||
|
||||
#define LOG_PREFIX "fc0013"
|
||||
|
||||
#undef err
|
||||
#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef info
|
||||
#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef warn
|
||||
#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
|
||||
|
||||
struct fc0013_priv {
|
||||
struct i2c_adapter *i2c;
|
||||
u8 addr;
|
||||
u8 dual_master;
|
||||
u8 xtal_freq;
|
||||
|
||||
u32 frequency;
|
||||
u32 bandwidth;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,634 @@
|
|||
/*
|
||||
* Fitipower FC0013 tuner driver
|
||||
*
|
||||
* Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
|
||||
* partially based on driver code from Fitipower
|
||||
* Copyright (C) 2010 Fitipower Integrated Technology Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fc0013.h"
|
||||
#include "fc0013-priv.h"
|
||||
|
||||
static int fc0013_writereg(struct fc0013_priv *priv, u8 reg, u8 val)
|
||||
{
|
||||
u8 buf[2] = {reg, val};
|
||||
struct i2c_msg msg = {
|
||||
.addr = priv->addr, .flags = 0, .buf = buf, .len = 2
|
||||
};
|
||||
|
||||
if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
|
||||
err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val)
|
||||
{
|
||||
struct i2c_msg msg[2] = {
|
||||
{ .addr = priv->addr, .flags = 0, .buf = ®, .len = 1 },
|
||||
{ .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
|
||||
};
|
||||
|
||||
if (i2c_transfer(priv->i2c, msg, 2) != 2) {
|
||||
err("I2C read reg failed, reg: %02x", reg);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0013_release(struct dvb_frontend *fe)
|
||||
{
|
||||
kfree(fe->tuner_priv);
|
||||
fe->tuner_priv = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0013_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct fc0013_priv *priv = fe->tuner_priv;
|
||||
int i, ret = 0;
|
||||
unsigned char reg[] = {
|
||||
0x00, /* reg. 0x00: dummy */
|
||||
0x09, /* reg. 0x01 */
|
||||
0x16, /* reg. 0x02 */
|
||||
0x00, /* reg. 0x03 */
|
||||
0x00, /* reg. 0x04 */
|
||||
0x17, /* reg. 0x05 */
|
||||
0x02, /* reg. 0x06 */
|
||||
0x0a, /* reg. 0x07: CHECK */
|
||||
0xff, /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
|
||||
Loop Bw 1/8 */
|
||||
0x6f, /* reg. 0x09: enable LoopThrough */
|
||||
0xb8, /* reg. 0x0a: Disable LO Test Buffer */
|
||||
0x82, /* reg. 0x0b: CHECK */
|
||||
0xfc, /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
|
||||
0x01, /* reg. 0x0d: AGC Not Forcing & LNA Forcing, may need 0x02 */
|
||||
0x00, /* reg. 0x0e */
|
||||
0x00, /* reg. 0x0f */
|
||||
0x00, /* reg. 0x10 */
|
||||
0x00, /* reg. 0x11 */
|
||||
0x00, /* reg. 0x12 */
|
||||
0x00, /* reg. 0x13 */
|
||||
0x50, /* reg. 0x14: DVB-t High Gain, UHF.
|
||||
Middle Gain: 0x48, Low Gain: 0x40 */
|
||||
0x01, /* reg. 0x15 */
|
||||
};
|
||||
|
||||
switch (priv->xtal_freq) {
|
||||
case FC_XTAL_27_MHZ:
|
||||
case FC_XTAL_28_8_MHZ:
|
||||
reg[0x07] |= 0x20;
|
||||
break;
|
||||
case FC_XTAL_36_MHZ:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (priv->dual_master)
|
||||
reg[0x0c] |= 0x02;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
for (i = 1; i < sizeof(reg); i++) {
|
||||
ret = fc0013_writereg(priv, i, reg[i]);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
if (ret)
|
||||
err("fc0013_writereg failed: %d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fc0013_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
/* nothing to do here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
|
||||
{
|
||||
struct fc0013_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
u8 rc_cal;
|
||||
int val;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
/* push rc_cal value, get rc_cal value */
|
||||
ret = fc0013_writereg(priv, 0x10, 0x00);
|
||||
if (ret)
|
||||
goto error_out;
|
||||
|
||||
/* get rc_cal value */
|
||||
ret = fc0013_readreg(priv, 0x10, &rc_cal);
|
||||
if (ret)
|
||||
goto error_out;
|
||||
|
||||
rc_cal &= 0x0f;
|
||||
|
||||
val = (int)rc_cal + rc_val;
|
||||
|
||||
/* forcing rc_cal */
|
||||
ret = fc0013_writereg(priv, 0x0d, 0x11);
|
||||
if (ret)
|
||||
goto error_out;
|
||||
|
||||
/* modify rc_cal value */
|
||||
if (val > 15)
|
||||
ret = fc0013_writereg(priv, 0x10, 0x0f);
|
||||
else if (val < 0)
|
||||
ret = fc0013_writereg(priv, 0x10, 0x00);
|
||||
else
|
||||
ret = fc0013_writereg(priv, 0x10, (u8)val);
|
||||
|
||||
error_out:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(fc0013_rc_cal_add);
|
||||
|
||||
int fc0013_rc_cal_reset(struct dvb_frontend *fe)
|
||||
{
|
||||
struct fc0013_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
ret = fc0013_writereg(priv, 0x0d, 0x01);
|
||||
if (!ret)
|
||||
ret = fc0013_writereg(priv, 0x10, 0x00);
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(fc0013_rc_cal_reset);
|
||||
|
||||
static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq)
|
||||
{
|
||||
int ret;
|
||||
u8 tmp;
|
||||
|
||||
ret = fc0013_readreg(priv, 0x1d, &tmp);
|
||||
if (ret)
|
||||
goto error_out;
|
||||
tmp &= 0xe3;
|
||||
if (freq <= 177500) { /* VHF Track: 7 */
|
||||
ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
|
||||
} else if (freq <= 184500) { /* VHF Track: 6 */
|
||||
ret = fc0013_writereg(priv, 0x1d, tmp | 0x18);
|
||||
} else if (freq <= 191500) { /* VHF Track: 5 */
|
||||
ret = fc0013_writereg(priv, 0x1d, tmp | 0x14);
|
||||
} else if (freq <= 198500) { /* VHF Track: 4 */
|
||||
ret = fc0013_writereg(priv, 0x1d, tmp | 0x10);
|
||||
} else if (freq <= 205500) { /* VHF Track: 3 */
|
||||
ret = fc0013_writereg(priv, 0x1d, tmp | 0x0c);
|
||||
} else if (freq <= 219500) { /* VHF Track: 2 */
|
||||
ret = fc0013_writereg(priv, 0x1d, tmp | 0x08);
|
||||
} else if (freq < 300000) { /* VHF Track: 1 */
|
||||
ret = fc0013_writereg(priv, 0x1d, tmp | 0x04);
|
||||
} else { /* UHF and GPS */
|
||||
ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
|
||||
}
|
||||
if (ret)
|
||||
goto error_out;
|
||||
error_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fc0013_set_params(struct dvb_frontend *fe)
|
||||
{
|
||||
struct fc0013_priv *priv = fe->tuner_priv;
|
||||
int i, ret = 0;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 freq = p->frequency / 1000;
|
||||
u32 delsys = p->delivery_system;
|
||||
unsigned char reg[7], am, pm, multi, tmp;
|
||||
unsigned long f_vco;
|
||||
unsigned short xtal_freq_khz_2, xin, xdiv;
|
||||
int vco_select = false;
|
||||
|
||||
if (fe->callback) {
|
||||
ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
|
||||
FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (priv->xtal_freq) {
|
||||
case FC_XTAL_27_MHZ:
|
||||
xtal_freq_khz_2 = 27000 / 2;
|
||||
break;
|
||||
case FC_XTAL_36_MHZ:
|
||||
xtal_freq_khz_2 = 36000 / 2;
|
||||
break;
|
||||
case FC_XTAL_28_8_MHZ:
|
||||
default:
|
||||
xtal_freq_khz_2 = 28800 / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
/* set VHF track */
|
||||
ret = fc0013_set_vhf_track(priv, freq);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
if (freq < 300000) {
|
||||
/* enable VHF filter */
|
||||
ret = fc0013_readreg(priv, 0x07, &tmp);
|
||||
if (ret)
|
||||
goto exit;
|
||||
ret = fc0013_writereg(priv, 0x07, tmp | 0x10);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* disable UHF & disable GPS */
|
||||
ret = fc0013_readreg(priv, 0x14, &tmp);
|
||||
if (ret)
|
||||
goto exit;
|
||||
ret = fc0013_writereg(priv, 0x14, tmp & 0x1f);
|
||||
if (ret)
|
||||
goto exit;
|
||||
} else if (freq <= 862000) {
|
||||
/* disable VHF filter */
|
||||
ret = fc0013_readreg(priv, 0x07, &tmp);
|
||||
if (ret)
|
||||
goto exit;
|
||||
ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* enable UHF & disable GPS */
|
||||
ret = fc0013_readreg(priv, 0x14, &tmp);
|
||||
if (ret)
|
||||
goto exit;
|
||||
ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x40);
|
||||
if (ret)
|
||||
goto exit;
|
||||
} else {
|
||||
/* disable VHF filter */
|
||||
ret = fc0013_readreg(priv, 0x07, &tmp);
|
||||
if (ret)
|
||||
goto exit;
|
||||
ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* disable UHF & enable GPS */
|
||||
ret = fc0013_readreg(priv, 0x14, &tmp);
|
||||
if (ret)
|
||||
goto exit;
|
||||
ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x20);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* select frequency divider and the frequency of VCO */
|
||||
if (freq < 37084) { /* freq * 96 < 3560000 */
|
||||
multi = 96;
|
||||
reg[5] = 0x82;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 55625) { /* freq * 64 < 3560000 */
|
||||
multi = 64;
|
||||
reg[5] = 0x02;
|
||||
reg[6] = 0x02;
|
||||
} else if (freq < 74167) { /* freq * 48 < 3560000 */
|
||||
multi = 48;
|
||||
reg[5] = 0x42;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 111250) { /* freq * 32 < 3560000 */
|
||||
multi = 32;
|
||||
reg[5] = 0x82;
|
||||
reg[6] = 0x02;
|
||||
} else if (freq < 148334) { /* freq * 24 < 3560000 */
|
||||
multi = 24;
|
||||
reg[5] = 0x22;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 222500) { /* freq * 16 < 3560000 */
|
||||
multi = 16;
|
||||
reg[5] = 0x42;
|
||||
reg[6] = 0x02;
|
||||
} else if (freq < 296667) { /* freq * 12 < 3560000 */
|
||||
multi = 12;
|
||||
reg[5] = 0x12;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 445000) { /* freq * 8 < 3560000 */
|
||||
multi = 8;
|
||||
reg[5] = 0x22;
|
||||
reg[6] = 0x02;
|
||||
} else if (freq < 593334) { /* freq * 6 < 3560000 */
|
||||
multi = 6;
|
||||
reg[5] = 0x0a;
|
||||
reg[6] = 0x00;
|
||||
} else if (freq < 950000) { /* freq * 4 < 3800000 */
|
||||
multi = 4;
|
||||
reg[5] = 0x12;
|
||||
reg[6] = 0x02;
|
||||
} else {
|
||||
multi = 2;
|
||||
reg[5] = 0x0a;
|
||||
reg[6] = 0x02;
|
||||
}
|
||||
|
||||
f_vco = freq * multi;
|
||||
|
||||
if (f_vco >= 3060000) {
|
||||
reg[6] |= 0x08;
|
||||
vco_select = true;
|
||||
}
|
||||
|
||||
if (freq >= 45000) {
|
||||
/* From divided value (XDIV) determined the FA and FP value */
|
||||
xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
|
||||
if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
|
||||
xdiv++;
|
||||
|
||||
pm = (unsigned char)(xdiv / 8);
|
||||
am = (unsigned char)(xdiv - (8 * pm));
|
||||
|
||||
if (am < 2) {
|
||||
reg[1] = am + 8;
|
||||
reg[2] = pm - 1;
|
||||
} else {
|
||||
reg[1] = am;
|
||||
reg[2] = pm;
|
||||
}
|
||||
} else {
|
||||
/* fix for frequency less than 45 MHz */
|
||||
reg[1] = 0x06;
|
||||
reg[2] = 0x11;
|
||||
}
|
||||
|
||||
/* fix clock out */
|
||||
reg[6] |= 0x20;
|
||||
|
||||
/* From VCO frequency determines the XIN ( fractional part of Delta
|
||||
Sigma PLL) and divided value (XDIV) */
|
||||
xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
|
||||
xin = (xin << 15) / xtal_freq_khz_2;
|
||||
if (xin >= 16384)
|
||||
xin += 32768;
|
||||
|
||||
reg[3] = xin >> 8;
|
||||
reg[4] = xin & 0xff;
|
||||
|
||||
if (delsys == SYS_DVBT) {
|
||||
reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
|
||||
switch (p->bandwidth_hz) {
|
||||
case 6000000:
|
||||
reg[6] |= 0x80;
|
||||
break;
|
||||
case 7000000:
|
||||
reg[6] |= 0x40;
|
||||
break;
|
||||
case 8000000:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
err("%s: modulation type not supported!", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* modified for Realtek demod */
|
||||
reg[5] |= 0x07;
|
||||
|
||||
for (i = 1; i <= 6; i++) {
|
||||
ret = fc0013_writereg(priv, i, reg[i]);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = fc0013_readreg(priv, 0x11, &tmp);
|
||||
if (ret)
|
||||
goto exit;
|
||||
if (multi == 64)
|
||||
ret = fc0013_writereg(priv, 0x11, tmp | 0x04);
|
||||
else
|
||||
ret = fc0013_writereg(priv, 0x11, tmp & 0xfb);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* VCO Calibration */
|
||||
ret = fc0013_writereg(priv, 0x0e, 0x80);
|
||||
if (!ret)
|
||||
ret = fc0013_writereg(priv, 0x0e, 0x00);
|
||||
|
||||
/* VCO Re-Calibration if needed */
|
||||
if (!ret)
|
||||
ret = fc0013_writereg(priv, 0x0e, 0x00);
|
||||
|
||||
if (!ret) {
|
||||
msleep(10);
|
||||
ret = fc0013_readreg(priv, 0x0e, &tmp);
|
||||
}
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* vco selection */
|
||||
tmp &= 0x3f;
|
||||
|
||||
if (vco_select) {
|
||||
if (tmp > 0x3c) {
|
||||
reg[6] &= ~0x08;
|
||||
ret = fc0013_writereg(priv, 0x06, reg[6]);
|
||||
if (!ret)
|
||||
ret = fc0013_writereg(priv, 0x0e, 0x80);
|
||||
if (!ret)
|
||||
ret = fc0013_writereg(priv, 0x0e, 0x00);
|
||||
}
|
||||
} else {
|
||||
if (tmp < 0x02) {
|
||||
reg[6] |= 0x08;
|
||||
ret = fc0013_writereg(priv, 0x06, reg[6]);
|
||||
if (!ret)
|
||||
ret = fc0013_writereg(priv, 0x0e, 0x80);
|
||||
if (!ret)
|
||||
ret = fc0013_writereg(priv, 0x0e, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
priv->frequency = p->frequency;
|
||||
priv->bandwidth = p->bandwidth_hz;
|
||||
|
||||
exit:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
if (ret)
|
||||
warn("%s: failed: %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fc0013_get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
struct fc0013_priv *priv = fe->tuner_priv;
|
||||
*frequency = priv->frequency;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0013_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
/* always ? */
|
||||
*frequency = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fc0013_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
|
||||
{
|
||||
struct fc0013_priv *priv = fe->tuner_priv;
|
||||
*bandwidth = priv->bandwidth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define INPUT_ADC_LEVEL -8
|
||||
|
||||
static int fc0013_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
struct fc0013_priv *priv = fe->tuner_priv;
|
||||
int ret;
|
||||
unsigned char tmp;
|
||||
int int_temp, lna_gain, int_lna, tot_agc_gain, power;
|
||||
const int fc0013_lna_gain_table[] = {
|
||||
/* low gain */
|
||||
-63, -58, -99, -73,
|
||||
-63, -65, -54, -60,
|
||||
/* middle gain */
|
||||
71, 70, 68, 67,
|
||||
65, 63, 61, 58,
|
||||
/* high gain */
|
||||
197, 191, 188, 186,
|
||||
184, 182, 181, 179,
|
||||
};
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
|
||||
|
||||
ret = fc0013_writereg(priv, 0x13, 0x00);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = fc0013_readreg(priv, 0x13, &tmp);
|
||||
if (ret)
|
||||
goto err;
|
||||
int_temp = tmp;
|
||||
|
||||
ret = fc0013_readreg(priv, 0x14, &tmp);
|
||||
if (ret)
|
||||
goto err;
|
||||
lna_gain = tmp & 0x1f;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
|
||||
if (lna_gain < ARRAY_SIZE(fc0013_lna_gain_table)) {
|
||||
int_lna = fc0013_lna_gain_table[lna_gain];
|
||||
tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
|
||||
(int_temp & 0x1f)) * 2;
|
||||
power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
|
||||
|
||||
if (power >= 45)
|
||||
*strength = 255; /* 100% */
|
||||
else if (power < -95)
|
||||
*strength = 0;
|
||||
else
|
||||
*strength = (power + 95) * 255 / 140;
|
||||
|
||||
*strength |= *strength << 8;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
goto exit;
|
||||
|
||||
err:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
|
||||
exit:
|
||||
if (ret)
|
||||
warn("%s: failed: %d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dvb_tuner_ops fc0013_tuner_ops = {
|
||||
.info = {
|
||||
.name = "Fitipower FC0013",
|
||||
|
||||
.frequency_min = 37000000, /* estimate */
|
||||
.frequency_max = 1680000000, /* CHECK */
|
||||
.frequency_step = 0,
|
||||
},
|
||||
|
||||
.release = fc0013_release,
|
||||
|
||||
.init = fc0013_init,
|
||||
.sleep = fc0013_sleep,
|
||||
|
||||
.set_params = fc0013_set_params,
|
||||
|
||||
.get_frequency = fc0013_get_frequency,
|
||||
.get_if_frequency = fc0013_get_if_frequency,
|
||||
.get_bandwidth = fc0013_get_bandwidth,
|
||||
|
||||
.get_rf_strength = fc0013_get_rf_strength,
|
||||
};
|
||||
|
||||
struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
|
||||
enum fc001x_xtal_freq xtal_freq)
|
||||
{
|
||||
struct fc0013_priv *priv = NULL;
|
||||
|
||||
priv = kzalloc(sizeof(struct fc0013_priv), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
return NULL;
|
||||
|
||||
priv->i2c = i2c;
|
||||
priv->dual_master = dual_master;
|
||||
priv->addr = i2c_address;
|
||||
priv->xtal_freq = xtal_freq;
|
||||
|
||||
info("Fitipower FC0013 successfully attached.");
|
||||
|
||||
fe->tuner_priv = priv;
|
||||
|
||||
memcpy(&fe->ops.tuner_ops, &fc0013_tuner_ops,
|
||||
sizeof(struct dvb_tuner_ops));
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(fc0013_attach);
|
||||
|
||||
MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver");
|
||||
MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.2");
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Fitipower FC0013 tuner driver
|
||||
*
|
||||
* Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FC0013_H_
|
||||
#define _FC0013_H_
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "fc001x-common.h"
|
||||
|
||||
#if defined(CONFIG_MEDIA_TUNER_FC0013) || \
|
||||
(defined(CONFIG_MEDIA_TUNER_FC0013_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
u8 i2c_address, int dual_master,
|
||||
enum fc001x_xtal_freq xtal_freq);
|
||||
extern int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val);
|
||||
extern int fc0013_rc_cal_reset(struct dvb_frontend *fe);
|
||||
#else
|
||||
static inline struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
u8 i2c_address, int dual_master,
|
||||
enum fc001x_xtal_freq xtal_freq)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fc0013_rc_cal_reset(struct dvb_frontend *fe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Fitipower FC0012 & FC0013 tuner driver - common defines
|
||||
*
|
||||
* Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _FC001X_COMMON_H_
|
||||
#define _FC001X_COMMON_H_
|
||||
|
||||
enum fc001x_xtal_freq {
|
||||
FC_XTAL_27_MHZ, /* 27000000 */
|
||||
FC_XTAL_28_8_MHZ, /* 28800000 */
|
||||
FC_XTAL_36_MHZ, /* 36000000 */
|
||||
};
|
||||
|
||||
/*
|
||||
* enum fc001x_fe_callback_commands - Frontend callbacks
|
||||
*
|
||||
* @FC_FE_CALLBACK_VHF_ENABLE: enable VHF or UHF
|
||||
*/
|
||||
enum fc001x_fe_callback_commands {
|
||||
FC_FE_CALLBACK_VHF_ENABLE,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* Infineon TUA 9001 silicon tuner driver
|
||||
*
|
||||
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "tua9001.h"
|
||||
#include "tua9001_priv.h"
|
||||
|
||||
/* write register */
|
||||
static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff };
|
||||
struct i2c_msg msg[1] = {
|
||||
{
|
||||
.addr = priv->cfg->i2c_addr,
|
||||
.flags = 0,
|
||||
.len = sizeof(buf),
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(priv->i2c, msg, 1);
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: I2C wr failed=%d reg=%02x\n",
|
||||
__func__, ret, reg);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tua9001_release(struct dvb_frontend *fe)
|
||||
{
|
||||
kfree(fe->tuner_priv);
|
||||
fe->tuner_priv = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tua9001_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tua9001_priv *priv = fe->tuner_priv;
|
||||
int ret = 0;
|
||||
u8 i;
|
||||
struct reg_val data[] = {
|
||||
{ 0x1e, 0x6512 },
|
||||
{ 0x25, 0xb888 },
|
||||
{ 0x39, 0x5460 },
|
||||
{ 0x3b, 0x00c0 },
|
||||
{ 0x3a, 0xf000 },
|
||||
{ 0x08, 0x0000 },
|
||||
{ 0x32, 0x0030 },
|
||||
{ 0x41, 0x703a },
|
||||
{ 0x40, 0x1c78 },
|
||||
{ 0x2c, 0x1c00 },
|
||||
{ 0x36, 0xc013 },
|
||||
{ 0x37, 0x6f18 },
|
||||
{ 0x27, 0x0008 },
|
||||
{ 0x2a, 0x0001 },
|
||||
{ 0x34, 0x0a40 },
|
||||
};
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
|
||||
|
||||
if (ret < 0)
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tua9001_set_params(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tua9001_priv *priv = fe->tuner_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int ret, i;
|
||||
u16 val;
|
||||
u32 frequency;
|
||||
struct reg_val data[2];
|
||||
|
||||
pr_debug("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
|
||||
__func__, c->delivery_system, c->frequency,
|
||||
c->bandwidth_hz);
|
||||
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DVBT:
|
||||
switch (c->bandwidth_hz) {
|
||||
case 8000000:
|
||||
val = 0x0000;
|
||||
break;
|
||||
case 7000000:
|
||||
val = 0x1000;
|
||||
break;
|
||||
case 6000000:
|
||||
val = 0x2000;
|
||||
break;
|
||||
case 5000000:
|
||||
val = 0x3000;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
data[0].reg = 0x04;
|
||||
data[0].val = val;
|
||||
|
||||
frequency = (c->frequency - 150000000);
|
||||
frequency /= 100;
|
||||
frequency *= 48;
|
||||
frequency /= 10000;
|
||||
|
||||
data[1].reg = 0x1f;
|
||||
data[1].val = frequency;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
|
||||
|
||||
err:
|
||||
if (ret < 0)
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
*frequency = 0; /* Zero-IF */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dvb_tuner_ops tua9001_tuner_ops = {
|
||||
.info = {
|
||||
.name = "Infineon TUA 9001",
|
||||
|
||||
.frequency_min = 170000000,
|
||||
.frequency_max = 862000000,
|
||||
.frequency_step = 0,
|
||||
},
|
||||
|
||||
.release = tua9001_release,
|
||||
|
||||
.init = tua9001_init,
|
||||
.set_params = tua9001_set_params,
|
||||
|
||||
.get_if_frequency = tua9001_get_if_frequency,
|
||||
};
|
||||
|
||||
struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, struct tua9001_config *cfg)
|
||||
{
|
||||
struct tua9001_priv *priv = NULL;
|
||||
|
||||
priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
return NULL;
|
||||
|
||||
priv->cfg = cfg;
|
||||
priv->i2c = i2c;
|
||||
|
||||
printk(KERN_INFO "Infineon TUA 9001 successfully attached.");
|
||||
|
||||
memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
|
||||
sizeof(struct dvb_tuner_ops));
|
||||
|
||||
fe->tuner_priv = priv;
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(tua9001_attach);
|
||||
|
||||
MODULE_DESCRIPTION("Infineon TUA 9001 silicon tuner driver");
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Infineon TUA 9001 silicon tuner driver
|
||||
*
|
||||
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef TUA9001_H
|
||||
#define TUA9001_H
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
struct tua9001_config {
|
||||
/*
|
||||
* I2C address
|
||||
*/
|
||||
u8 i2c_addr;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_MEDIA_TUNER_TUA9001) || \
|
||||
(defined(CONFIG_MEDIA_TUNER_TUA9001_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, struct tua9001_config *cfg);
|
||||
#else
|
||||
static inline struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, struct tua9001_config *cfg)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Infineon TUA 9001 silicon tuner driver
|
||||
*
|
||||
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef TUA9001_PRIV_H
|
||||
#define TUA9001_PRIV_H
|
||||
|
||||
struct reg_val {
|
||||
u8 reg;
|
||||
u16 val;
|
||||
};
|
||||
|
||||
struct tua9001_priv {
|
||||
struct tua9001_config *cfg;
|
||||
struct i2c_adapter *i2c;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -54,7 +54,7 @@ struct xc5000_priv {
|
|||
struct list_head hybrid_tuner_instance_list;
|
||||
|
||||
u32 if_khz;
|
||||
u32 xtal_khz;
|
||||
u16 xtal_khz;
|
||||
u32 freq_hz;
|
||||
u32 bandwidth;
|
||||
u8 video_standard;
|
||||
|
@ -631,7 +631,10 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
|
|||
ret = xc_load_i2c_sequence(fe, fw->data);
|
||||
if (XC_RESULT_SUCCESS == ret)
|
||||
ret = xc_set_xtal(fe);
|
||||
printk(KERN_INFO "xc5000: firmware upload complete...\n");
|
||||
if (XC_RESULT_SUCCESS == ret)
|
||||
printk(KERN_INFO "xc5000: firmware upload complete...\n");
|
||||
else
|
||||
printk(KERN_ERR "xc5000: firmware upload failed...\n");
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
@ -34,7 +34,7 @@ struct xc5000_config {
|
|||
u8 i2c_address;
|
||||
u32 if_khz;
|
||||
u8 radio_input;
|
||||
u32 xtal_khz;
|
||||
u16 xtal_khz;
|
||||
|
||||
int chip_id;
|
||||
};
|
||||
|
|
|
@ -477,7 +477,6 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
|
|||
static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int ca_message_header_len;
|
||||
|
||||
u32 command = 0;
|
||||
struct ca_msg *hw_buffer;
|
||||
|
@ -496,7 +495,6 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
|
|||
|
||||
|
||||
if (p_ca_message->msg) {
|
||||
ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
|
||||
/* EN50221 tag */
|
||||
command = 0;
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/swab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
@ -1696,7 +1695,7 @@ static struct pci_driver ddb_pci_driver = {
|
|||
.name = "DDBridge",
|
||||
.id_table = ddb_id_tbl,
|
||||
.probe = ddb_probe,
|
||||
.remove = ddb_remove,
|
||||
.remove = __devexit_p(ddb_remove),
|
||||
};
|
||||
|
||||
static __init int module_init_ddbridge(void)
|
||||
|
|
|
@ -568,6 +568,16 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
|
|||
}
|
||||
EXPORT_SYMBOL(dvb_dmx_swfilter_204);
|
||||
|
||||
void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count)
|
||||
{
|
||||
spin_lock(&demux->lock);
|
||||
|
||||
demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, DMX_OK);
|
||||
|
||||
spin_unlock(&demux->lock);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_dmx_swfilter_raw);
|
||||
|
||||
static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -145,5 +145,7 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
|
|||
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
|
||||
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
|
||||
size_t count);
|
||||
void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf,
|
||||
size_t count);
|
||||
|
||||
#endif /* _DVB_DEMUX_H_ */
|
||||
|
|
|
@ -182,13 +182,13 @@ static enum dvbv3_emulation_type dvbv3_type(u32 delivery_system)
|
|||
case SYS_DMBTH:
|
||||
return DVBV3_OFDM;
|
||||
case SYS_ATSC:
|
||||
case SYS_ATSCMH:
|
||||
case SYS_DVBC_ANNEX_B:
|
||||
return DVBV3_ATSC;
|
||||
case SYS_UNDEFINED:
|
||||
case SYS_ISDBC:
|
||||
case SYS_DVBH:
|
||||
case SYS_DAB:
|
||||
case SYS_ATSCMH:
|
||||
default:
|
||||
/*
|
||||
* Doesn't know how to emulate those types and/or
|
||||
|
@ -1030,6 +1030,25 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
|
|||
_DTV_CMD(DTV_HIERARCHY, 0, 0),
|
||||
|
||||
_DTV_CMD(DTV_ENUM_DELSYS, 0, 0),
|
||||
|
||||
_DTV_CMD(DTV_ATSCMH_PARADE_ID, 1, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 1, 0),
|
||||
|
||||
_DTV_CMD(DTV_ATSCMH_FIC_VER, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_PARADE_ID, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_NOG, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_TNOG, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_SGN, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_PRC, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0),
|
||||
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0),
|
||||
};
|
||||
|
||||
static void dtv_property_dump(struct dtv_property *tvp)
|
||||
|
@ -1121,6 +1140,8 @@ static int dtv_property_cache_sync(struct dvb_frontend *fe,
|
|||
case DVBV3_ATSC:
|
||||
dprintk("%s() Preparing ATSC req\n", __func__);
|
||||
c->modulation = p->u.vsb.modulation;
|
||||
if (c->delivery_system == SYS_ATSCMH)
|
||||
break;
|
||||
if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
|
||||
c->delivery_system = SYS_ATSC;
|
||||
else
|
||||
|
@ -1367,6 +1388,54 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
|
|||
case DTV_DVBT2_PLP_ID:
|
||||
tvp->u.data = c->dvbt2_plp_id;
|
||||
break;
|
||||
|
||||
/* ATSC-MH */
|
||||
case DTV_ATSCMH_FIC_VER:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_fic_ver;
|
||||
break;
|
||||
case DTV_ATSCMH_PARADE_ID:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_parade_id;
|
||||
break;
|
||||
case DTV_ATSCMH_NOG:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_nog;
|
||||
break;
|
||||
case DTV_ATSCMH_TNOG:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_tnog;
|
||||
break;
|
||||
case DTV_ATSCMH_SGN:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_sgn;
|
||||
break;
|
||||
case DTV_ATSCMH_PRC:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_prc;
|
||||
break;
|
||||
case DTV_ATSCMH_RS_FRAME_MODE:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_rs_frame_mode;
|
||||
break;
|
||||
case DTV_ATSCMH_RS_FRAME_ENSEMBLE:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_rs_frame_ensemble;
|
||||
break;
|
||||
case DTV_ATSCMH_RS_CODE_MODE_PRI:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_rs_code_mode_pri;
|
||||
break;
|
||||
case DTV_ATSCMH_RS_CODE_MODE_SEC:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_rs_code_mode_sec;
|
||||
break;
|
||||
case DTV_ATSCMH_SCCC_BLOCK_MODE:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_sccc_block_mode;
|
||||
break;
|
||||
case DTV_ATSCMH_SCCC_CODE_MODE_A:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_a;
|
||||
break;
|
||||
case DTV_ATSCMH_SCCC_CODE_MODE_B:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_b;
|
||||
break;
|
||||
case DTV_ATSCMH_SCCC_CODE_MODE_C:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_c;
|
||||
break;
|
||||
case DTV_ATSCMH_SCCC_CODE_MODE_D:
|
||||
tvp->u.data = fe->dtv_property_cache.atscmh_sccc_code_mode_d;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1708,6 +1777,15 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
|
|||
case DTV_DVBT2_PLP_ID:
|
||||
c->dvbt2_plp_id = tvp->u.data;
|
||||
break;
|
||||
|
||||
/* ATSC-MH */
|
||||
case DTV_ATSCMH_PARADE_ID:
|
||||
fe->dtv_property_cache.atscmh_parade_id = tvp->u.data;
|
||||
break;
|
||||
case DTV_ATSCMH_RS_FRAME_ENSEMBLE:
|
||||
fe->dtv_property_cache.atscmh_rs_frame_ensemble = tvp->u.data;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -372,6 +372,24 @@ struct dtv_frontend_properties {
|
|||
|
||||
/* DVB-T2 specifics */
|
||||
u32 dvbt2_plp_id;
|
||||
|
||||
/* ATSC-MH specifics */
|
||||
u8 atscmh_fic_ver;
|
||||
u8 atscmh_parade_id;
|
||||
u8 atscmh_nog;
|
||||
u8 atscmh_tnog;
|
||||
u8 atscmh_sgn;
|
||||
u8 atscmh_prc;
|
||||
|
||||
u8 atscmh_rs_frame_mode;
|
||||
u8 atscmh_rs_frame_ensemble;
|
||||
u8 atscmh_rs_code_mode_pri;
|
||||
u8 atscmh_rs_code_mode_sec;
|
||||
u8 atscmh_sccc_block_mode;
|
||||
u8 atscmh_sccc_code_mode_a;
|
||||
u8 atscmh_sccc_code_mode_b;
|
||||
u8 atscmh_sccc_code_mode_c;
|
||||
u8 atscmh_sccc_code_mode_d;
|
||||
};
|
||||
|
||||
struct dvb_frontend {
|
||||
|
|
|
@ -409,6 +409,7 @@ config DVB_USB_MXL111SF
|
|||
tristate "MxL111SF DTV USB2.0 support"
|
||||
depends on DVB_USB
|
||||
select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
|
||||
select DVB_LG2160 if !DVB_FE_CUSTOMISE
|
||||
select VIDEO_TVEEPROM
|
||||
help
|
||||
Say Y here to support the MxL111SF USB2.0 DTV receiver.
|
||||
|
@ -422,3 +423,15 @@ config DVB_USB_RTL28XXU
|
|||
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the Realtek RTL28xxU DVB USB receiver.
|
||||
|
||||
config DVB_USB_AF9035
|
||||
tristate "Afatech AF9035 DVB-T USB2.0 support"
|
||||
depends on DVB_USB
|
||||
select DVB_AF9033
|
||||
select MEDIA_TUNER_TUA9001 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_FC0011 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the Afatech AF9035 based DVB USB receiver.
|
||||
|
||||
|
|
|
@ -110,6 +110,9 @@ obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
|
|||
dvb-usb-rtl28xxu-objs = rtl28xxu.o
|
||||
obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
|
||||
|
||||
dvb-usb-af9035-objs = af9035.o
|
||||
obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
|
||||
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
|
||||
# due to tuner-xc3028
|
||||
|
|
|
@ -244,8 +244,7 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
u8 uninitialized_var(mbox), addr_len;
|
||||
struct req_t req;
|
||||
|
||||
/* TODO: implement bus lock
|
||||
|
||||
/*
|
||||
The bus lock is needed because there is two tuners both using same I2C-address.
|
||||
Due to that the only way to select correct tuner is use demodulator I2C-gate.
|
||||
|
||||
|
@ -789,7 +788,7 @@ static void af9015_set_remote_config(struct usb_device *udev,
|
|||
/* try to load remote based USB ID */
|
||||
if (!props->rc.core.rc_codes)
|
||||
props->rc.core.rc_codes = af9015_rc_setup_match(
|
||||
(vid << 16) + pid, af9015_rc_setup_usbids);
|
||||
(vid << 16) | pid, af9015_rc_setup_usbids);
|
||||
|
||||
/* try to load remote based USB iManufacturer string */
|
||||
if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) {
|
||||
|
@ -1220,8 +1219,8 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
}
|
||||
|
||||
/* attach demodulator */
|
||||
adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
|
||||
&adap->dev->i2c_adap);
|
||||
adap->fe_adap[0].fe = dvb_attach(af9013_attach,
|
||||
&af9015_af9013_config[adap->id], &adap->dev->i2c_adap);
|
||||
|
||||
/*
|
||||
* AF9015 firmware does not like if it gets interrupted by I2C adapter
|
||||
|
@ -1324,14 +1323,15 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
switch (af9015_af9013_config[adap->id].tuner) {
|
||||
case AF9013_TUNER_MT2060:
|
||||
case AF9013_TUNER_MT2060_2:
|
||||
ret = dvb_attach(mt2060_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
|
||||
&af9015_mt2060_config,
|
||||
ret = dvb_attach(mt2060_attach, adap->fe_adap[0].fe,
|
||||
&adap->dev->i2c_adap, &af9015_mt2060_config,
|
||||
af9015_config.mt2060_if1[adap->id])
|
||||
== NULL ? -ENODEV : 0;
|
||||
break;
|
||||
case AF9013_TUNER_QT1010:
|
||||
case AF9013_TUNER_QT1010A:
|
||||
ret = dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
|
||||
ret = dvb_attach(qt1010_attach, adap->fe_adap[0].fe,
|
||||
&adap->dev->i2c_adap,
|
||||
&af9015_qt1010_config) == NULL ? -ENODEV : 0;
|
||||
break;
|
||||
case AF9013_TUNER_TDA18271:
|
||||
|
@ -1434,69 +1434,85 @@ enum af9015_usb_table_entry {
|
|||
};
|
||||
|
||||
static struct usb_device_id af9015_usb_table[] = {
|
||||
[AFATECH_9015] =
|
||||
{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
|
||||
[AFATECH_9016] =
|
||||
{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
|
||||
[WINFAST_DTV_GOLD] =
|
||||
{USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
|
||||
[PINNACLE_PCTV_71E] =
|
||||
{USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
|
||||
[KWORLD_PLUSTV_399U] =
|
||||
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
|
||||
[TINYTWIN] = {USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN)},
|
||||
[AZUREWAVE_TU700] =
|
||||
{USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700)},
|
||||
[TERRATEC_AF9015] = {USB_DEVICE(USB_VID_TERRATEC,
|
||||
[AFATECH_9015] = {
|
||||
USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
|
||||
[AFATECH_9016] = {
|
||||
USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
|
||||
[WINFAST_DTV_GOLD] = {
|
||||
USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
|
||||
[PINNACLE_PCTV_71E] = {
|
||||
USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
|
||||
[KWORLD_PLUSTV_399U] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
|
||||
[TINYTWIN] = {
|
||||
USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN)},
|
||||
[AZUREWAVE_TU700] = {
|
||||
USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700)},
|
||||
[TERRATEC_AF9015] = {
|
||||
USB_DEVICE(USB_VID_TERRATEC,
|
||||
USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
|
||||
[KWORLD_PLUSTV_PC160] =
|
||||
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
|
||||
[AVERTV_VOLAR_X] =
|
||||
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
|
||||
[XTENSIONS_380U] =
|
||||
{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
|
||||
[MSI_DIGIVOX_DUO] =
|
||||
{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
|
||||
[AVERTV_VOLAR_X_REV2] =
|
||||
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
|
||||
[TELESTAR_STARSTICK_2] =
|
||||
{USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
|
||||
[AVERMEDIA_A309_USB] =
|
||||
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
|
||||
[MSI_DIGIVOX_MINI_III] =
|
||||
{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
|
||||
[KWORLD_E396] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
|
||||
[KWORLD_E39B] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
|
||||
[KWORLD_E395] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
|
||||
[TREKSTOR_DVBT] = {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
|
||||
[AVERTV_A850] = {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
|
||||
[AVERTV_A805] = {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
|
||||
[CONCEPTRONIC_CTVDIGRCU] =
|
||||
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
|
||||
[KWORLD_MC810] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
|
||||
[GENIUS_TVGO_DVB_T03] =
|
||||
{USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
|
||||
[KWORLD_399U_2] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
|
||||
[KWORLD_PC160_T] =
|
||||
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
|
||||
[SVEON_STV20] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
|
||||
[TINYTWIN_2] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
|
||||
[WINFAST_DTV2000DS] =
|
||||
{USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
|
||||
[KWORLD_UB383_T] =
|
||||
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
|
||||
[KWORLD_E39A] =
|
||||
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
|
||||
[AVERMEDIA_A815M] =
|
||||
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
|
||||
[CINERGY_T_STICK_RC] = {USB_DEVICE(USB_VID_TERRATEC,
|
||||
[KWORLD_PLUSTV_PC160] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
|
||||
[AVERTV_VOLAR_X] = {
|
||||
USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
|
||||
[XTENSIONS_380U] = {
|
||||
USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
|
||||
[MSI_DIGIVOX_DUO] = {
|
||||
USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
|
||||
[AVERTV_VOLAR_X_REV2] = {
|
||||
USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
|
||||
[TELESTAR_STARSTICK_2] = {
|
||||
USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
|
||||
[AVERMEDIA_A309_USB] = {
|
||||
USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
|
||||
[MSI_DIGIVOX_MINI_III] = {
|
||||
USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
|
||||
[KWORLD_E396] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
|
||||
[KWORLD_E39B] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
|
||||
[KWORLD_E395] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
|
||||
[TREKSTOR_DVBT] = {
|
||||
USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
|
||||
[AVERTV_A850] = {
|
||||
USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
|
||||
[AVERTV_A805] = {
|
||||
USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
|
||||
[CONCEPTRONIC_CTVDIGRCU] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
|
||||
[KWORLD_MC810] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
|
||||
[GENIUS_TVGO_DVB_T03] = {
|
||||
USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
|
||||
[KWORLD_399U_2] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
|
||||
[KWORLD_PC160_T] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
|
||||
[SVEON_STV20] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
|
||||
[TINYTWIN_2] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
|
||||
[WINFAST_DTV2000DS] = {
|
||||
USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
|
||||
[KWORLD_UB383_T] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
|
||||
[KWORLD_E39A] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
|
||||
[AVERMEDIA_A815M] = {
|
||||
USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
|
||||
[CINERGY_T_STICK_RC] = {
|
||||
USB_DEVICE(USB_VID_TERRATEC,
|
||||
USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
|
||||
[CINERGY_T_DUAL_RC] = {USB_DEVICE(USB_VID_TERRATEC,
|
||||
[CINERGY_T_DUAL_RC] = {
|
||||
USB_DEVICE(USB_VID_TERRATEC,
|
||||
USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)},
|
||||
[AVERTV_A850T] =
|
||||
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
|
||||
[TINYTWIN_3] = {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
|
||||
[SVEON_STV22] = {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)},
|
||||
[AVERTV_A850T] = {
|
||||
USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
|
||||
[TINYTWIN_3] = {
|
||||
USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
|
||||
[SVEON_STV22] = {
|
||||
USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
|
||||
|
@ -1516,43 +1532,44 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.num_adapters = 2,
|
||||
.adapter = {
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
||||
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.num_frontends = 1,
|
||||
.fe = {
|
||||
{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
||||
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = af9015_pid_filter,
|
||||
.pid_filter_ctrl = af9015_pid_filter_ctrl,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = af9015_pid_filter,
|
||||
.pid_filter_ctrl = af9015_pid_filter_ctrl,
|
||||
|
||||
.frontend_attach =
|
||||
af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x84,
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.frontend_attach =
|
||||
af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x85,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize =
|
||||
TS_USB20_FRAME_SIZE,
|
||||
}
|
||||
.frontend_attach = af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x84,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {
|
||||
{
|
||||
.frontend_attach = af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x85,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = TS_USB20_FRAME_SIZE,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}},
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1575,102 +1592,67 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.cold_ids = {
|
||||
&af9015_usb_table[AFATECH_9015],
|
||||
&af9015_usb_table[AFATECH_9016],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Leadtek WinFast DTV Dongle Gold",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[WINFAST_DTV_GOLD],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Pinnacle PCTV 71e",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[PINNACLE_PCTV_71E],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "KWorld PlusTV Dual DVB-T Stick " \
|
||||
"(DVB-T 399U)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[KWORLD_PLUSTV_399U],
|
||||
&af9015_usb_table[KWORLD_399U_2],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "DigitalNow TinyTwin DVB-T Receiver",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[TINYTWIN],
|
||||
&af9015_usb_table[TINYTWIN_2],
|
||||
&af9015_usb_table[TINYTWIN_3],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "TwinHan AzureWave AD-TU700(704J)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[AZUREWAVE_TU700],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "TerraTec Cinergy T USB XE",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[TERRATEC_AF9015],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "KWorld PlusTV Dual DVB-T PCI " \
|
||||
"(DVB-T PC160-2T)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[KWORLD_PLUSTV_PC160],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "AVerMedia AVerTV DVB-T Volar X",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[AVERTV_VOLAR_X],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "TerraTec Cinergy T Stick RC",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[CINERGY_T_STICK_RC],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "TerraTec Cinergy T Stick Dual RC",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[CINERGY_T_DUAL_RC],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "AverMedia AVerTV Red HD+ (A850T)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[AVERTV_A850T],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
}
|
||||
}, {
|
||||
|
@ -1686,43 +1668,44 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.num_adapters = 2,
|
||||
.adapter = {
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
||||
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.num_frontends = 1,
|
||||
.fe = {
|
||||
{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
||||
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = af9015_pid_filter,
|
||||
.pid_filter_ctrl = af9015_pid_filter_ctrl,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = af9015_pid_filter,
|
||||
.pid_filter_ctrl = af9015_pid_filter_ctrl,
|
||||
|
||||
.frontend_attach =
|
||||
af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x84,
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.frontend_attach =
|
||||
af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x85,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize =
|
||||
TS_USB20_FRAME_SIZE,
|
||||
}
|
||||
.frontend_attach = af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x84,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {
|
||||
{
|
||||
.frontend_attach = af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x85,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = TS_USB20_FRAME_SIZE,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}},
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1744,51 +1727,33 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.name = "Xtensions XD-380",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[XTENSIONS_380U],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "MSI DIGIVOX Duo",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[MSI_DIGIVOX_DUO],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[AVERTV_VOLAR_X_REV2],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Telestar Starstick 2",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[TELESTAR_STARSTICK_2],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "AVerMedia A309",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[AVERMEDIA_A309_USB],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "MSI Digi VOX mini III",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[MSI_DIGIVOX_MINI_III],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "KWorld USB DVB-T TV Stick II " \
|
||||
"(VS-DVB-T 395U)",
|
||||
.cold_ids = {
|
||||
|
@ -1796,34 +1761,23 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
&af9015_usb_table[KWORLD_E39B],
|
||||
&af9015_usb_table[KWORLD_E395],
|
||||
&af9015_usb_table[KWORLD_E39A],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "TrekStor DVB-T USB Stick",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[TREKSTOR_DVBT],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "AverMedia AVerTV Volar Black HD " \
|
||||
"(A850)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[AVERTV_A850],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Sveon STV22 Dual USB DVB-T Tuner HDTV",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[SVEON_STV22],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
}
|
||||
}, {
|
||||
|
@ -1839,43 +1793,44 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.num_adapters = 2,
|
||||
.adapter = {
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
||||
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.num_frontends = 1,
|
||||
.fe = {
|
||||
{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
||||
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = af9015_pid_filter,
|
||||
.pid_filter_ctrl = af9015_pid_filter_ctrl,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = af9015_pid_filter,
|
||||
.pid_filter_ctrl = af9015_pid_filter_ctrl,
|
||||
|
||||
.frontend_attach =
|
||||
af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x84,
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {{
|
||||
.frontend_attach =
|
||||
af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x85,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize =
|
||||
TS_USB20_FRAME_SIZE,
|
||||
}
|
||||
.frontend_attach = af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x84,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.num_frontends = 1,
|
||||
.fe = {
|
||||
{
|
||||
.frontend_attach = af9015_af9013_frontend_attach,
|
||||
.tuner_attach = af9015_tuner_attach,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
.endpoint = 0x85,
|
||||
.u = {
|
||||
.bulk = {
|
||||
.buffersize = TS_USB20_FRAME_SIZE,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}},
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1897,76 +1852,50 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.name = "AverMedia AVerTV Volar GPS 805 (A805)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[AVERTV_A805],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
|
||||
"V3.0",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[CONCEPTRONIC_CTVDIGRCU],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "KWorld Digial MC-810",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[KWORLD_MC810],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Genius TVGo DVB-T03",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[GENIUS_TVGO_DVB_T03],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "KWorld PlusTV DVB-T PCI Pro Card " \
|
||||
"(DVB-T PC160-T)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[KWORLD_PC160_T],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Sveon STV20 Tuner USB DVB-T HDTV",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[SVEON_STV20],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "Leadtek WinFast DTV2000DS",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[WINFAST_DTV2000DS],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "KWorld USB DVB-T Stick Mobile " \
|
||||
"(UB383-T)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[KWORLD_UB383_T],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.name = "AverMedia AVerTV Volar M (A815Mac)",
|
||||
.cold_ids = {
|
||||
&af9015_usb_table[AVERMEDIA_A815M],
|
||||
NULL
|
||||
},
|
||||
.warm_ids = {NULL},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -2019,5 +1948,5 @@ static struct usb_driver af9015_usb_driver = {
|
|||
module_usb_driver(af9015_usb_driver);
|
||||
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T");
|
||||
MODULE_DESCRIPTION("Afatech AF9015 driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Afatech AF9035 DVB USB driver
|
||||
*
|
||||
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
|
||||
* Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef AF9035_H
|
||||
#define AF9035_H
|
||||
|
||||
/* prefix for dvb-usb log writings */
|
||||
#define DVB_USB_LOG_PREFIX "af9035"
|
||||
|
||||
#include "dvb-usb.h"
|
||||
#include "af9033.h"
|
||||
#include "tua9001.h"
|
||||
#include "fc0011.h"
|
||||
#include "mxl5007t.h"
|
||||
#include "tda18218.h"
|
||||
|
||||
struct reg_val {
|
||||
u32 reg;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
struct reg_val_mask {
|
||||
u32 reg;
|
||||
u8 val;
|
||||
u8 mask;
|
||||
};
|
||||
|
||||
struct usb_req {
|
||||
u8 cmd;
|
||||
u8 mbox;
|
||||
u8 wlen;
|
||||
u8 *wbuf;
|
||||
u8 rlen;
|
||||
u8 *rbuf;
|
||||
};
|
||||
|
||||
struct state {
|
||||
bool dual_mode;
|
||||
|
||||
struct af9033_config af9033_config[2];
|
||||
};
|
||||
|
||||
u32 clock_lut[] = {
|
||||
20480000, /* FPGA */
|
||||
16384000, /* 16.38 MHz */
|
||||
20480000, /* 20.48 MHz */
|
||||
36000000, /* 36.00 MHz */
|
||||
30000000, /* 30.00 MHz */
|
||||
26000000, /* 26.00 MHz */
|
||||
28000000, /* 28.00 MHz */
|
||||
32000000, /* 32.00 MHz */
|
||||
34000000, /* 34.00 MHz */
|
||||
24000000, /* 24.00 MHz */
|
||||
22000000, /* 22.00 MHz */
|
||||
12000000, /* 12.00 MHz */
|
||||
};
|
||||
|
||||
u32 clock_lut_it9135[] = {
|
||||
12000000, /* 12.00 MHz */
|
||||
20480000, /* 20.48 MHz */
|
||||
36000000, /* 36.00 MHz */
|
||||
30000000, /* 30.00 MHz */
|
||||
26000000, /* 26.00 MHz */
|
||||
28000000, /* 28.00 MHz */
|
||||
32000000, /* 32.00 MHz */
|
||||
34000000, /* 34.00 MHz */
|
||||
24000000, /* 24.00 MHz */
|
||||
22000000, /* 22.00 MHz */
|
||||
};
|
||||
|
||||
/* EEPROM locations */
|
||||
#define EEPROM_IR_MODE 0x430d
|
||||
#define EEPROM_DUAL_MODE 0x4326
|
||||
#define EEPROM_IR_TYPE 0x4329
|
||||
#define EEPROM_1_IFFREQ_L 0x432d
|
||||
#define EEPROM_1_IFFREQ_H 0x432e
|
||||
#define EEPROM_1_TUNER_ID 0x4331
|
||||
#define EEPROM_2_IFFREQ_L 0x433d
|
||||
#define EEPROM_2_IFFREQ_H 0x433e
|
||||
#define EEPROM_2_TUNER_ID 0x4341
|
||||
|
||||
/* USB commands */
|
||||
#define CMD_MEM_RD 0x00
|
||||
#define CMD_MEM_WR 0x01
|
||||
#define CMD_I2C_RD 0x02
|
||||
#define CMD_I2C_WR 0x03
|
||||
#define CMD_IR_GET 0x18
|
||||
#define CMD_FW_DL 0x21
|
||||
#define CMD_FW_QUERYINFO 0x22
|
||||
#define CMD_FW_BOOT 0x23
|
||||
#define CMD_FW_DL_BEGIN 0x24
|
||||
#define CMD_FW_DL_END 0x25
|
||||
#define CMD_FW_SCATTER_WR 0x29
|
||||
|
||||
#endif
|
|
@ -32,7 +32,7 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
|
|||
|
||||
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
|
||||
|
@ -118,7 +118,7 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
|
|||
|
||||
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
st->buf[0] = REQUEST_SET_GPIO;
|
||||
|
@ -139,7 +139,7 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
|
|||
if (st->fw_version >= 0x10201) {
|
||||
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
st->buf[0] = REQUEST_SET_USB_XFER_LEN;
|
||||
|
@ -178,7 +178,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
|
|||
/* Ensure nobody else hits the i2c bus while we're sending our
|
||||
sequence of messages, (such as the remote control thread) */
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
return -EINTR;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (i == 0) {
|
||||
|
@ -228,7 +228,8 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
|
|||
/* Write request */
|
||||
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
return -EINTR;
|
||||
}
|
||||
st->buf[0] = REQUEST_NEW_I2C_WRITE;
|
||||
st->buf[1] = msg[i].addr << 1;
|
||||
|
@ -271,10 +272,11 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
|
|||
int i,len;
|
||||
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
return -EINTR;
|
||||
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
|
@ -369,7 +371,7 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
|
|||
|
||||
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
st->buf[0] = REQUEST_SET_CLOCK;
|
||||
|
@ -401,7 +403,7 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
|
|||
|
||||
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
st->buf[0] = REQUEST_SET_I2C_PARAM;
|
||||
|
@ -561,7 +563,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
|||
|
||||
if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
st->buf[0] = REQUEST_ENABLE_VIDEO;
|
||||
|
@ -611,7 +613,7 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
|
|||
|
||||
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
|
||||
err("could not acquire lock");
|
||||
return 0;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
st->buf[0] = REQUEST_SET_RC;
|
||||
|
|
|
@ -3569,6 +3569,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
|
|||
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) },
|
||||
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) },
|
||||
/* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) },
|
||||
{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_2) },
|
||||
{ 0 } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
|
||||
|
@ -3832,7 +3833,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
},
|
||||
},
|
||||
|
||||
.num_device_descs = 11,
|
||||
.num_device_descs = 12,
|
||||
.devices = {
|
||||
{ "DiBcom STK7070P reference design",
|
||||
{ &dib0700_usb_id_table[15], NULL },
|
||||
|
@ -3878,6 +3879,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
{ &dib0700_usb_id_table[50], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "Elgato EyeTV DTT rev. 2",
|
||||
{ &dib0700_usb_id_table[81], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
},
|
||||
|
||||
.rc.core = {
|
||||
|
|
|
@ -76,6 +76,11 @@
|
|||
#define USB_PID_AFATECH_AF9005 0x9020
|
||||
#define USB_PID_AFATECH_AF9015_9015 0x9015
|
||||
#define USB_PID_AFATECH_AF9015_9016 0x9016
|
||||
#define USB_PID_AFATECH_AF9035_1000 0x1000
|
||||
#define USB_PID_AFATECH_AF9035_1001 0x1001
|
||||
#define USB_PID_AFATECH_AF9035_1002 0x1002
|
||||
#define USB_PID_AFATECH_AF9035_1003 0x1003
|
||||
#define USB_PID_AFATECH_AF9035_9035 0x9035
|
||||
#define USB_PID_TREKSTOR_DVBT 0x901b
|
||||
#define USB_VID_ALINK_DTU 0xf170
|
||||
#define USB_PID_ANSONIC_DVBT_USB 0x6000
|
||||
|
@ -152,6 +157,7 @@
|
|||
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
|
||||
#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
|
||||
#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069
|
||||
#define USB_PID_TERRATEC_CINERGY_T_STICK 0x0093
|
||||
#define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097
|
||||
#define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099
|
||||
#define USB_PID_TWINHAN_VP7041_COLD 0x3201
|
||||
|
@ -221,6 +227,11 @@
|
|||
#define USB_PID_AVERMEDIA_A850T 0x850b
|
||||
#define USB_PID_AVERMEDIA_A805 0xa805
|
||||
#define USB_PID_AVERMEDIA_A815M 0x815a
|
||||
#define USB_PID_AVERMEDIA_A835 0xa835
|
||||
#define USB_PID_AVERMEDIA_B835 0xb835
|
||||
#define USB_PID_AVERMEDIA_1867 0x1867
|
||||
#define USB_PID_AVERMEDIA_A867 0xa867
|
||||
#define USB_PID_AVERMEDIA_TWINSTAR 0x0825
|
||||
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
|
||||
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
|
||||
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
|
||||
|
@ -327,6 +338,7 @@
|
|||
#define USB_PID_MYGICA_D689 0xd811
|
||||
#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
|
||||
#define USB_PID_ELGATO_EYETV_DTT 0x0021
|
||||
#define USB_PID_ELGATO_EYETV_DTT_2 0x003f
|
||||
#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
|
||||
#define USB_PID_ELGATO_EYETV_SAT 0x002a
|
||||
#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
|
||||
|
|
|
@ -80,6 +80,14 @@ static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer
|
|||
dvb_dmx_swfilter_204(&adap->demux, buffer, length);
|
||||
}
|
||||
|
||||
static void dvb_usb_data_complete_raw(struct usb_data_stream *stream,
|
||||
u8 *buffer, size_t length)
|
||||
{
|
||||
struct dvb_usb_adapter *adap = stream->user_priv;
|
||||
if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
|
||||
dvb_dmx_swfilter_raw(&adap->demux, buffer, length);
|
||||
}
|
||||
|
||||
int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
@ -90,6 +98,10 @@ int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
|
|||
adap->fe_adap[i].stream.complete =
|
||||
dvb_usb_data_complete_204;
|
||||
else
|
||||
if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD)
|
||||
adap->fe_adap[i].stream.complete =
|
||||
dvb_usb_data_complete_raw;
|
||||
else
|
||||
adap->fe_adap[i].stream.complete = dvb_usb_data_complete;
|
||||
adap->fe_adap[i].stream.user_priv = adap;
|
||||
ret = usb_urb_init(&adap->fe_adap[i].stream,
|
||||
|
|
|
@ -141,6 +141,7 @@ struct dvb_usb_adapter_fe_properties {
|
|||
#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
|
||||
#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04
|
||||
#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS 0x08
|
||||
#define DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD 0x10
|
||||
int caps;
|
||||
int pid_filter_count;
|
||||
|
||||
|
@ -156,7 +157,7 @@ struct dvb_usb_adapter_fe_properties {
|
|||
int size_of_priv;
|
||||
};
|
||||
|
||||
#define MAX_NO_OF_FE_PER_ADAP 2
|
||||
#define MAX_NO_OF_FE_PER_ADAP 3
|
||||
struct dvb_usb_adapter_properties {
|
||||
int size_of_priv;
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int i = 0, ret = 0;
|
||||
int i = 0;
|
||||
u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
|
||||
u16 value;
|
||||
|
||||
|
@ -162,7 +162,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
/* read stv0299 register */
|
||||
value = msg[0].buf[0];/* register */
|
||||
for (i = 0; i < msg[1].len; i++) {
|
||||
ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0,
|
||||
dw210x_op_rw(d->udev, 0xb5, value + i, 0,
|
||||
buf6, 2, DW210X_READ_MSG);
|
||||
msg[1].buf[i] = buf6[0];
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
buf6[0] = 0x2a;
|
||||
buf6[1] = msg[0].buf[0];
|
||||
buf6[2] = msg[0].buf[1];
|
||||
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
buf6, 3, DW210X_WRITE_MSG);
|
||||
break;
|
||||
case 0x60:
|
||||
|
@ -187,17 +187,17 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
buf6[4] = msg[0].buf[1];
|
||||
buf6[5] = msg[0].buf[2];
|
||||
buf6[6] = msg[0].buf[3];
|
||||
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
buf6, 7, DW210X_WRITE_MSG);
|
||||
} else {
|
||||
/* read from tuner */
|
||||
ret = dw210x_op_rw(d->udev, 0xb5, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb5, 0, 0,
|
||||
buf6, 1, DW210X_READ_MSG);
|
||||
msg[0].buf[0] = buf6[0];
|
||||
}
|
||||
break;
|
||||
case (DW2102_RC_QUERY):
|
||||
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
buf6, 2, DW210X_READ_MSG);
|
||||
msg[0].buf[0] = buf6[0];
|
||||
msg[0].buf[1] = buf6[1];
|
||||
|
@ -205,7 +205,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
case (DW2102_VOLTAGE_CTRL):
|
||||
buf6[0] = 0x30;
|
||||
buf6[1] = msg[0].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
buf6, 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
|
@ -221,7 +221,6 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
|
|||
struct i2c_msg msg[], int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int ret = 0;
|
||||
u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
if (!d)
|
||||
|
@ -235,10 +234,10 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
|
|||
buf6[0] = msg[0].addr << 1;
|
||||
buf6[1] = msg[0].len;
|
||||
buf6[2] = msg[0].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
buf6, msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
/* read si2109 register */
|
||||
ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
|
||||
buf6, msg[1].len + 2, DW210X_READ_MSG);
|
||||
memcpy(msg[1].buf, buf6 + 2, msg[1].len);
|
||||
|
||||
|
@ -250,11 +249,11 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
|
|||
buf6[0] = msg[0].addr << 1;
|
||||
buf6[1] = msg[0].len;
|
||||
memcpy(buf6 + 2, msg[0].buf, msg[0].len);
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
|
||||
msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
case(DW2102_RC_QUERY):
|
||||
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
buf6, 2, DW210X_READ_MSG);
|
||||
msg[0].buf[0] = buf6[0];
|
||||
msg[0].buf[1] = buf6[1];
|
||||
|
@ -262,7 +261,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
|
|||
case(DW2102_VOLTAGE_CTRL):
|
||||
buf6[0] = 0x30;
|
||||
buf6[1] = msg[0].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
buf6, 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
|
@ -276,7 +275,6 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
|
|||
static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int ret = 0;
|
||||
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
|
@ -291,10 +289,10 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
|||
obuf[0] = msg[0].addr << 1;
|
||||
obuf[1] = msg[0].len;
|
||||
obuf[2] = msg[0].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
/* second read registers */
|
||||
ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
|
||||
dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
|
||||
ibuf, msg[1].len + 2, DW210X_READ_MSG);
|
||||
memcpy(msg[1].buf, ibuf + 2, msg[1].len);
|
||||
|
||||
|
@ -308,7 +306,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
|||
obuf[0] = msg[0].addr << 1;
|
||||
obuf[1] = msg[0].len;
|
||||
memcpy(obuf + 2, msg[0].buf, msg[0].len);
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
|
@ -318,13 +316,13 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
|||
obuf[0] = msg[0].addr << 1;
|
||||
obuf[1] = msg[0].len;
|
||||
memcpy(obuf + 2, msg[0].buf, msg[0].len);
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
case(DW2102_RC_QUERY): {
|
||||
u8 ibuf[2];
|
||||
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
ibuf, 2, DW210X_READ_MSG);
|
||||
memcpy(msg[0].buf, ibuf , 2);
|
||||
break;
|
||||
|
@ -333,7 +331,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
|||
u8 obuf[2];
|
||||
obuf[0] = 0x30;
|
||||
obuf[1] = msg[0].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
obuf, 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
|
@ -349,7 +347,6 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
|||
static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int ret = 0;
|
||||
int len, i, j;
|
||||
|
||||
if (!d)
|
||||
|
@ -361,7 +358,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
|||
switch (msg[j].addr) {
|
||||
case(DW2102_RC_QUERY): {
|
||||
u8 ibuf[2];
|
||||
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
ibuf, 2, DW210X_READ_MSG);
|
||||
memcpy(msg[j].buf, ibuf , 2);
|
||||
break;
|
||||
|
@ -370,7 +367,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
|||
u8 obuf[2];
|
||||
obuf[0] = 0x30;
|
||||
obuf[1] = msg[j].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
obuf, 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
|
@ -382,7 +379,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
|||
if (msg[j].flags == I2C_M_RD) {
|
||||
/* read registers */
|
||||
u8 ibuf[msg[j].len + 2];
|
||||
ret = dw210x_op_rw(d->udev, 0xc3,
|
||||
dw210x_op_rw(d->udev, 0xc3,
|
||||
(msg[j].addr << 1) + 1, 0,
|
||||
ibuf, msg[j].len + 2,
|
||||
DW210X_READ_MSG);
|
||||
|
@ -402,7 +399,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
|||
do {
|
||||
memcpy(obuf + 3, msg[j].buf + i,
|
||||
(len > 16 ? 16 : len));
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, (len > 16 ? 16 : len) + 3,
|
||||
DW210X_WRITE_MSG);
|
||||
i += 16;
|
||||
|
@ -414,7 +411,7 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
|||
obuf[0] = msg[j].addr << 1;
|
||||
obuf[1] = msg[j].len;
|
||||
memcpy(obuf + 2, msg[j].buf, msg[j].len);
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, msg[j].len + 2,
|
||||
DW210X_WRITE_MSG);
|
||||
}
|
||||
|
@ -432,7 +429,7 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
int num)
|
||||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int ret = 0, i;
|
||||
int i;
|
||||
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
|
@ -447,10 +444,10 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
obuf[0] = msg[0].addr << 1;
|
||||
obuf[1] = msg[0].len;
|
||||
obuf[2] = msg[0].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
/* second read registers */
|
||||
ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
|
||||
dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
|
||||
ibuf, msg[1].len + 2, DW210X_READ_MSG);
|
||||
memcpy(msg[1].buf, ibuf + 2, msg[1].len);
|
||||
|
||||
|
@ -465,13 +462,13 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
obuf[0] = msg[0].addr << 1;
|
||||
obuf[1] = msg[0].len;
|
||||
memcpy(obuf + 2, msg[0].buf, msg[0].len);
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
case(DW2102_RC_QUERY): {
|
||||
u8 ibuf[2];
|
||||
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
ibuf, 2, DW210X_READ_MSG);
|
||||
memcpy(msg[0].buf, ibuf , 2);
|
||||
break;
|
||||
|
@ -496,7 +493,6 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
struct usb_device *udev;
|
||||
int ret = 0;
|
||||
int len, i, j;
|
||||
|
||||
if (!d)
|
||||
|
@ -509,7 +505,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
switch (msg[j].addr) {
|
||||
case (DW2102_RC_QUERY): {
|
||||
u8 ibuf[5];
|
||||
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
ibuf, 5, DW210X_READ_MSG);
|
||||
memcpy(msg[j].buf, ibuf + 3, 2);
|
||||
break;
|
||||
|
@ -519,11 +515,11 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
|
||||
obuf[0] = 1;
|
||||
obuf[1] = msg[j].buf[1];/* off-on */
|
||||
ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0x8a, 0, 0,
|
||||
obuf, 2, DW210X_WRITE_MSG);
|
||||
obuf[0] = 3;
|
||||
obuf[1] = msg[j].buf[0];/* 13v-18v */
|
||||
ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0x8a, 0, 0,
|
||||
obuf, 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
|
@ -532,7 +528,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
|
||||
obuf[0] = 5;
|
||||
obuf[1] = msg[j].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0x8a, 0, 0,
|
||||
obuf, 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
|
@ -545,7 +541,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
if (msg[j].flags == I2C_M_RD) {
|
||||
/* read registers */
|
||||
u8 ibuf[msg[j].len];
|
||||
ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0x91, 0, 0,
|
||||
ibuf, msg[j].len,
|
||||
DW210X_READ_MSG);
|
||||
memcpy(msg[j].buf, ibuf, msg[j].len);
|
||||
|
@ -563,7 +559,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
do {
|
||||
memcpy(obuf + 3, msg[j].buf + i,
|
||||
(len > 16 ? 16 : len));
|
||||
ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0x80, 0, 0,
|
||||
obuf, (len > 16 ? 16 : len) + 3,
|
||||
DW210X_WRITE_MSG);
|
||||
i += 16;
|
||||
|
@ -575,7 +571,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
obuf[0] = msg[j + 1].len;
|
||||
obuf[1] = (msg[j].addr << 1);
|
||||
memcpy(obuf + 2, msg[j].buf, msg[j].len);
|
||||
ret = dw210x_op_rw(d->udev,
|
||||
dw210x_op_rw(d->udev,
|
||||
udev->descriptor.idProduct ==
|
||||
0x7500 ? 0x92 : 0x90, 0, 0,
|
||||
obuf, msg[j].len + 2,
|
||||
|
@ -587,7 +583,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
obuf[0] = msg[j].len + 1;
|
||||
obuf[1] = (msg[j].addr << 1);
|
||||
memcpy(obuf + 2, msg[j].buf, msg[j].len);
|
||||
ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
|
||||
dw210x_op_rw(d->udev, 0x80, 0, 0,
|
||||
obuf, msg[j].len + 2,
|
||||
DW210X_WRITE_MSG);
|
||||
break;
|
||||
|
|
|
@ -81,7 +81,7 @@ static int it913x_bulk_write(struct usb_device *dev,
|
|||
for (i = 0; i < IT913X_RETRY; i++) {
|
||||
ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
|
||||
snd, len , &actual_l, IT913X_SND_TIMEOUT);
|
||||
if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT)
|
||||
if (ret != -EBUSY && ret != -ETIMEDOUT)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ static int it913x_bulk_read(struct usb_device *dev,
|
|||
for (i = 0; i < IT913X_RETRY; i++) {
|
||||
ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
|
||||
rev, len , &actual_l, IT913X_RCV_TIMEOUT);
|
||||
if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT)
|
||||
if (ret != -EBUSY && ret != -ETIMEDOUT)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -373,7 +373,7 @@ static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
|||
struct lme2510_state *st = adap->dev->priv;
|
||||
static u8 clear_pid_reg[] = LME_ALL_PIDS;
|
||||
static u8 rbuf[1];
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
deb_info(1, "PID Clearing Filter");
|
||||
|
||||
|
@ -1205,14 +1205,13 @@ static int lme2510_probe(struct usb_interface *intf,
|
|||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
int ret = 0;
|
||||
|
||||
usb_reset_configuration(udev);
|
||||
|
||||
usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
|
||||
|
||||
if (udev->speed != USB_SPEED_HIGH) {
|
||||
ret = usb_reset_device(udev);
|
||||
usb_reset_device(udev);
|
||||
info("DEV Failed to connect in HIGH SPEED mode");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -284,6 +284,7 @@ static int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
|
|||
|
||||
switch (delsys) {
|
||||
case SYS_ATSC:
|
||||
case SYS_ATSCMH:
|
||||
bw = 0; /* ATSC */
|
||||
break;
|
||||
case SYS_DVBC_ANNEX_B:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -322,6 +322,9 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
* since there is some demod params needed to set according to tuner.
|
||||
*/
|
||||
|
||||
/* demod needs some time to wake up */
|
||||
msleep(20);
|
||||
|
||||
/* open demod I2C gate */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate);
|
||||
if (ret)
|
||||
|
@ -909,6 +912,8 @@ static int rtl28xxu_probe(struct usb_interface *intf,
|
|||
int ret, i;
|
||||
int properties_count = ARRAY_SIZE(rtl28xxu_properties);
|
||||
struct dvb_usb_device *d;
|
||||
struct usb_device *udev;
|
||||
bool found;
|
||||
|
||||
deb_info("%s: interface=%d\n", __func__,
|
||||
intf->cur_altsetting->desc.bInterfaceNumber);
|
||||
|
@ -916,6 +921,29 @@ static int rtl28xxu_probe(struct usb_interface *intf,
|
|||
if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
|
||||
return 0;
|
||||
|
||||
/* Dynamic USB ID support. Replaces first device ID with current one .*/
|
||||
udev = interface_to_usbdev(intf);
|
||||
|
||||
for (i = 0, found = false; i < ARRAY_SIZE(rtl28xxu_table) - 1; i++) {
|
||||
if (rtl28xxu_table[i].idVendor ==
|
||||
le16_to_cpu(udev->descriptor.idVendor) &&
|
||||
rtl28xxu_table[i].idProduct ==
|
||||
le16_to_cpu(udev->descriptor.idProduct)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
deb_info("%s: using dynamic ID %04x:%04x\n", __func__,
|
||||
le16_to_cpu(udev->descriptor.idVendor),
|
||||
le16_to_cpu(udev->descriptor.idProduct));
|
||||
rtl28xxu_properties[0].devices[0].warm_ids[0]->idVendor =
|
||||
le16_to_cpu(udev->descriptor.idVendor);
|
||||
rtl28xxu_properties[0].devices[0].warm_ids[0]->idProduct =
|
||||
le16_to_cpu(udev->descriptor.idProduct);
|
||||
}
|
||||
|
||||
for (i = 0; i < properties_count; i++) {
|
||||
ret = dvb_usb_device_init(intf, &rtl28xxu_properties[i],
|
||||
THIS_MODULE, &d, adapter_nr);
|
||||
|
|
|
@ -531,6 +531,14 @@ config DVB_LGDT3305
|
|||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_LG2160
|
||||
tristate "LG Electronics LG216x based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
An ATSC/MH demodulator module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_S5H1409
|
||||
tristate "Samsung S5H1409 based"
|
||||
depends on DVB_CORE && I2C
|
||||
|
@ -540,12 +548,26 @@ config DVB_S5H1409
|
|||
to support this frontend.
|
||||
|
||||
config DVB_AU8522
|
||||
tristate "Auvitek AU8522 based"
|
||||
depends on DVB_CORE && I2C && VIDEO_V4L2
|
||||
depends on I2C
|
||||
tristate
|
||||
|
||||
config DVB_AU8522_DTV
|
||||
tristate "Auvitek AU8522 based DTV demod"
|
||||
depends on DVB_CORE && I2C
|
||||
select DVB_AU8522
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
|
||||
you want to enable DTV demodulation support for this frontend.
|
||||
|
||||
config DVB_AU8522_V4L
|
||||
tristate "Auvitek AU8522 based ATV demod"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
select DVB_AU8522
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
|
||||
you want to enable ATV demodulation support for this frontend.
|
||||
|
||||
config DVB_S5H1411
|
||||
tristate "Samsung S5H1411 based"
|
||||
|
@ -713,6 +735,11 @@ config DVB_M88RS2000
|
|||
A DVB-S tuner module.
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_AF9033
|
||||
tristate "Afatech AF9033 DVB-T demodulator"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
|
||||
comment "Tools to develop new frontends"
|
||||
|
||||
config DVB_DUMMY_FE
|
||||
|
|
|
@ -7,7 +7,6 @@ ccflags-y += -I$(srctree)/drivers/media/common/tuners/
|
|||
|
||||
stb0899-objs = stb0899_drv.o stb0899_algo.o
|
||||
stv0900-objs = stv0900_core.o stv0900_sw.o
|
||||
au8522-objs = au8522_dig.o au8522_decoder.o
|
||||
drxd-objs = drxd_firm.o drxd_hard.o
|
||||
cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
|
||||
drxk-objs := drxk_hard.o
|
||||
|
@ -50,6 +49,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
|
|||
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
|
||||
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
|
||||
obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
|
||||
obj-$(CONFIG_DVB_LG2160) += lg2160.o
|
||||
obj-$(CONFIG_DVB_CX24123) += cx24123.o
|
||||
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
|
||||
obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
|
||||
|
@ -63,7 +63,9 @@ obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
|
|||
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
|
||||
obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
|
||||
obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
|
||||
obj-$(CONFIG_DVB_AU8522) += au8522.o
|
||||
obj-$(CONFIG_DVB_AU8522) += au8522_common.o
|
||||
obj-$(CONFIG_DVB_AU8522_DTV) += au8522_dig.o
|
||||
obj-$(CONFIG_DVB_AU8522_V4L) += au8522_decoder.o
|
||||
obj-$(CONFIG_DVB_TDA10048) += tda10048.o
|
||||
obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
|
||||
obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
|
||||
|
@ -98,4 +100,5 @@ obj-$(CONFIG_DVB_A8293) += a8293.o
|
|||
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
|
||||
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
|
||||
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
|
||||
obj-$(CONFIG_DVB_AF9033) += af9033.o
|
||||
|
||||
|
|
|
@ -514,7 +514,6 @@ err:
|
|||
|
||||
static void af9013_statistics_work(struct work_struct *work)
|
||||
{
|
||||
int ret;
|
||||
struct af9013_state *state = container_of(work,
|
||||
struct af9013_state, statistics_work.work);
|
||||
unsigned int next_msec;
|
||||
|
@ -530,27 +529,27 @@ static void af9013_statistics_work(struct work_struct *work)
|
|||
default:
|
||||
state->statistics_step = 0;
|
||||
case 0:
|
||||
ret = af9013_statistics_signal_strength(&state->fe);
|
||||
af9013_statistics_signal_strength(&state->fe);
|
||||
state->statistics_step++;
|
||||
next_msec = 300;
|
||||
break;
|
||||
case 1:
|
||||
ret = af9013_statistics_snr_start(&state->fe);
|
||||
af9013_statistics_snr_start(&state->fe);
|
||||
state->statistics_step++;
|
||||
next_msec = 200;
|
||||
break;
|
||||
case 2:
|
||||
ret = af9013_statistics_ber_unc_start(&state->fe);
|
||||
af9013_statistics_ber_unc_start(&state->fe);
|
||||
state->statistics_step++;
|
||||
next_msec = 1000;
|
||||
break;
|
||||
case 3:
|
||||
ret = af9013_statistics_snr_result(&state->fe);
|
||||
af9013_statistics_snr_result(&state->fe);
|
||||
state->statistics_step++;
|
||||
next_msec = 400;
|
||||
break;
|
||||
case 4:
|
||||
ret = af9013_statistics_ber_unc_result(&state->fe);
|
||||
af9013_statistics_ber_unc_result(&state->fe);
|
||||
state->statistics_step++;
|
||||
next_msec = 100;
|
||||
break;
|
||||
|
@ -558,8 +557,6 @@ static void af9013_statistics_work(struct work_struct *work)
|
|||
|
||||
schedule_delayed_work(&state->statistics_work,
|
||||
msecs_to_jiffies(next_msec));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int af9013_get_tune_settings(struct dvb_frontend *fe,
|
||||
|
|
|
@ -0,0 +1,980 @@
|
|||
/*
|
||||
* Afatech AF9033 demodulator driver
|
||||
*
|
||||
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
|
||||
* Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "af9033_priv.h"
|
||||
|
||||
struct af9033_state {
|
||||
struct i2c_adapter *i2c;
|
||||
struct dvb_frontend fe;
|
||||
struct af9033_config cfg;
|
||||
|
||||
u32 bandwidth_hz;
|
||||
bool ts_mode_parallel;
|
||||
bool ts_mode_serial;
|
||||
|
||||
u32 ber;
|
||||
u32 ucb;
|
||||
unsigned long last_stat_check;
|
||||
};
|
||||
|
||||
/* write multiple registers */
|
||||
static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
|
||||
int len)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[3 + len];
|
||||
struct i2c_msg msg[1] = {
|
||||
{
|
||||
.addr = state->cfg.i2c_addr,
|
||||
.flags = 0,
|
||||
.len = sizeof(buf),
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
buf[0] = (reg >> 16) & 0xff;
|
||||
buf[1] = (reg >> 8) & 0xff;
|
||||
buf[2] = (reg >> 0) & 0xff;
|
||||
memcpy(&buf[3], val, len);
|
||||
|
||||
ret = i2c_transfer(state->i2c, msg, 1);
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: i2c wr failed=%d reg=%06x len=%d\n",
|
||||
__func__, ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* read multiple registers */
|
||||
static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff,
|
||||
(reg >> 0) & 0xff };
|
||||
struct i2c_msg msg[2] = {
|
||||
{
|
||||
.addr = state->cfg.i2c_addr,
|
||||
.flags = 0,
|
||||
.len = sizeof(buf),
|
||||
.buf = buf
|
||||
}, {
|
||||
.addr = state->cfg.i2c_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = val
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(state->i2c, msg, 2);
|
||||
if (ret == 2) {
|
||||
ret = 0;
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: i2c rd failed=%d reg=%06x len=%d\n",
|
||||
__func__, ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* write single register */
|
||||
static int af9033_wr_reg(struct af9033_state *state, u32 reg, u8 val)
|
||||
{
|
||||
return af9033_wr_regs(state, reg, &val, 1);
|
||||
}
|
||||
|
||||
/* read single register */
|
||||
static int af9033_rd_reg(struct af9033_state *state, u32 reg, u8 *val)
|
||||
{
|
||||
return af9033_rd_regs(state, reg, val, 1);
|
||||
}
|
||||
|
||||
/* write single register with mask */
|
||||
static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
|
||||
u8 mask)
|
||||
{
|
||||
int ret;
|
||||
u8 tmp;
|
||||
|
||||
/* no need for read if whole reg is written */
|
||||
if (mask != 0xff) {
|
||||
ret = af9033_rd_regs(state, reg, &tmp, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val &= mask;
|
||||
tmp &= ~mask;
|
||||
val |= tmp;
|
||||
}
|
||||
|
||||
return af9033_wr_regs(state, reg, &val, 1);
|
||||
}
|
||||
|
||||
/* read single register with mask */
|
||||
static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
|
||||
u8 mask)
|
||||
{
|
||||
int ret, i;
|
||||
u8 tmp;
|
||||
|
||||
ret = af9033_rd_regs(state, reg, &tmp, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tmp &= mask;
|
||||
|
||||
/* find position of the first bit */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((mask >> i) & 0x01)
|
||||
break;
|
||||
}
|
||||
*val = tmp >> i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 af9033_div(u32 a, u32 b, u32 x)
|
||||
{
|
||||
u32 r = 0, c = 0, i;
|
||||
|
||||
pr_debug("%s: a=%d b=%d x=%d\n", __func__, a, b, x);
|
||||
|
||||
if (a > b) {
|
||||
c = a / b;
|
||||
a = a - c * b;
|
||||
}
|
||||
|
||||
for (i = 0; i < x; i++) {
|
||||
if (a >= b) {
|
||||
r += 1;
|
||||
a -= b;
|
||||
}
|
||||
a <<= 1;
|
||||
r <<= 1;
|
||||
}
|
||||
r = (c << (u32)x) + r;
|
||||
|
||||
pr_debug("%s: a=%d b=%d x=%d r=%d r=%x\n", __func__, a, b, x, r, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void af9033_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static int af9033_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret, i, len;
|
||||
const struct reg_val *init;
|
||||
u8 buf[4];
|
||||
u32 adc_cw, clock_cw;
|
||||
struct reg_val_mask tab[] = {
|
||||
{ 0x80fb24, 0x00, 0x08 },
|
||||
{ 0x80004c, 0x00, 0xff },
|
||||
{ 0x00f641, state->cfg.tuner, 0xff },
|
||||
{ 0x80f5ca, 0x01, 0x01 },
|
||||
{ 0x80f715, 0x01, 0x01 },
|
||||
{ 0x00f41f, 0x04, 0x04 },
|
||||
{ 0x00f41a, 0x01, 0x01 },
|
||||
{ 0x80f731, 0x00, 0x01 },
|
||||
{ 0x00d91e, 0x00, 0x01 },
|
||||
{ 0x00d919, 0x00, 0x01 },
|
||||
{ 0x80f732, 0x00, 0x01 },
|
||||
{ 0x00d91f, 0x00, 0x01 },
|
||||
{ 0x00d91a, 0x00, 0x01 },
|
||||
{ 0x80f730, 0x00, 0x01 },
|
||||
{ 0x80f778, 0x00, 0xff },
|
||||
{ 0x80f73c, 0x01, 0x01 },
|
||||
{ 0x80f776, 0x00, 0x01 },
|
||||
{ 0x00d8fd, 0x01, 0xff },
|
||||
{ 0x00d830, 0x01, 0xff },
|
||||
{ 0x00d831, 0x00, 0xff },
|
||||
{ 0x00d832, 0x00, 0xff },
|
||||
{ 0x80f985, state->ts_mode_serial, 0x01 },
|
||||
{ 0x80f986, state->ts_mode_parallel, 0x01 },
|
||||
{ 0x00d827, 0x00, 0xff },
|
||||
{ 0x00d829, 0x00, 0xff },
|
||||
};
|
||||
|
||||
/* program clock control */
|
||||
clock_cw = af9033_div(state->cfg.clock, 1000000ul, 19ul);
|
||||
buf[0] = (clock_cw >> 0) & 0xff;
|
||||
buf[1] = (clock_cw >> 8) & 0xff;
|
||||
buf[2] = (clock_cw >> 16) & 0xff;
|
||||
buf[3] = (clock_cw >> 24) & 0xff;
|
||||
|
||||
pr_debug("%s: clock=%d clock_cw=%08x\n", __func__, state->cfg.clock,
|
||||
clock_cw);
|
||||
|
||||
ret = af9033_wr_regs(state, 0x800025, buf, 4);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* program ADC control */
|
||||
for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
|
||||
if (clock_adc_lut[i].clock == state->cfg.clock)
|
||||
break;
|
||||
}
|
||||
|
||||
adc_cw = af9033_div(clock_adc_lut[i].adc, 1000000ul, 19ul);
|
||||
buf[0] = (adc_cw >> 0) & 0xff;
|
||||
buf[1] = (adc_cw >> 8) & 0xff;
|
||||
buf[2] = (adc_cw >> 16) & 0xff;
|
||||
|
||||
pr_debug("%s: adc=%d adc_cw=%06x\n", __func__, clock_adc_lut[i].adc,
|
||||
adc_cw);
|
||||
|
||||
ret = af9033_wr_regs(state, 0x80f1cd, buf, 3);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* program register table */
|
||||
for (i = 0; i < ARRAY_SIZE(tab); i++) {
|
||||
ret = af9033_wr_reg_mask(state, tab[i].reg, tab[i].val,
|
||||
tab[i].mask);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* settings for TS interface */
|
||||
if (state->cfg.ts_mode == AF9033_TS_MODE_USB) {
|
||||
ret = af9033_wr_reg_mask(state, 0x80f9a5, 0x00, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x01, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
} else {
|
||||
ret = af9033_wr_reg_mask(state, 0x80f990, 0x00, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x00, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* load OFSM settings */
|
||||
pr_debug("%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;
|
||||
}
|
||||
|
||||
/* load tuner specific settings */
|
||||
pr_debug("%s: load tuner specific settings\n",
|
||||
__func__);
|
||||
switch (state->cfg.tuner) {
|
||||
case AF9033_TUNER_TUA9001:
|
||||
len = ARRAY_SIZE(tuner_init_tua9001);
|
||||
init = tuner_init_tua9001;
|
||||
break;
|
||||
case AF9033_TUNER_FC0011:
|
||||
len = ARRAY_SIZE(tuner_init_fc0011);
|
||||
init = tuner_init_fc0011;
|
||||
break;
|
||||
case AF9033_TUNER_MXL5007T:
|
||||
len = ARRAY_SIZE(tuner_init_mxl5007t);
|
||||
init = tuner_init_mxl5007t;
|
||||
break;
|
||||
case AF9033_TUNER_TDA18218:
|
||||
len = ARRAY_SIZE(tuner_init_tda18218);
|
||||
init = tuner_init_tda18218;
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: unsupported tuner ID=%d\n", __func__,
|
||||
state->cfg.tuner);
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
ret = af9033_wr_reg(state, init[i].reg, init[i].val);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
state->bandwidth_hz = 0; /* force to program all parameters */
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret, i;
|
||||
u8 tmp;
|
||||
|
||||
ret = af9033_wr_reg(state, 0x80004c, 1);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg(state, 0x800000, 0);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
for (i = 100, tmp = 1; i && tmp; i--) {
|
||||
ret = af9033_rd_reg(state, 0x80004c, &tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
usleep_range(200, 10000);
|
||||
}
|
||||
|
||||
pr_debug("%s: loop=%d\n", __func__, i);
|
||||
|
||||
if (i == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = af9033_wr_reg_mask(state, 0x80fb24, 0x08, 0x08);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* prevent current leak (?) */
|
||||
if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
|
||||
/* enable parallel TS */
|
||||
ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg_mask(state, 0x00d916, 0x01, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_get_tune_settings(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_tune_settings *fesettings)
|
||||
{
|
||||
fesettings->min_delay_ms = 800;
|
||||
fesettings->step_size = 0;
|
||||
fesettings->max_drift = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af9033_set_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int ret, i, spec_inv;
|
||||
u8 tmp, buf[3], bandwidth_reg_val;
|
||||
u32 if_frequency, freq_cw, adc_freq;
|
||||
|
||||
pr_debug("%s: frequency=%d bandwidth_hz=%d\n", __func__, c->frequency,
|
||||
c->bandwidth_hz);
|
||||
|
||||
/* check bandwidth */
|
||||
switch (c->bandwidth_hz) {
|
||||
case 6000000:
|
||||
bandwidth_reg_val = 0x00;
|
||||
break;
|
||||
case 7000000:
|
||||
bandwidth_reg_val = 0x01;
|
||||
break;
|
||||
case 8000000:
|
||||
bandwidth_reg_val = 0x02;
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: invalid bandwidth_hz\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* program tuner */
|
||||
if (fe->ops.tuner_ops.set_params)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
|
||||
/* program CFOE coefficients */
|
||||
if (c->bandwidth_hz != state->bandwidth_hz) {
|
||||
for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
|
||||
if (coeff_lut[i].clock == state->cfg.clock &&
|
||||
coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = af9033_wr_regs(state, 0x800001,
|
||||
coeff_lut[i].val, sizeof(coeff_lut[i].val));
|
||||
}
|
||||
|
||||
/* program frequency control */
|
||||
if (c->bandwidth_hz != state->bandwidth_hz) {
|
||||
spec_inv = state->cfg.spec_inv ? -1 : 1;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
|
||||
if (clock_adc_lut[i].clock == state->cfg.clock)
|
||||
break;
|
||||
}
|
||||
adc_freq = clock_adc_lut[i].adc;
|
||||
|
||||
/* get used IF frequency */
|
||||
if (fe->ops.tuner_ops.get_if_frequency)
|
||||
fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
|
||||
else
|
||||
if_frequency = 0;
|
||||
|
||||
while (if_frequency > (adc_freq / 2))
|
||||
if_frequency -= adc_freq;
|
||||
|
||||
if (if_frequency >= 0)
|
||||
spec_inv *= -1;
|
||||
else
|
||||
if_frequency *= -1;
|
||||
|
||||
freq_cw = af9033_div(if_frequency, adc_freq, 23ul);
|
||||
|
||||
if (spec_inv == -1)
|
||||
freq_cw *= -1;
|
||||
|
||||
/* get adc multiplies */
|
||||
ret = af9033_rd_reg(state, 0x800045, &tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (tmp == 1)
|
||||
freq_cw /= 2;
|
||||
|
||||
buf[0] = (freq_cw >> 0) & 0xff;
|
||||
buf[1] = (freq_cw >> 8) & 0xff;
|
||||
buf[2] = (freq_cw >> 16) & 0x7f;
|
||||
ret = af9033_wr_regs(state, 0x800029, buf, 3);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
state->bandwidth_hz = c->bandwidth_hz;
|
||||
}
|
||||
|
||||
ret = af9033_wr_reg_mask(state, 0x80f904, bandwidth_reg_val, 0x03);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg(state, 0x800040, 0x00);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg(state, 0x800047, 0x00);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg_mask(state, 0x80f999, 0x00, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (c->frequency <= 230000000)
|
||||
tmp = 0x00; /* VHF */
|
||||
else
|
||||
tmp = 0x01; /* UHF */
|
||||
|
||||
ret = af9033_wr_reg(state, 0x80004b, tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg(state, 0x800000, 0x00);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int ret;
|
||||
u8 buf[8];
|
||||
|
||||
pr_debug("%s\n", __func__);
|
||||
|
||||
/* read all needed registers */
|
||||
ret = af9033_rd_regs(state, 0x80f900, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
switch ((buf[0] >> 0) & 3) {
|
||||
case 0:
|
||||
c->transmission_mode = TRANSMISSION_MODE_2K;
|
||||
break;
|
||||
case 1:
|
||||
c->transmission_mode = TRANSMISSION_MODE_8K;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((buf[1] >> 0) & 3) {
|
||||
case 0:
|
||||
c->guard_interval = GUARD_INTERVAL_1_32;
|
||||
break;
|
||||
case 1:
|
||||
c->guard_interval = GUARD_INTERVAL_1_16;
|
||||
break;
|
||||
case 2:
|
||||
c->guard_interval = GUARD_INTERVAL_1_8;
|
||||
break;
|
||||
case 3:
|
||||
c->guard_interval = GUARD_INTERVAL_1_4;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((buf[2] >> 0) & 7) {
|
||||
case 0:
|
||||
c->hierarchy = HIERARCHY_NONE;
|
||||
break;
|
||||
case 1:
|
||||
c->hierarchy = HIERARCHY_1;
|
||||
break;
|
||||
case 2:
|
||||
c->hierarchy = HIERARCHY_2;
|
||||
break;
|
||||
case 3:
|
||||
c->hierarchy = HIERARCHY_4;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((buf[3] >> 0) & 3) {
|
||||
case 0:
|
||||
c->modulation = QPSK;
|
||||
break;
|
||||
case 1:
|
||||
c->modulation = QAM_16;
|
||||
break;
|
||||
case 2:
|
||||
c->modulation = QAM_64;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((buf[4] >> 0) & 3) {
|
||||
case 0:
|
||||
c->bandwidth_hz = 6000000;
|
||||
break;
|
||||
case 1:
|
||||
c->bandwidth_hz = 7000000;
|
||||
break;
|
||||
case 2:
|
||||
c->bandwidth_hz = 8000000;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((buf[6] >> 0) & 7) {
|
||||
case 0:
|
||||
c->code_rate_HP = FEC_1_2;
|
||||
break;
|
||||
case 1:
|
||||
c->code_rate_HP = FEC_2_3;
|
||||
break;
|
||||
case 2:
|
||||
c->code_rate_HP = FEC_3_4;
|
||||
break;
|
||||
case 3:
|
||||
c->code_rate_HP = FEC_5_6;
|
||||
break;
|
||||
case 4:
|
||||
c->code_rate_HP = FEC_7_8;
|
||||
break;
|
||||
case 5:
|
||||
c->code_rate_HP = FEC_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((buf[7] >> 0) & 7) {
|
||||
case 0:
|
||||
c->code_rate_LP = FEC_1_2;
|
||||
break;
|
||||
case 1:
|
||||
c->code_rate_LP = FEC_2_3;
|
||||
break;
|
||||
case 2:
|
||||
c->code_rate_LP = FEC_3_4;
|
||||
break;
|
||||
case 3:
|
||||
c->code_rate_LP = FEC_5_6;
|
||||
break;
|
||||
case 4:
|
||||
c->code_rate_LP = FEC_7_8;
|
||||
break;
|
||||
case 5:
|
||||
c->code_rate_LP = FEC_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 tmp;
|
||||
|
||||
*status = 0;
|
||||
|
||||
/* radio channel status, 0=no result, 1=has signal, 2=no signal */
|
||||
ret = af9033_rd_reg(state, 0x800047, &tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* has signal */
|
||||
if (tmp == 0x01)
|
||||
*status |= FE_HAS_SIGNAL;
|
||||
|
||||
if (tmp != 0x02) {
|
||||
/* TPS lock */
|
||||
ret = af9033_rd_reg_mask(state, 0x80f5a9, &tmp, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (tmp)
|
||||
*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
|
||||
FE_HAS_VITERBI;
|
||||
|
||||
/* full lock */
|
||||
ret = af9033_rd_reg_mask(state, 0x80f999, &tmp, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (tmp)
|
||||
*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
|
||||
FE_HAS_VITERBI | FE_HAS_SYNC |
|
||||
FE_HAS_LOCK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret, i, len;
|
||||
u8 buf[3], tmp;
|
||||
u32 snr_val;
|
||||
const struct val_snr *uninitialized_var(snr_lut);
|
||||
|
||||
/* read value */
|
||||
ret = af9033_rd_regs(state, 0x80002c, buf, 3);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
/* read current modulation */
|
||||
ret = af9033_rd_reg(state, 0x80f903, &tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
switch ((tmp >> 0) & 3) {
|
||||
case 0:
|
||||
len = ARRAY_SIZE(qpsk_snr_lut);
|
||||
snr_lut = qpsk_snr_lut;
|
||||
break;
|
||||
case 1:
|
||||
len = ARRAY_SIZE(qam16_snr_lut);
|
||||
snr_lut = qam16_snr_lut;
|
||||
break;
|
||||
case 2:
|
||||
len = ARRAY_SIZE(qam64_snr_lut);
|
||||
snr_lut = qam64_snr_lut;
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
tmp = snr_lut[i].snr;
|
||||
|
||||
if (snr_val < snr_lut[i].val)
|
||||
break;
|
||||
}
|
||||
|
||||
*snr = tmp * 10; /* dB/10 */
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 strength2;
|
||||
|
||||
/* read signal strength of 0-100 scale */
|
||||
ret = af9033_rd_reg(state, 0x800048, &strength2);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* scale value to 0x0000-0xffff */
|
||||
*strength = strength2 * 0xffff / 100;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_update_ch_stat(struct af9033_state *state)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 err_cnt, bit_cnt;
|
||||
u16 abort_cnt;
|
||||
u8 buf[7];
|
||||
|
||||
/* only update data every half second */
|
||||
if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) {
|
||||
ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
/* in 8 byte packets? */
|
||||
abort_cnt = (buf[1] << 8) + buf[0];
|
||||
/* in bits */
|
||||
err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2];
|
||||
/* in 8 byte packets? always(?) 0x2710 = 10000 */
|
||||
bit_cnt = (buf[6] << 8) + buf[5];
|
||||
|
||||
if (bit_cnt < abort_cnt) {
|
||||
abort_cnt = 1000;
|
||||
state->ber = 0xffffffff;
|
||||
} else {
|
||||
/* 8 byte packets, that have not been rejected already */
|
||||
bit_cnt -= (u32)abort_cnt;
|
||||
if (bit_cnt == 0) {
|
||||
state->ber = 0xffffffff;
|
||||
} else {
|
||||
err_cnt -= (u32)abort_cnt * 8 * 8;
|
||||
bit_cnt *= 8 * 8;
|
||||
state->ber = err_cnt * (0xffffffff / bit_cnt);
|
||||
}
|
||||
}
|
||||
state->ucb += abort_cnt;
|
||||
state->last_stat_check = jiffies;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
|
||||
ret = af9033_update_ch_stat(state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*ber = state->ber;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
|
||||
ret = af9033_update_ch_stat(state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*ucblocks = state->ucb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
|
||||
pr_debug("%s: enable=%d\n", __func__, enable);
|
||||
|
||||
ret = af9033_wr_reg_mask(state, 0x00fa04, enable, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_debug("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops af9033_ops;
|
||||
|
||||
struct dvb_frontend *af9033_attach(const struct af9033_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
int ret;
|
||||
struct af9033_state *state;
|
||||
u8 buf[8];
|
||||
|
||||
pr_debug("%s:\n", __func__);
|
||||
|
||||
/* allocate memory for the internal state */
|
||||
state = kzalloc(sizeof(struct af9033_state), GFP_KERNEL);
|
||||
if (state == NULL)
|
||||
goto err;
|
||||
|
||||
/* setup the state */
|
||||
state->i2c = i2c;
|
||||
memcpy(&state->cfg, config, sizeof(struct af9033_config));
|
||||
|
||||
if (state->cfg.clock != 12000000) {
|
||||
printk(KERN_INFO "af9033: unsupported clock=%d, only " \
|
||||
"12000000 Hz is supported currently\n",
|
||||
state->cfg.clock);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* firmware version */
|
||||
ret = af9033_rd_regs(state, 0x0083e9, &buf[0], 4);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_rd_regs(state, 0x804191, &buf[4], 4);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
printk(KERN_INFO "af9033: firmware version: LINK=%d.%d.%d.%d " \
|
||||
"OFDM=%d.%d.%d.%d\n", buf[0], buf[1], buf[2], buf[3],
|
||||
buf[4], buf[5], buf[6], buf[7]);
|
||||
|
||||
/* configure internal TS mode */
|
||||
switch (state->cfg.ts_mode) {
|
||||
case AF9033_TS_MODE_PARALLEL:
|
||||
state->ts_mode_parallel = true;
|
||||
break;
|
||||
case AF9033_TS_MODE_SERIAL:
|
||||
state->ts_mode_serial = true;
|
||||
break;
|
||||
case AF9033_TS_MODE_USB:
|
||||
/* usb mode for AF9035 */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
|
||||
state->fe.demodulator_priv = state;
|
||||
|
||||
return &state->fe;
|
||||
|
||||
err:
|
||||
kfree(state);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(af9033_attach);
|
||||
|
||||
static struct dvb_frontend_ops af9033_ops = {
|
||||
.delsys = { SYS_DVBT },
|
||||
.info = {
|
||||
.name = "Afatech AF9033 (DVB-T)",
|
||||
.frequency_min = 174000000,
|
||||
.frequency_max = 862000000,
|
||||
.frequency_stepsize = 250000,
|
||||
.frequency_tolerance = 0,
|
||||
.caps = FE_CAN_FEC_1_2 |
|
||||
FE_CAN_FEC_2_3 |
|
||||
FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 |
|
||||
FE_CAN_FEC_7_8 |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK |
|
||||
FE_CAN_QAM_16 |
|
||||
FE_CAN_QAM_64 |
|
||||
FE_CAN_QAM_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||
FE_CAN_GUARD_INTERVAL_AUTO |
|
||||
FE_CAN_HIERARCHY_AUTO |
|
||||
FE_CAN_RECOVER |
|
||||
FE_CAN_MUTE_TS
|
||||
},
|
||||
|
||||
.release = af9033_release,
|
||||
|
||||
.init = af9033_init,
|
||||
.sleep = af9033_sleep,
|
||||
|
||||
.get_tune_settings = af9033_get_tune_settings,
|
||||
.set_frontend = af9033_set_frontend,
|
||||
.get_frontend = af9033_get_frontend,
|
||||
|
||||
.read_status = af9033_read_status,
|
||||
.read_snr = af9033_read_snr,
|
||||
.read_signal_strength = af9033_read_signal_strength,
|
||||
.read_ber = af9033_read_ber,
|
||||
.read_ucblocks = af9033_read_ucblocks,
|
||||
|
||||
.i2c_gate_ctrl = af9033_i2c_gate_ctrl,
|
||||
};
|
||||
|
||||
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
|
||||
MODULE_DESCRIPTION("Afatech AF9033 DVB-T demodulator driver");
|
||||
MODULE_LICENSE("GPL");
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue