mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 03:06:10 +00:00
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (116 commits) V4L/DVB (13698): pms: replace asm/uaccess.h to linux/uaccess.h V4L/DVB (13690): radio/si470x: #include <sched.h> V4L/DVB (13688): au8522: modify the attributes of local filter coefficients V4L/DVB (13687): cx231xx: use NULL when pointer is needed V4L/DVB: Davinci VPFE Capture: remove unused #include <linux/version.h> V4L/DVB (13685): Correct code taking the size of a pointer V4L/DVB (13684): Fix some cut-and-paste noise in dib0090.h V4L/DVB (13683): sanio-ms: clean up init, exit and id_table V4L/DVB (13682): dib8000: make some constant static V4L/DVB: lgs8gxx: Use shifts rather than multiply/divide when possible V4L/DVB (13680b): DocBook/media: create links for included sources V4L/DVB (13680a): DocBook/media: copy images after building HTML V4L/DVB (13678): Add support for yet another DvbWorld, TeVii and Prof USB devices V4L/DVB (13676): configurable IRQ mode on NetUP Dual DVB-S2 CI; IRQ from CAM processing (CI interface works faster) V4L/DVB (13674): stv090x: Add DiSEqC envelope mode V4L/DVB (13673): lnbp21: Implement 22 kHz tone control V4L/DVB (13671): sh_mobile_ceu_camera: Remove frame size page alignment V4L/DVB (13670): soc-camera: Add mt9t112 camera driver V4L/DVB (13669): tw9910: Add sync polarity support V4L/DVB (13668): tw9910: remove cropping ...
This commit is contained in:
commit
6a5df38f5f
227 changed files with 10404 additions and 4051 deletions
|
@ -32,10 +32,10 @@ PS_METHOD = $(prefer-db2x)
|
|||
|
||||
###
|
||||
# The targets that may be used.
|
||||
PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs media
|
||||
PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs xmldoclinks
|
||||
|
||||
BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
|
||||
xmldocs: $(BOOKS)
|
||||
xmldocs: $(BOOKS) xmldoclinks
|
||||
sgmldocs: xmldocs
|
||||
|
||||
PS := $(patsubst %.xml, %.ps, $(BOOKS))
|
||||
|
@ -45,15 +45,24 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
|
|||
pdfdocs: $(PDF)
|
||||
|
||||
HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
|
||||
htmldocs: media $(HTML)
|
||||
htmldocs: $(HTML)
|
||||
$(call build_main_index)
|
||||
$(call build_images)
|
||||
|
||||
MAN := $(patsubst %.xml, %.9, $(BOOKS))
|
||||
mandocs: $(MAN)
|
||||
|
||||
media:
|
||||
mkdir -p $(srctree)/Documentation/DocBook/media/
|
||||
cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(srctree)/Documentation/DocBook/media/
|
||||
build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
|
||||
cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/
|
||||
|
||||
xmldoclinks:
|
||||
ifneq ($(objtree),$(srctree))
|
||||
for dep in dvb media-entities.tmpl media-indices.tmpl v4l; do \
|
||||
rm -f $(objtree)/Documentation/DocBook/$$dep \
|
||||
&& ln -s $(srctree)/Documentation/DocBook/$$dep $(objtree)/Documentation/DocBook/ \
|
||||
|| exit; \
|
||||
done
|
||||
endif
|
||||
|
||||
installmandocs: mandocs
|
||||
mkdir -p /usr/local/man/man9/
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<!ENTITY VIDIOC-ENUMINPUT "<link linkend='vidioc-enuminput'><constant>VIDIOC_ENUMINPUT</constant></link>">
|
||||
<!ENTITY VIDIOC-ENUMOUTPUT "<link linkend='vidioc-enumoutput'><constant>VIDIOC_ENUMOUTPUT</constant></link>">
|
||||
<!ENTITY VIDIOC-ENUMSTD "<link linkend='vidioc-enumstd'><constant>VIDIOC_ENUMSTD</constant></link>">
|
||||
<!ENTITY VIDIOC-ENUM-DV-PRESETS "<link linkend='vidioc-enum-dv-presets'><constant>VIDIOC_ENUM_DV_PRESETS</constant></link>">
|
||||
<!ENTITY VIDIOC-ENUM-FMT "<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>">
|
||||
<!ENTITY VIDIOC-ENUM-FRAMEINTERVALS "<link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>">
|
||||
<!ENTITY VIDIOC-ENUM-FRAMESIZES "<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>">
|
||||
|
@ -30,6 +31,8 @@
|
|||
<!ENTITY VIDIOC-G-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_G_AUDOUT</constant></link>">
|
||||
<!ENTITY VIDIOC-G-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_G_CROP</constant></link>">
|
||||
<!ENTITY VIDIOC-G-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_G_CTRL</constant></link>">
|
||||
<!ENTITY VIDIOC-G-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_G_DV_PRESET</constant></link>">
|
||||
<!ENTITY VIDIOC-G-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_G_DV_TIMINGS</constant></link>">
|
||||
<!ENTITY VIDIOC-G-ENC-INDEX "<link linkend='vidioc-g-enc-index'><constant>VIDIOC_G_ENC_INDEX</constant></link>">
|
||||
<!ENTITY VIDIOC-G-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_G_EXT_CTRLS</constant></link>">
|
||||
<!ENTITY VIDIOC-G-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_G_FBUF</constant></link>">
|
||||
|
@ -53,6 +56,7 @@
|
|||
<!ENTITY VIDIOC-QUERYCTRL "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYCTRL</constant></link>">
|
||||
<!ENTITY VIDIOC-QUERYMENU "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYMENU</constant></link>">
|
||||
<!ENTITY VIDIOC-QUERYSTD "<link linkend='vidioc-querystd'><constant>VIDIOC_QUERYSTD</constant></link>">
|
||||
<!ENTITY VIDIOC-QUERY-DV-PRESET "<link linkend='vidioc-query-dv-preset'><constant>VIDIOC_QUERY_DV_PRESET</constant></link>">
|
||||
<!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>">
|
||||
<!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>">
|
||||
<!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>">
|
||||
|
@ -60,6 +64,8 @@
|
|||
<!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>">
|
||||
<!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
|
||||
<!ENTITY VIDIOC-S-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_S_CTRL</constant></link>">
|
||||
<!ENTITY VIDIOC-S-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_S_DV_PRESET</constant></link>">
|
||||
<!ENTITY VIDIOC-S-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_S_DV_TIMINGS</constant></link>">
|
||||
<!ENTITY VIDIOC-S-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_S_EXT_CTRLS</constant></link>">
|
||||
<!ENTITY VIDIOC-S-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_S_FBUF</constant></link>">
|
||||
<!ENTITY VIDIOC-S-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>">
|
||||
|
@ -118,6 +124,7 @@
|
|||
<!-- Structures -->
|
||||
<!ENTITY v4l2-audio "struct <link linkend='v4l2-audio'>v4l2_audio</link>">
|
||||
<!ENTITY v4l2-audioout "struct <link linkend='v4l2-audioout'>v4l2_audioout</link>">
|
||||
<!ENTITY v4l2-bt-timings "struct <link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>">
|
||||
<!ENTITY v4l2-buffer "struct <link linkend='v4l2-buffer'>v4l2_buffer</link>">
|
||||
<!ENTITY v4l2-capability "struct <link linkend='v4l2-capability'>v4l2_capability</link>">
|
||||
<!ENTITY v4l2-captureparm "struct <link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
|
||||
|
@ -128,6 +135,9 @@
|
|||
<!ENTITY v4l2-dbg-chip-ident "struct <link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link>">
|
||||
<!ENTITY v4l2-dbg-match "struct <link linkend='v4l2-dbg-match'>v4l2_dbg_match</link>">
|
||||
<!ENTITY v4l2-dbg-register "struct <link linkend='v4l2-dbg-register'>v4l2_dbg_register</link>">
|
||||
<!ENTITY v4l2-dv-enum-preset "struct <link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link>">
|
||||
<!ENTITY v4l2-dv-preset "struct <link linkend='v4l2-dv-preset'>v4l2_dv_preset</link>">
|
||||
<!ENTITY v4l2-dv-timings "struct <link linkend='v4l2-dv-timings'>v4l2_dv_timings</link>">
|
||||
<!ENTITY v4l2-enc-idx "struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
|
||||
<!ENTITY v4l2-enc-idx-entry "struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
|
||||
<!ENTITY v4l2-encoder-cmd "struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
|
||||
|
@ -243,6 +253,10 @@
|
|||
<!ENTITY sub-enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
|
||||
<!ENTITY sub-enuminput SYSTEM "v4l/vidioc-enuminput.xml">
|
||||
<!ENTITY sub-enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
|
||||
<!ENTITY sub-enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml">
|
||||
<!ENTITY sub-g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml">
|
||||
<!ENTITY sub-query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml">
|
||||
<!ENTITY sub-g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml">
|
||||
<!ENTITY sub-enumstd SYSTEM "v4l/vidioc-enumstd.xml">
|
||||
<!ENTITY sub-g-audio SYSTEM "v4l/vidioc-g-audio.xml">
|
||||
<!ENTITY sub-g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
|
||||
|
@ -333,6 +347,10 @@
|
|||
<!ENTITY enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
|
||||
<!ENTITY enuminput SYSTEM "v4l/vidioc-enuminput.xml">
|
||||
<!ENTITY enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
|
||||
<!ENTITY enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml">
|
||||
<!ENTITY g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml">
|
||||
<!ENTITY query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml">
|
||||
<!ENTITY g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml">
|
||||
<!ENTITY enumstd SYSTEM "v4l/vidioc-enumstd.xml">
|
||||
<!ENTITY g-audio SYSTEM "v4l/vidioc-g-audio.xml">
|
||||
<!ENTITY g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
<indexentry><primaryie>enum <link linkend='v4l2-preemphasis'>v4l2_preemphasis</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-audio'>v4l2_audio</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-audioout'>v4l2_audioout</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-bt-timings'>v4l2_bt_timings</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-buffer'>v4l2_buffer</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-capability'>v4l2_capability</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-captureparm'>v4l2_captureparm</link></primaryie></indexentry>
|
||||
|
@ -46,6 +47,9 @@
|
|||
<indexentry><primaryie>struct <link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-dbg-match'>v4l2_dbg_match</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-dbg-register'>v4l2_dbg_register</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-dv-preset'>v4l2_dv_preset</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-dv-timings'>v4l2_dv_timings</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link></primaryie></indexentry>
|
||||
<indexentry><primaryie>struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link></primaryie></indexentry>
|
||||
|
|
|
@ -716,6 +716,41 @@ if (-1 == ioctl (fd, &VIDIOC-S-STD;, &std_id)) {
|
|||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<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
|
||||
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 input and output: </para><itemizedlist>
|
||||
<listitem>
|
||||
<para>DV Presets: Digital Video (DV) presets. 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>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<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>
|
||||
<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;
|
||||
|
|
|
@ -2291,8 +2291,8 @@ was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structn
|
|||
<listitem>
|
||||
<para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
</orderedlist>
|
||||
</section>
|
||||
<section>
|
||||
<title>V4L2 in Linux 2.6.32</title>
|
||||
<orderedlist>
|
||||
|
@ -2322,8 +2322,16 @@ more information.</para>
|
|||
<listitem>
|
||||
<para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
</orderedlist>
|
||||
</section>
|
||||
<section>
|
||||
<title>V4L2 in Linux 2.6.33</title>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Added support for Digital Video timings in order to support HDTV receivers and transmitters.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="other">
|
||||
|
|
|
@ -74,6 +74,17 @@ Remote Controller chapter.</contrib>
|
|||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
|
||||
<author>
|
||||
<firstname>Muralidharan</firstname>
|
||||
<surname>Karicheri</surname>
|
||||
<contrib>Documented the Digital Video timings API.</contrib>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>m-karicheri2@ti.com</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
|
@ -89,7 +100,7 @@ Remote Controller chapter.</contrib>
|
|||
<year>2008</year>
|
||||
<year>2009</year>
|
||||
<holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
|
||||
Rubli, Andy Walls, Mauro Carvalho Chehab</holder>
|
||||
Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder>
|
||||
</copyright>
|
||||
<legalnotice>
|
||||
<para>Except when explicitly stated as GPL, programming examples within
|
||||
|
@ -102,6 +113,13 @@ structs, ioctls) must be noted in more detail in the history chapter
|
|||
(compat.sgml), along with the possible impact on existing drivers and
|
||||
applications. -->
|
||||
|
||||
<revision>
|
||||
<revnumber>2.6.33</revnumber>
|
||||
<date>2009-12-03</date>
|
||||
<authorinitials>mk</authorinitials>
|
||||
<revremark>Added documentation for the Digital Video timings API.</revremark>
|
||||
</revision>
|
||||
|
||||
<revision>
|
||||
<revnumber>2.6.32</revnumber>
|
||||
<date>2009-08-31</date>
|
||||
|
@ -355,7 +373,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||
</partinfo>
|
||||
|
||||
<title>Video for Linux Two API Specification</title>
|
||||
<subtitle>Revision 2.6.32</subtitle>
|
||||
<subtitle>Revision 2.6.33</subtitle>
|
||||
|
||||
<chapter id="common">
|
||||
&sub-common;
|
||||
|
@ -411,6 +429,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||
&sub-encoder-cmd;
|
||||
&sub-enumaudio;
|
||||
&sub-enumaudioout;
|
||||
&sub-enum-dv-presets;
|
||||
&sub-enum-fmt;
|
||||
&sub-enum-framesizes;
|
||||
&sub-enum-frameintervals;
|
||||
|
@ -421,6 +440,8 @@ and discussions on the V4L mailing list.</revremark>
|
|||
&sub-g-audioout;
|
||||
&sub-g-crop;
|
||||
&sub-g-ctrl;
|
||||
&sub-g-dv-preset;
|
||||
&sub-g-dv-timings;
|
||||
&sub-g-enc-index;
|
||||
&sub-g-ext-ctrls;
|
||||
&sub-g-fbuf;
|
||||
|
@ -441,6 +462,7 @@ and discussions on the V4L mailing list.</revremark>
|
|||
&sub-querybuf;
|
||||
&sub-querycap;
|
||||
&sub-queryctrl;
|
||||
&sub-query-dv-preset;
|
||||
&sub-querystd;
|
||||
&sub-reqbufs;
|
||||
&sub-s-hw-freq-seek;
|
||||
|
|
|
@ -733,6 +733,99 @@ struct <link linkend="v4l2-standard">v4l2_standard</link> {
|
|||
__u32 reserved[4];
|
||||
};
|
||||
|
||||
/*
|
||||
* V I D E O T I M I N G S D V P R E S E T
|
||||
*/
|
||||
struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link> {
|
||||
__u32 preset;
|
||||
__u32 reserved[4];
|
||||
};
|
||||
|
||||
/*
|
||||
* D V P R E S E T S E N U M E R A T I O N
|
||||
*/
|
||||
struct <link linkend="v4l2-dv-enum-preset">v4l2_dv_enum_preset</link> {
|
||||
__u32 index;
|
||||
__u32 preset;
|
||||
__u8 name[32]; /* Name of the preset timing */
|
||||
__u32 width;
|
||||
__u32 height;
|
||||
__u32 reserved[4];
|
||||
};
|
||||
|
||||
/*
|
||||
* D V P R E S E T V A L U E S
|
||||
*/
|
||||
#define V4L2_DV_INVALID 0
|
||||
#define V4L2_DV_480P59_94 1 /* BT.1362 */
|
||||
#define V4L2_DV_576P50 2 /* BT.1362 */
|
||||
#define V4L2_DV_720P24 3 /* SMPTE 296M */
|
||||
#define V4L2_DV_720P25 4 /* SMPTE 296M */
|
||||
#define V4L2_DV_720P30 5 /* SMPTE 296M */
|
||||
#define V4L2_DV_720P50 6 /* SMPTE 296M */
|
||||
#define V4L2_DV_720P59_94 7 /* SMPTE 274M */
|
||||
#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */
|
||||
#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */
|
||||
#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */
|
||||
#define V4L2_DV_1080I25 11 /* BT.1120 */
|
||||
#define V4L2_DV_1080I50 12 /* SMPTE 296M */
|
||||
#define V4L2_DV_1080I60 13 /* SMPTE 296M */
|
||||
#define V4L2_DV_1080P24 14 /* SMPTE 296M */
|
||||
#define V4L2_DV_1080P25 15 /* SMPTE 296M */
|
||||
#define V4L2_DV_1080P30 16 /* SMPTE 296M */
|
||||
#define V4L2_DV_1080P50 17 /* BT.1120 */
|
||||
#define V4L2_DV_1080P60 18 /* BT.1120 */
|
||||
|
||||
/*
|
||||
* D V B T T I M I N G S
|
||||
*/
|
||||
|
||||
/* BT.656/BT.1120 timing data */
|
||||
struct <link linkend="v4l2-bt-timings">v4l2_bt_timings</link> {
|
||||
__u32 width; /* width in pixels */
|
||||
__u32 height; /* height in lines */
|
||||
__u32 interlaced; /* Interlaced or progressive */
|
||||
__u32 polarities; /* Positive or negative polarity */
|
||||
__u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */
|
||||
__u32 hfrontporch; /* Horizpontal front porch in pixels */
|
||||
__u32 hsync; /* Horizontal Sync length in pixels */
|
||||
__u32 hbackporch; /* Horizontal back porch in pixels */
|
||||
__u32 vfrontporch; /* Vertical front porch in pixels */
|
||||
__u32 vsync; /* Vertical Sync length in lines */
|
||||
__u32 vbackporch; /* Vertical back porch in lines */
|
||||
__u32 il_vfrontporch; /* Vertical front porch for bottom field of
|
||||
* interlaced field formats
|
||||
*/
|
||||
__u32 il_vsync; /* Vertical sync length for bottom field of
|
||||
* interlaced field formats
|
||||
*/
|
||||
__u32 il_vbackporch; /* Vertical back porch for bottom field of
|
||||
* interlaced field formats
|
||||
*/
|
||||
__u32 reserved[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Interlaced or progressive format */
|
||||
#define V4L2_DV_PROGRESSIVE 0
|
||||
#define V4L2_DV_INTERLACED 1
|
||||
|
||||
/* Polarities. If bit is not set, it is assumed to be negative polarity */
|
||||
#define V4L2_DV_VSYNC_POS_POL 0x00000001
|
||||
#define V4L2_DV_HSYNC_POS_POL 0x00000002
|
||||
|
||||
|
||||
/* DV timings */
|
||||
struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link> {
|
||||
__u32 type;
|
||||
union {
|
||||
struct <link linkend="v4l2-bt-timings">v4l2_bt_timings</link> bt;
|
||||
__u32 reserved[32];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Values for the type field */
|
||||
#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */
|
||||
|
||||
/*
|
||||
* V I D E O I N P U T S
|
||||
*/
|
||||
|
@ -744,7 +837,8 @@ struct <link linkend="v4l2-input">v4l2_input</link> {
|
|||
__u32 tuner; /* Associated tuner */
|
||||
v4l2_std_id std;
|
||||
__u32 status;
|
||||
__u32 reserved[4];
|
||||
__u32 capabilities;
|
||||
__u32 reserved[3];
|
||||
};
|
||||
|
||||
/* Values for the 'type' field */
|
||||
|
@ -775,6 +869,11 @@ struct <link linkend="v4l2-input">v4l2_input</link> {
|
|||
#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
|
||||
#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
|
||||
|
||||
/* capabilities flags */
|
||||
#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */
|
||||
#define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */
|
||||
#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */
|
||||
|
||||
/*
|
||||
* V I D E O O U T P U T S
|
||||
*/
|
||||
|
@ -785,13 +884,19 @@ struct <link linkend="v4l2-output">v4l2_output</link> {
|
|||
__u32 audioset; /* Associated audios (bitfield) */
|
||||
__u32 modulator; /* Associated modulator */
|
||||
v4l2_std_id std;
|
||||
__u32 reserved[4];
|
||||
__u32 capabilities;
|
||||
__u32 reserved[3];
|
||||
};
|
||||
/* Values for the 'type' field */
|
||||
#define V4L2_OUTPUT_TYPE_MODULATOR 1
|
||||
#define V4L2_OUTPUT_TYPE_ANALOG 2
|
||||
#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
|
||||
|
||||
/* capabilities flags */
|
||||
#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */
|
||||
#define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */
|
||||
#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */
|
||||
|
||||
/*
|
||||
* C O N T R O L S
|
||||
*/
|
||||
|
@ -1626,6 +1731,13 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
|
|||
#endif
|
||||
|
||||
#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link>)
|
||||
#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct <link linkend="v4l2-dv-enum-preset">v4l2_dv_enum_preset</link>)
|
||||
#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
|
||||
#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
|
||||
#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>)
|
||||
#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>)
|
||||
#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>)
|
||||
|
||||
/* Reminder: when adding new ioctls please add support for them to
|
||||
drivers/media/video/v4l2-compat-ioctl32.c as well! */
|
||||
|
||||
|
|
238
Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml
Normal file
238
Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml
Normal file
|
@ -0,0 +1,238 @@
|
|||
<refentry id="vidioc-enum-dv-presets">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_ENUM_DV_PRESETS</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>VIDIOC_ENUM_DV_PRESETS</refname>
|
||||
<refpurpose>Enumerate supported Digital Video presets</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<funcsynopsis>
|
||||
<funcprototype>
|
||||
<funcdef>int <function>ioctl</function></funcdef>
|
||||
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||
<paramdef>int <parameter>request</parameter></paramdef>
|
||||
<paramdef>struct v4l2_dv_enum_preset *<parameter>argp</parameter></paramdef>
|
||||
</funcprototype>
|
||||
</funcsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Arguments</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><parameter>fd</parameter></term>
|
||||
<listitem>
|
||||
<para>&fd;</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><parameter>request</parameter></term>
|
||||
<listitem>
|
||||
<para>VIDIOC_ENUM_DV_PRESETS</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><parameter>argp</parameter></term>
|
||||
<listitem>
|
||||
<para></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>To query the attributes of a DV preset, applications initialize the
|
||||
<structfield>index</structfield> field and zero the reserved array of &v4l2-dv-enum-preset;
|
||||
and call the <constant>VIDIOC_ENUM_DV_PRESETS</constant> ioctl with a pointer to this
|
||||
structure. Drivers fill the rest of the structure or return an
|
||||
&EINVAL; when the index is out of bounds. To enumerate all DV Presets supported,
|
||||
applications shall begin at index zero, incrementing by one until the
|
||||
driver returns <errorcode>EINVAL</errorcode>. Drivers may enumerate a
|
||||
different set of DV presets after switching the video input or
|
||||
output.</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-dv-enum-preset">
|
||||
<title>struct <structname>v4l2_dv_enum_presets</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>index</structfield></entry>
|
||||
<entry>Number of the DV preset, set by the
|
||||
application.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>preset</structfield></entry>
|
||||
<entry>This field identifies one of the DV preset values listed in <xref linkend="v4l2-dv-presets-vals"/>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u8</entry>
|
||||
<entry><structfield>name</structfield>[24]</entry>
|
||||
<entry>Name of the preset, a NUL-terminated ASCII string, for example: "720P-60", "1080I-60". This information is
|
||||
intended for the user.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>width</structfield></entry>
|
||||
<entry>Width of the active video in pixels for the DV preset.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>height</structfield></entry>
|
||||
<entry>Height of the active video in lines for the DV preset.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved</structfield>[4]</entry>
|
||||
<entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-dv-presets-vals">
|
||||
<title>struct <structname>DV Presets</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>Preset</entry>
|
||||
<entry>Preset value</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_INVALID</entry>
|
||||
<entry>0</entry>
|
||||
<entry>Invalid preset value.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_480P59_94</entry>
|
||||
<entry>1</entry>
|
||||
<entry>720x480 progressive video at 59.94 fps as per BT.1362.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_576P50</entry>
|
||||
<entry>2</entry>
|
||||
<entry>720x576 progressive video at 50 fps as per BT.1362.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_720P24</entry>
|
||||
<entry>3</entry>
|
||||
<entry>1280x720 progressive video at 24 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_720P25</entry>
|
||||
<entry>4</entry>
|
||||
<entry>1280x720 progressive video at 25 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_720P30</entry>
|
||||
<entry>5</entry>
|
||||
<entry>1280x720 progressive video at 30 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_720P50</entry>
|
||||
<entry>6</entry>
|
||||
<entry>1280x720 progressive video at 50 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_720P59_94</entry>
|
||||
<entry>7</entry>
|
||||
<entry>1280x720 progressive video at 59.94 fps as per SMPTE 274M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_720P60</entry>
|
||||
<entry>8</entry>
|
||||
<entry>1280x720 progressive video at 60 fps as per SMPTE 274M/296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080I29_97</entry>
|
||||
<entry>9</entry>
|
||||
<entry>1920x1080 interlaced video at 29.97 fps as per BT.1120/SMPTE 274M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080I30</entry>
|
||||
<entry>10</entry>
|
||||
<entry>1920x1080 interlaced video at 30 fps as per BT.1120/SMPTE 274M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080I25</entry>
|
||||
<entry>11</entry>
|
||||
<entry>1920x1080 interlaced video at 25 fps as per BT.1120.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080I50</entry>
|
||||
<entry>12</entry>
|
||||
<entry>1920x1080 interlaced video at 50 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080I60</entry>
|
||||
<entry>13</entry>
|
||||
<entry>1920x1080 interlaced video at 60 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080P24</entry>
|
||||
<entry>14</entry>
|
||||
<entry>1920x1080 progressive video at 24 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080P25</entry>
|
||||
<entry>15</entry>
|
||||
<entry>1920x1080 progressive video at 25 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080P30</entry>
|
||||
<entry>16</entry>
|
||||
<entry>1920x1080 progressive video at 30 fps as per SMPTE 296M.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080P50</entry>
|
||||
<entry>17</entry>
|
||||
<entry>1920x1080 progressive video at 50 fps as per BT.1120.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_1080P60</entry>
|
||||
<entry>18</entry>
|
||||
<entry>1920x1080 progressive video at 60 fps as per BT.1120.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
&return-value;
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><errorcode>EINVAL</errorcode></term>
|
||||
<listitem>
|
||||
<para>The &v4l2-dv-enum-preset; <structfield>index</structfield>
|
||||
is out of bounds.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: "v4l2.sgml"
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
-->
|
|
@ -124,7 +124,13 @@ current input.</entry>
|
|||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved</structfield>[4]</entry>
|
||||
<entry><structfield>capabilities</structfield></entry>
|
||||
<entry>This field provides capabilities for the
|
||||
input. See <xref linkend="input-capabilities" /> for flags.</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>
|
||||
|
@ -261,6 +267,34 @@ flag is set Macrovision has been detected.</entry>
|
|||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<!-- Capability flags based on video timings RFC by Muralidharan
|
||||
Karicheri, titled RFC (v1.2): V4L - Support for video timings at the
|
||||
input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
|
||||
-->
|
||||
<table frame="none" pgwide="1" id="input-capabilities">
|
||||
<title>Input capabilities</title>
|
||||
<tgroup cols="3">
|
||||
&cs-def;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_IN_CAP_PRESETS</constant></entry>
|
||||
<entry>0x00000001</entry>
|
||||
<entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
|
||||
<entry>0x00000002</entry>
|
||||
<entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_IN_CAP_STD</constant></entry>
|
||||
<entry>0x00000004</entry>
|
||||
<entry>This input supports setting the TV standard by using VIDIOC_S_STD.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
|
|
@ -114,7 +114,13 @@ details on video standards and how to switch see <xref
|
|||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved</structfield>[4]</entry>
|
||||
<entry><structfield>capabilities</structfield></entry>
|
||||
<entry>This field provides capabilities for the
|
||||
output. See <xref linkend="output-capabilities" /> for flags.</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>
|
||||
|
@ -147,6 +153,34 @@ CVBS, S-Video, RGB.</entry>
|
|||
</tgroup>
|
||||
</table>
|
||||
|
||||
<!-- Capabilities flags based on video timings RFC by Muralidharan
|
||||
Karicheri, titled RFC (v1.2): V4L - Support for video timings at the
|
||||
input/output interface to linux-media@vger.kernel.org on 19 Oct 2009.
|
||||
-->
|
||||
<table frame="none" pgwide="1" id="output-capabilities">
|
||||
<title>Output capabilities</title>
|
||||
<tgroup cols="3">
|
||||
&cs-def;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_OUT_CAP_PRESETS</constant></entry>
|
||||
<entry>0x00000001</entry>
|
||||
<entry>This output supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry>
|
||||
<entry>0x00000002</entry>
|
||||
<entry>This output supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_OUT_CAP_STD</constant></entry>
|
||||
<entry>0x00000004</entry>
|
||||
<entry>This output supports setting the TV standard by using VIDIOC_S_STD.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
&return-value;
|
||||
|
|
111
Documentation/DocBook/v4l/vidioc-g-dv-preset.xml
Normal file
111
Documentation/DocBook/v4l/vidioc-g-dv-preset.xml
Normal file
|
@ -0,0 +1,111 @@
|
|||
<refentry id="vidioc-g-dv-preset">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>VIDIOC_G_DV_PRESET</refname>
|
||||
<refname>VIDIOC_S_DV_PRESET</refname>
|
||||
<refpurpose>Query or select the DV preset of the current input or output</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<funcsynopsis>
|
||||
<funcprototype>
|
||||
<funcdef>int <function>ioctl</function></funcdef>
|
||||
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||
<paramdef>int <parameter>request</parameter></paramdef>
|
||||
<paramdef>&v4l2-dv-preset;
|
||||
*<parameter>argp</parameter></paramdef>
|
||||
</funcprototype>
|
||||
</funcsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Arguments</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><parameter>fd</parameter></term>
|
||||
<listitem>
|
||||
<para>&fd;</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><parameter>request</parameter></term>
|
||||
<listitem>
|
||||
<para>VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><parameter>argp</parameter></term>
|
||||
<listitem>
|
||||
<para></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
<para>To query and select the current DV preset, applications
|
||||
use the <constant>VIDIOC_G_DV_PRESET</constant> and <constant>VIDIOC_S_DV_PRESET</constant>
|
||||
ioctls which take a pointer to a &v4l2-dv-preset; type as argument.
|
||||
Applications must zero the reserved array in &v4l2-dv-preset;.
|
||||
<constant>VIDIOC_G_DV_PRESET</constant> returns a dv preset in the field
|
||||
<structfield>preset</structfield> of &v4l2-dv-preset;.</para>
|
||||
|
||||
<para><constant>VIDIOC_S_DV_PRESET</constant> accepts a pointer to a &v4l2-dv-preset;
|
||||
that has the preset value to be set. Applications must zero the reserved array in &v4l2-dv-preset;.
|
||||
If the preset is not supported, it returns an &EINVAL; </para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
&return-value;
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><errorcode>EINVAL</errorcode></term>
|
||||
<listitem>
|
||||
<para>This ioctl is not supported, or the
|
||||
<constant>VIDIOC_S_DV_PRESET</constant>,<constant>VIDIOC_S_DV_PRESET</constant> parameter was unsuitable.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><errorcode>EBUSY</errorcode></term>
|
||||
<listitem>
|
||||
<para>The device is busy and therefore can not change the preset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-dv-preset">
|
||||
<title>struct <structname>v4l2_dv_preset</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>preset</structfield></entry>
|
||||
<entry>Preset value to represent the digital video timings</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved[4]</structfield></entry>
|
||||
<entry>Reserved fields for future use</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: "v4l2.sgml"
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
-->
|
224
Documentation/DocBook/v4l/vidioc-g-dv-timings.xml
Normal file
224
Documentation/DocBook/v4l/vidioc-g-dv-timings.xml
Normal file
|
@ -0,0 +1,224 @@
|
|||
<refentry id="vidioc-g-dv-timings">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<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>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<funcsynopsis>
|
||||
<funcprototype>
|
||||
<funcdef>int <function>ioctl</function></funcdef>
|
||||
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||
<paramdef>int <parameter>request</parameter></paramdef>
|
||||
<paramdef>&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_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><parameter>argp</parameter></term>
|
||||
<listitem>
|
||||
<para></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<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,
|
||||
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>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
&return-value;
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><errorcode>EINVAL</errorcode></term>
|
||||
<listitem>
|
||||
<para>This ioctl is not supported, or the
|
||||
<constant>VIDIOC_S_DV_TIMINGS</constant> parameter was unsuitable.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><errorcode>EBUSY</errorcode></term>
|
||||
<listitem>
|
||||
<para>The device is busy and therefore can not change the timings.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-bt-timings">
|
||||
<title>struct <structname>v4l2_bt_timings</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>width</structfield></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>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>interlaced</structfield></entry>
|
||||
<entry>Progressive (0) or interlaced (1)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>polarities</structfield></entry>
|
||||
<entry>This is a bit mask that defines polarities of sync signals.
|
||||
bit 0 (V4L2_DV_VSYNC_POS_POL) is for vertical sync polarity and bit 1 (V4L2_DV_HSYNC_POS_POL) is for horizontal sync polarity. If the bit is set
|
||||
(1) it is positive polarity and if is cleared (0), it is negative polarity.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u64</entry>
|
||||
<entry><structfield>pixelclock</structfield></entry>
|
||||
<entry>Pixel clock in Hz. Ex. 74.25MHz->74250000</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>hfrontporch</structfield></entry>
|
||||
<entry>Horizontal front porch in pixels</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>hsync</structfield></entry>
|
||||
<entry>Horizontal sync length in pixels</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>hbackporch</structfield></entry>
|
||||
<entry>Horizontal back porch in pixels</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>vfrontporch</structfield></entry>
|
||||
<entry>Vertical front porch in lines</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>vsync</structfield></entry>
|
||||
<entry>Vertical sync length in lines</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>vbackporch</structfield></entry>
|
||||
<entry>Vertical back porch in lines</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>
|
||||
</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>
|
||||
</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>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-dv-timings">
|
||||
<title>struct <structname>v4l2_dv_timings</structname></title>
|
||||
<tgroup cols="4">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>type</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>Type of DV timings as listed in <xref linkend="dv-timing-types"/>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>union</entry>
|
||||
<entry><structfield></structfield></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>&v4l2-bt-timings;</entry>
|
||||
<entry><structfield>bt</structfield></entry>
|
||||
<entry>Timings defined by BT.656/1120 specifications</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>reserved</structfield>[32]</entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table pgwide="1" frame="none" id="dv-timing-types">
|
||||
<title>DV Timing types</title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>Timing type</entry>
|
||||
<entry>value</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>V4L2_DV_BT_656_1120</entry>
|
||||
<entry>0</entry>
|
||||
<entry>BT.656/1120 timings</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: "v4l2.sgml"
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
-->
|
|
@ -86,6 +86,12 @@ standards.</para>
|
|||
<constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><errorcode>EBUSY</errorcode></term>
|
||||
<listitem>
|
||||
<para>The device is busy and therefore can not change the standard</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
|
85
Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
Normal file
85
Documentation/DocBook/v4l/vidioc-query-dv-preset.xml
Normal file
|
@ -0,0 +1,85 @@
|
|||
<refentry id="vidioc-query-dv-preset">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_QUERY_DV_PRESET</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>VIDIOC_QUERY_DV_PRESET</refname>
|
||||
<refpurpose>Sense the DV preset received by the current
|
||||
input</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<funcsynopsis>
|
||||
<funcprototype>
|
||||
<funcdef>int <function>ioctl</function></funcdef>
|
||||
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||
<paramdef>int <parameter>request</parameter></paramdef>
|
||||
<paramdef>&v4l2-dv-preset; *<parameter>argp</parameter></paramdef>
|
||||
</funcprototype>
|
||||
</funcsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Arguments</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><parameter>fd</parameter></term>
|
||||
<listitem>
|
||||
<para>&fd;</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><parameter>request</parameter></term>
|
||||
<listitem>
|
||||
<para>VIDIOC_QUERY_DV_PRESET</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><parameter>argp</parameter></term>
|
||||
<listitem>
|
||||
<para></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>The hardware may be able to detect the current DV preset
|
||||
automatically, similar to sensing the video standard. To do so, applications
|
||||
call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a
|
||||
&v4l2-dv-preset; type. Once the hardware detects a preset, that preset is
|
||||
returned in the preset field of &v4l2-dv-preset;. When detection is not
|
||||
possible or fails, the value V4L2_DV_INVALID is returned.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
&return-value;
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><errorcode>EINVAL</errorcode></term>
|
||||
<listitem>
|
||||
<para>This ioctl is not supported.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><errorcode>EBUSY</errorcode></term>
|
||||
<listitem>
|
||||
<para>The device is busy and therefore can not sense the preset</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-parent-document: "v4l2.sgml"
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
-->
|
|
@ -70,6 +70,12 @@ current video input or output.</para>
|
|||
<para>This ioctl is not supported.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><errorcode>EBUSY</errorcode></term>
|
||||
<listitem>
|
||||
<para>The device is busy and therefore can not detect the standard</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
|
|
@ -12,6 +12,7 @@ m5602 0402:5602 ALi Video Camera Controller
|
|||
spca501 040a:0002 Kodak DVC-325
|
||||
spca500 040a:0300 Kodak EZ200
|
||||
zc3xx 041e:041e Creative WebCam Live!
|
||||
ov519 041e:4003 Video Blaster WebCam Go Plus
|
||||
spca500 041e:400a Creative PC-CAM 300
|
||||
sunplus 041e:400b Creative PC-CAM 600
|
||||
sunplus 041e:4012 PC-Cam350
|
||||
|
@ -168,10 +169,14 @@ sunplus 055f:c650 Mustek MDC5500Z
|
|||
zc3xx 055f:d003 Mustek WCam300A
|
||||
zc3xx 055f:d004 Mustek WCam300 AN
|
||||
conex 0572:0041 Creative Notebook cx11646
|
||||
ov519 05a9:0511 Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera
|
||||
ov519 05a9:0518 Creative WebCam
|
||||
ov519 05a9:0519 OV519 Microphone
|
||||
ov519 05a9:0530 OmniVision
|
||||
ov519 05a9:2800 OmniVision SuperCAM
|
||||
ov519 05a9:4519 Webcam Classic
|
||||
ov519 05a9:8519 OmniVision
|
||||
ov519 05a9:a511 D-Link USB Digital Video Camera
|
||||
ov519 05a9:a518 D-Link DSB-C310 Webcam
|
||||
sunplus 05da:1018 Digital Dream Enigma 1.3
|
||||
stk014 05e1:0893 Syntek DV4000
|
||||
|
@ -187,7 +192,7 @@ ov534 06f8:3002 Hercules Blog Webcam
|
|||
ov534 06f8:3003 Hercules Dualpix HD Weblog
|
||||
sonixj 06f8:3004 Hercules Classic Silver
|
||||
sonixj 06f8:3008 Hercules Deluxe Optical Glass
|
||||
pac7311 06f8:3009 Hercules Classic Link
|
||||
pac7302 06f8:3009 Hercules Classic Link
|
||||
spca508 0733:0110 ViewQuest VQ110
|
||||
spca501 0733:0401 Intel Create and Share
|
||||
spca501 0733:0402 ViewQuest M318B
|
||||
|
@ -199,6 +204,7 @@ sunplus 0733:2221 Mercury Digital Pro 3.1p
|
|||
sunplus 0733:3261 Concord 3045 spca536a
|
||||
sunplus 0733:3281 Cyberpix S550V
|
||||
spca506 0734:043b 3DeMon USB Capture aka
|
||||
ov519 0813:0002 Dual Mode USB Camera Plus
|
||||
spca500 084d:0003 D-Link DSC-350
|
||||
spca500 08ca:0103 Aiptek PocketDV
|
||||
sunplus 08ca:0104 Aiptek PocketDVII 1.3
|
||||
|
@ -236,15 +242,15 @@ pac7311 093a:2603 Philips SPC 500 NC
|
|||
pac7311 093a:2608 Trust WB-3300p
|
||||
pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
|
||||
pac7311 093a:260f SnakeCam
|
||||
pac7311 093a:2620 Apollo AC-905
|
||||
pac7311 093a:2621 PAC731x
|
||||
pac7311 093a:2622 Genius Eye 312
|
||||
pac7311 093a:2624 PAC7302
|
||||
pac7311 093a:2626 Labtec 2200
|
||||
pac7311 093a:2628 Genius iLook 300
|
||||
pac7311 093a:2629 Genious iSlim 300
|
||||
pac7311 093a:262a Webcam 300k
|
||||
pac7311 093a:262c Philips SPC 230 NC
|
||||
pac7302 093a:2620 Apollo AC-905
|
||||
pac7302 093a:2621 PAC731x
|
||||
pac7302 093a:2622 Genius Eye 312
|
||||
pac7302 093a:2624 PAC7302
|
||||
pac7302 093a:2626 Labtec 2200
|
||||
pac7302 093a:2628 Genius iLook 300
|
||||
pac7302 093a:2629 Genious iSlim 300
|
||||
pac7302 093a:262a Webcam 300k
|
||||
pac7302 093a:262c Philips SPC 230 NC
|
||||
jeilinj 0979:0280 Sakar 57379
|
||||
zc3xx 0ac8:0302 Z-star Vimicro zc0302
|
||||
vc032x 0ac8:0321 Vimicro generic vc0321
|
||||
|
@ -259,6 +265,7 @@ vc032x 0ac8:c002 Sony embedded vimicro
|
|||
vc032x 0ac8:c301 Samsung Q1 Ultra Premium
|
||||
spca508 0af9:0010 Hama USB Sightcam 100
|
||||
spca508 0af9:0011 Hama USB Sightcam 100
|
||||
ov519 0b62:0059 iBOT2 Webcam
|
||||
sonixb 0c45:6001 Genius VideoCAM NB
|
||||
sonixb 0c45:6005 Microdia Sweex Mini Webcam
|
||||
sonixb 0c45:6007 Sonix sn9c101 + Tas5110D
|
||||
|
@ -318,8 +325,10 @@ sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655)
|
|||
sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660)
|
||||
sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R)
|
||||
sunplus 0d64:0303 Sunplus FashionCam DXG
|
||||
ov519 0e96:c001 TRUST 380 USB2 SPACEC@M
|
||||
etoms 102c:6151 Qcam Sangha CIF
|
||||
etoms 102c:6251 Qcam xxxxxx VGA
|
||||
ov519 1046:9967 W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go
|
||||
zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
|
||||
spca561 10fd:7e50 FlyCam Usb 100
|
||||
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
|
||||
|
@ -332,7 +341,12 @@ spca501 1776:501c Arowana 300K CMOS Camera
|
|||
t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
|
||||
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
|
||||
pac207 2001:f115 D-Link DSB-C120
|
||||
sq905c 2770:9050 sq905c
|
||||
sq905c 2770:905c DualCamera
|
||||
sq905 2770:9120 Argus Digital Camera DC1512
|
||||
sq905c 2770:913d sq905c
|
||||
spca500 2899:012c Toptro Industrial
|
||||
ov519 8020:ef04 ov519
|
||||
spca508 8086:0110 Intel Easy PC Camera
|
||||
spca500 8086:0630 Intel Pocket PC Camera
|
||||
spca506 99fa:8988 Grandtec V.cap
|
||||
|
|
157
Documentation/video4linux/sh_mobile_ceu_camera.txt
Normal file
157
Documentation/video4linux/sh_mobile_ceu_camera.txt
Normal file
|
@ -0,0 +1,157 @@
|
|||
Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
|
||||
=======================================================================
|
||||
|
||||
Terminology
|
||||
-----------
|
||||
|
||||
sensor scales: horizontal and vertical scales, configured by the sensor driver
|
||||
host scales: -"- host driver
|
||||
combined scales: sensor_scale * host_scale
|
||||
|
||||
|
||||
Generic scaling / cropping scheme
|
||||
---------------------------------
|
||||
|
||||
-1--
|
||||
|
|
||||
-2-- -\
|
||||
| --\
|
||||
| --\
|
||||
+-5-- -\ -- -3--
|
||||
| ---\
|
||||
| --- -4-- -\
|
||||
| -\
|
||||
| - -6--
|
||||
|
|
||||
| - -6'-
|
||||
| -/
|
||||
| --- -4'- -/
|
||||
| ---/
|
||||
+-5'- -/
|
||||
| -- -3'-
|
||||
| --/
|
||||
| --/
|
||||
-2'- -/
|
||||
|
|
||||
|
|
||||
-1'-
|
||||
|
||||
Produced by user requests:
|
||||
|
||||
S_CROP(left / top = (5) - (1), width / height = (5') - (5))
|
||||
S_FMT(width / height = (6') - (6))
|
||||
|
||||
Here:
|
||||
|
||||
(1) to (1') - whole max width or height
|
||||
(1) to (2) - sensor cropped left or top
|
||||
(2) to (2') - sensor cropped width or height
|
||||
(3) to (3') - sensor scale
|
||||
(3) to (4) - CEU cropped left or top
|
||||
(4) to (4') - CEU cropped width or height
|
||||
(5) to (5') - reverse sensor scale applied to CEU cropped width or height
|
||||
(2) to (5) - reverse sensor scale applied to CEU cropped left or top
|
||||
(6) to (6') - CEU scale - user window
|
||||
|
||||
|
||||
S_FMT
|
||||
-----
|
||||
|
||||
Do not touch input rectangle - it is already optimal.
|
||||
|
||||
1. Calculate current sensor scales:
|
||||
|
||||
scale_s = ((3') - (3)) / ((2') - (2))
|
||||
|
||||
2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
|
||||
current sensor scales onto input window - this is user S_CROP:
|
||||
|
||||
width_u = (5') - (5) = ((4') - (4)) * scale_s
|
||||
|
||||
3. Calculate new combined scales from "effective" input window to requested user
|
||||
window:
|
||||
|
||||
scale_comb = width_u / ((6') - (6))
|
||||
|
||||
4. Calculate sensor output window by applying combined scales to real input
|
||||
window:
|
||||
|
||||
width_s_out = ((2') - (2)) / scale_comb
|
||||
|
||||
5. Apply iterative sensor S_FMT for sensor output window.
|
||||
|
||||
subdev->video_ops->s_fmt(.width = width_s_out)
|
||||
|
||||
6. Retrieve sensor output window (g_fmt)
|
||||
|
||||
7. Calculate new sensor scales:
|
||||
|
||||
scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
|
||||
|
||||
8. Calculate new CEU crop - apply sensor scales to previously calculated
|
||||
"effective" crop:
|
||||
|
||||
width_ceu = (4')_new - (4)_new = width_u / scale_s_new
|
||||
left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
|
||||
|
||||
9. Use CEU cropping to crop to the new window:
|
||||
|
||||
ceu_crop(.width = width_ceu, .left = left_ceu)
|
||||
|
||||
10. Use CEU scaling to scale to the requested user window:
|
||||
|
||||
scale_ceu = width_ceu / width
|
||||
|
||||
|
||||
S_CROP
|
||||
------
|
||||
|
||||
If old scale applied to new crop is invalid produce nearest new scale possible
|
||||
|
||||
1. Calculate current combined scales.
|
||||
|
||||
scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3)))
|
||||
|
||||
2. Apply iterative sensor S_CROP for new input window.
|
||||
|
||||
3. If old combined scales applied to new crop produce an impossible user window,
|
||||
adjust scales to produce nearest possible window.
|
||||
|
||||
width_u_out = ((5') - (5)) / scale_comb
|
||||
|
||||
if (width_u_out > max)
|
||||
scale_comb = ((5') - (5)) / max;
|
||||
else if (width_u_out < min)
|
||||
scale_comb = ((5') - (5)) / min;
|
||||
|
||||
4. Issue G_CROP to retrieve actual input window.
|
||||
|
||||
5. Using actual input window and calculated combined scales calculate sensor
|
||||
target output window.
|
||||
|
||||
width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb
|
||||
|
||||
6. Apply iterative S_FMT for new sensor target output window.
|
||||
|
||||
7. Issue G_FMT to retrieve the actual sensor output window.
|
||||
|
||||
8. Calculate sensor scales.
|
||||
|
||||
scale_s = ((3') - (3)) / ((2') - (2))
|
||||
|
||||
9. Calculate sensor output subwindow to be cropped on CEU by applying sensor
|
||||
scales to the requested window.
|
||||
|
||||
width_ceu = ((5') - (5)) / scale_s
|
||||
|
||||
10. Use CEU cropping for above calculated window.
|
||||
|
||||
11. Calculate CEU scales from sensor scales from results of (10) and user window
|
||||
from (3)
|
||||
|
||||
scale_ceu = calc_scale(((5') - (5)), &width_u_out)
|
||||
|
||||
12. Apply CEU scales.
|
||||
|
||||
--
|
||||
Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
|
@ -561,6 +561,8 @@ video_device helper functions
|
|||
|
||||
There are a few useful helper functions:
|
||||
|
||||
- file/video_device private data
|
||||
|
||||
You can set/get driver private data in the video_device struct using:
|
||||
|
||||
void *video_get_drvdata(struct video_device *vdev);
|
||||
|
@ -575,8 +577,7 @@ struct video_device *video_devdata(struct file *file);
|
|||
|
||||
returns the video_device belonging to the file struct.
|
||||
|
||||
The final helper function combines video_get_drvdata with
|
||||
video_devdata:
|
||||
The video_drvdata function combines video_get_drvdata with video_devdata:
|
||||
|
||||
void *video_drvdata(struct file *file);
|
||||
|
||||
|
@ -584,6 +585,17 @@ You can go from a video_device struct to the v4l2_device struct using:
|
|||
|
||||
struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
|
||||
|
||||
- Device node name
|
||||
|
||||
The video_device node kernel name can be retrieved using
|
||||
|
||||
const char *video_device_node_name(struct video_device *vdev);
|
||||
|
||||
The name is used as a hint by userspace tools such as udev. The function
|
||||
should be used where possible instead of accessing the video_device::num and
|
||||
video_device::minor fields.
|
||||
|
||||
|
||||
video buffer helper functions
|
||||
-----------------------------
|
||||
|
||||
|
|
|
@ -316,20 +316,23 @@ static struct soc_camera_platform_info camera_info = {
|
|||
.format_name = "UYVY",
|
||||
.format_depth = 16,
|
||||
.format = {
|
||||
.pixelformat = V4L2_PIX_FMT_UYVY,
|
||||
.code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
|
||||
.colorspace = V4L2_COLORSPACE_SMPTE170M,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
},
|
||||
.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
|
||||
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
|
||||
.set_capture = camera_set_capture,
|
||||
.link = {
|
||||
.bus_id = 0,
|
||||
.add_device = ap325rxa_camera_add,
|
||||
.del_device = ap325rxa_camera_del,
|
||||
.module_name = "soc_camera_platform",
|
||||
},
|
||||
};
|
||||
|
||||
struct soc_camera_link camera_link = {
|
||||
.bus_id = 0,
|
||||
.add_device = ap325rxa_camera_add,
|
||||
.del_device = ap325rxa_camera_del,
|
||||
.module_name = "soc_camera_platform",
|
||||
.priv = &camera_info,
|
||||
};
|
||||
|
||||
static void dummy_release(struct device *dev)
|
||||
|
@ -347,7 +350,7 @@ static struct platform_device camera_device = {
|
|||
static int ap325rxa_camera_add(struct soc_camera_link *icl,
|
||||
struct device *dev)
|
||||
{
|
||||
if (icl != &camera_info.link || camera_probe() <= 0)
|
||||
if (icl != &camera_link || camera_probe() <= 0)
|
||||
return -ENODEV;
|
||||
|
||||
camera_info.dev = dev;
|
||||
|
@ -357,7 +360,7 @@ static int ap325rxa_camera_add(struct soc_camera_link *icl,
|
|||
|
||||
static void ap325rxa_camera_del(struct soc_camera_link *icl)
|
||||
{
|
||||
if (icl != &camera_info.link)
|
||||
if (icl != &camera_link)
|
||||
return;
|
||||
|
||||
platform_device_unregister(&camera_device);
|
||||
|
@ -470,13 +473,15 @@ static struct ov772x_camera_info ov7725_info = {
|
|||
.buswidth = SOCAM_DATAWIDTH_8,
|
||||
.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
|
||||
.edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
|
||||
.link = {
|
||||
.bus_id = 0,
|
||||
.power = ov7725_power,
|
||||
.board_info = &ap325rxa_i2c_camera[0],
|
||||
.i2c_adapter_id = 0,
|
||||
.module_name = "ov772x",
|
||||
},
|
||||
};
|
||||
|
||||
static struct soc_camera_link ov7725_link = {
|
||||
.bus_id = 0,
|
||||
.power = ov7725_power,
|
||||
.board_info = &ap325rxa_i2c_camera[0],
|
||||
.i2c_adapter_id = 0,
|
||||
.module_name = "ov772x",
|
||||
.priv = &ov7725_info,
|
||||
};
|
||||
|
||||
static struct platform_device ap325rxa_camera[] = {
|
||||
|
@ -484,13 +489,13 @@ static struct platform_device ap325rxa_camera[] = {
|
|||
.name = "soc-camera-pdrv",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &ov7725_info.link,
|
||||
.platform_data = &ov7725_link,
|
||||
},
|
||||
}, {
|
||||
.name = "soc-camera-pdrv",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &camera_info.link,
|
||||
.platform_data = &camera_link,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/input/sh_keysc.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/usb/r8a66597.h>
|
||||
#include <media/rj54n1cb0c.h>
|
||||
#include <media/soc_camera.h>
|
||||
#include <media/sh_mobile_ceu.h>
|
||||
#include <video/sh_mobile_lcdc.h>
|
||||
|
@ -255,6 +256,9 @@ static struct i2c_board_info kfr2r09_i2c_camera = {
|
|||
|
||||
static struct clk *camera_clk;
|
||||
|
||||
/* set VIO_CKO clock to 25MHz */
|
||||
#define CEU_MCLK_FREQ 25000000
|
||||
|
||||
#define DRVCRB 0xA405018C
|
||||
static int camera_power(struct device *dev, int mode)
|
||||
{
|
||||
|
@ -267,8 +271,7 @@ static int camera_power(struct device *dev, int mode)
|
|||
if (IS_ERR(camera_clk))
|
||||
return PTR_ERR(camera_clk);
|
||||
|
||||
/* set VIO_CKO clock to 25MHz */
|
||||
rate = clk_round_rate(camera_clk, 25000000);
|
||||
rate = clk_round_rate(camera_clk, CEU_MCLK_FREQ);
|
||||
ret = clk_set_rate(camera_clk, rate);
|
||||
if (ret < 0)
|
||||
goto eclkrate;
|
||||
|
@ -318,11 +321,17 @@ eclkrate:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct rj54n1_pdata rj54n1_priv = {
|
||||
.mclk_freq = CEU_MCLK_FREQ,
|
||||
.ioctl_high = false,
|
||||
};
|
||||
|
||||
static struct soc_camera_link rj54n1_link = {
|
||||
.power = camera_power,
|
||||
.board_info = &kfr2r09_i2c_camera,
|
||||
.i2c_adapter_id = 1,
|
||||
.module_name = "rj54n1cb0c",
|
||||
.priv = &rj54n1_priv,
|
||||
};
|
||||
|
||||
static struct platform_device kfr2r09_camera = {
|
||||
|
|
|
@ -432,23 +432,27 @@ static struct i2c_board_info migor_i2c_camera[] = {
|
|||
|
||||
static struct ov772x_camera_info ov7725_info = {
|
||||
.buswidth = SOCAM_DATAWIDTH_8,
|
||||
.link = {
|
||||
.power = ov7725_power,
|
||||
.board_info = &migor_i2c_camera[0],
|
||||
.i2c_adapter_id = 0,
|
||||
.module_name = "ov772x",
|
||||
},
|
||||
};
|
||||
|
||||
static struct soc_camera_link ov7725_link = {
|
||||
.power = ov7725_power,
|
||||
.board_info = &migor_i2c_camera[0],
|
||||
.i2c_adapter_id = 0,
|
||||
.module_name = "ov772x",
|
||||
.priv = &ov7725_info,
|
||||
};
|
||||
|
||||
static struct tw9910_video_info tw9910_info = {
|
||||
.buswidth = SOCAM_DATAWIDTH_8,
|
||||
.mpout = TW9910_MPO_FIELD,
|
||||
.link = {
|
||||
.power = tw9910_power,
|
||||
.board_info = &migor_i2c_camera[1],
|
||||
.i2c_adapter_id = 0,
|
||||
.module_name = "tw9910",
|
||||
}
|
||||
};
|
||||
|
||||
static struct soc_camera_link tw9910_link = {
|
||||
.power = tw9910_power,
|
||||
.board_info = &migor_i2c_camera[1],
|
||||
.i2c_adapter_id = 0,
|
||||
.module_name = "tw9910",
|
||||
.priv = &tw9910_info,
|
||||
};
|
||||
|
||||
static struct platform_device migor_camera[] = {
|
||||
|
@ -456,13 +460,13 @@ static struct platform_device migor_camera[] = {
|
|||
.name = "soc-camera-pdrv",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &ov7725_info.link,
|
||||
.platform_data = &ov7725_link,
|
||||
},
|
||||
}, {
|
||||
.name = "soc-camera-pdrv",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &tw9910_info.link,
|
||||
.platform_data = &tw9910_link,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
9
drivers/media/IR/Kconfig
Normal file
9
drivers/media/IR/Kconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
config IR_CORE
|
||||
tristate
|
||||
depends on INPUT
|
||||
default INPUT
|
||||
|
||||
config VIDEO_IR
|
||||
tristate
|
||||
depends on IR_CORE
|
||||
default IR_CORE
|
5
drivers/media/IR/Makefile
Normal file
5
drivers/media/IR/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
ir-common-objs := ir-functions.o ir-keymaps.o
|
||||
ir-core-objs := ir-keytable.o
|
||||
|
||||
obj-$(CONFIG_IR_CORE) += ir-core.o
|
||||
obj-$(CONFIG_VIDEO_IR) += ir-common.o
|
|
@ -34,9 +34,6 @@ static int repeat = 1;
|
|||
module_param(repeat, int, 0444);
|
||||
MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
|
||||
|
||||
int media_ir_debug; /* media_ir_debug level (0,1,2) */
|
||||
module_param_named(debug, media_ir_debug, int, 0644);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
|
||||
|
@ -55,25 +52,10 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
|
|||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
|
||||
int ir_type, struct ir_scancode_table *ir_codes)
|
||||
int ir_type)
|
||||
{
|
||||
ir->ir_type = ir_type;
|
||||
|
||||
ir->keytable.size = ir_roundup_tablesize(ir_codes->size);
|
||||
ir->keytable.scan = kzalloc(ir->keytable.size *
|
||||
sizeof(struct ir_scancode), GFP_KERNEL);
|
||||
if (!ir->keytable.scan)
|
||||
return -ENOMEM;
|
||||
|
||||
IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
|
||||
ir->keytable.size,
|
||||
ir->keytable.size * sizeof(ir->keytable.scan));
|
||||
|
||||
ir_copy_table(&ir->keytable, ir_codes);
|
||||
ir_set_keycode_table(dev, &ir->keytable);
|
||||
|
||||
clear_bit(0, dev->keybit);
|
||||
set_bit(EV_KEY, dev->evbit);
|
||||
if (repeat)
|
||||
set_bit(EV_REP, dev->evbit);
|
||||
|
|
@ -1847,76 +1847,6 @@ struct ir_scancode_table ir_codes_hauppauge_new_table = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
|
||||
|
||||
/*
|
||||
* Hauppauge:the newer, gray remotes (seems there are multiple
|
||||
* slightly different versions), shipped with cx88+ivtv cards.
|
||||
*
|
||||
* This table contains the complete RC5 code, instead of just the data part
|
||||
*/
|
||||
static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x1e00, KEY_0 },
|
||||
{ 0x1e01, KEY_1 },
|
||||
{ 0x1e02, KEY_2 },
|
||||
{ 0x1e03, KEY_3 },
|
||||
{ 0x1e04, KEY_4 },
|
||||
{ 0x1e05, KEY_5 },
|
||||
{ 0x1e06, KEY_6 },
|
||||
{ 0x1e07, KEY_7 },
|
||||
{ 0x1e08, KEY_8 },
|
||||
{ 0x1e09, KEY_9 },
|
||||
|
||||
{ 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
|
||||
{ 0x1e0b, KEY_RED }, /* red button */
|
||||
{ 0x1e0c, KEY_RADIO },
|
||||
{ 0x1e0d, KEY_MENU },
|
||||
{ 0x1e0e, KEY_SUBTITLE }, /* also the # key */
|
||||
{ 0x1e0f, KEY_MUTE },
|
||||
{ 0x1e10, KEY_VOLUMEUP },
|
||||
{ 0x1e11, KEY_VOLUMEDOWN },
|
||||
{ 0x1e12, KEY_PREVIOUS }, /* previous channel */
|
||||
{ 0x1e14, KEY_UP },
|
||||
{ 0x1e15, KEY_DOWN },
|
||||
{ 0x1e16, KEY_LEFT },
|
||||
{ 0x1e17, KEY_RIGHT },
|
||||
{ 0x1e18, KEY_VIDEO }, /* Videos */
|
||||
{ 0x1e19, KEY_AUDIO }, /* Music */
|
||||
/* 0x1e1a: Pictures - presume this means
|
||||
"Multimedia Home Platform" -
|
||||
no "PICTURES" key in input.h
|
||||
*/
|
||||
{ 0x1e1a, KEY_MHP },
|
||||
|
||||
{ 0x1e1b, KEY_EPG }, /* Guide */
|
||||
{ 0x1e1c, KEY_TV },
|
||||
{ 0x1e1e, KEY_NEXTSONG }, /* skip >| */
|
||||
{ 0x1e1f, KEY_EXIT }, /* back/exit */
|
||||
{ 0x1e20, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
{ 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
|
||||
{ 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
|
||||
{ 0x1e25, KEY_ENTER }, /* OK */
|
||||
{ 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
|
||||
{ 0x1e29, KEY_BLUE }, /* blue key */
|
||||
{ 0x1e2e, KEY_GREEN }, /* green button */
|
||||
{ 0x1e30, KEY_PAUSE }, /* pause */
|
||||
{ 0x1e32, KEY_REWIND }, /* backward << */
|
||||
{ 0x1e34, KEY_FASTFORWARD }, /* forward >> */
|
||||
{ 0x1e35, KEY_PLAY },
|
||||
{ 0x1e36, KEY_STOP },
|
||||
{ 0x1e37, KEY_RECORD }, /* recording */
|
||||
{ 0x1e38, KEY_YELLOW }, /* yellow key */
|
||||
{ 0x1e3b, KEY_SELECT }, /* top right button */
|
||||
{ 0x1e3c, KEY_ZOOM }, /* full */
|
||||
{ 0x1e3d, KEY_POWER }, /* system power (green button) */
|
||||
};
|
||||
|
||||
struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
|
||||
.scan = ir_codes_rc5_hauppauge_new,
|
||||
.size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
|
||||
|
||||
static struct ir_scancode ir_codes_npgtech[] = {
|
||||
{ 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
|
||||
{ 0x2a, KEY_FRONT },
|
||||
|
@ -3314,3 +3244,152 @@ struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
|
||||
|
||||
/*************************************************************
|
||||
* COMPLETE SCANCODE TABLES
|
||||
* Instead of just a partial scancode, the tables bellow
|
||||
* contains the complete scancode and the receiver protocol
|
||||
*************************************************************/
|
||||
|
||||
/*
|
||||
* Hauppauge:the newer, gray remotes (seems there are multiple
|
||||
* slightly different versions), shipped with cx88+ivtv cards.
|
||||
*
|
||||
* This table contains the complete RC5 code, instead of just the data part
|
||||
*/
|
||||
static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
|
||||
/* Keys 0 to 9 */
|
||||
{ 0x1e00, KEY_0 },
|
||||
{ 0x1e01, KEY_1 },
|
||||
{ 0x1e02, KEY_2 },
|
||||
{ 0x1e03, KEY_3 },
|
||||
{ 0x1e04, KEY_4 },
|
||||
{ 0x1e05, KEY_5 },
|
||||
{ 0x1e06, KEY_6 },
|
||||
{ 0x1e07, KEY_7 },
|
||||
{ 0x1e08, KEY_8 },
|
||||
{ 0x1e09, KEY_9 },
|
||||
|
||||
{ 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
|
||||
{ 0x1e0b, KEY_RED }, /* red button */
|
||||
{ 0x1e0c, KEY_RADIO },
|
||||
{ 0x1e0d, KEY_MENU },
|
||||
{ 0x1e0e, KEY_SUBTITLE }, /* also the # key */
|
||||
{ 0x1e0f, KEY_MUTE },
|
||||
{ 0x1e10, KEY_VOLUMEUP },
|
||||
{ 0x1e11, KEY_VOLUMEDOWN },
|
||||
{ 0x1e12, KEY_PREVIOUS }, /* previous channel */
|
||||
{ 0x1e14, KEY_UP },
|
||||
{ 0x1e15, KEY_DOWN },
|
||||
{ 0x1e16, KEY_LEFT },
|
||||
{ 0x1e17, KEY_RIGHT },
|
||||
{ 0x1e18, KEY_VIDEO }, /* Videos */
|
||||
{ 0x1e19, KEY_AUDIO }, /* Music */
|
||||
/* 0x1e1a: Pictures - presume this means
|
||||
"Multimedia Home Platform" -
|
||||
no "PICTURES" key in input.h
|
||||
*/
|
||||
{ 0x1e1a, KEY_MHP },
|
||||
|
||||
{ 0x1e1b, KEY_EPG }, /* Guide */
|
||||
{ 0x1e1c, KEY_TV },
|
||||
{ 0x1e1e, KEY_NEXTSONG }, /* skip >| */
|
||||
{ 0x1e1f, KEY_EXIT }, /* back/exit */
|
||||
{ 0x1e20, KEY_CHANNELUP }, /* channel / program + */
|
||||
{ 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
|
||||
{ 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
|
||||
{ 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
|
||||
{ 0x1e25, KEY_ENTER }, /* OK */
|
||||
{ 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
|
||||
{ 0x1e29, KEY_BLUE }, /* blue key */
|
||||
{ 0x1e2e, KEY_GREEN }, /* green button */
|
||||
{ 0x1e30, KEY_PAUSE }, /* pause */
|
||||
{ 0x1e32, KEY_REWIND }, /* backward << */
|
||||
{ 0x1e34, KEY_FASTFORWARD }, /* forward >> */
|
||||
{ 0x1e35, KEY_PLAY },
|
||||
{ 0x1e36, KEY_STOP },
|
||||
{ 0x1e37, KEY_RECORD }, /* recording */
|
||||
{ 0x1e38, KEY_YELLOW }, /* yellow key */
|
||||
{ 0x1e3b, KEY_SELECT }, /* top right button */
|
||||
{ 0x1e3c, KEY_ZOOM }, /* full */
|
||||
{ 0x1e3d, KEY_POWER }, /* system power (green button) */
|
||||
};
|
||||
|
||||
struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
|
||||
.scan = ir_codes_rc5_hauppauge_new,
|
||||
.size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
|
||||
.ir_type = IR_TYPE_RC5,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
|
||||
|
||||
/* Terratec Cinergy Hybrid T USB XS FM
|
||||
Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
*/
|
||||
static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = {
|
||||
{ 0x1441, KEY_HOME},
|
||||
{ 0x1401, KEY_POWER2},
|
||||
|
||||
{ 0x1442, KEY_MENU}, /* DVD menu */
|
||||
{ 0x1443, KEY_SUBTITLE},
|
||||
{ 0x1444, KEY_TEXT}, /* Teletext */
|
||||
{ 0x1445, KEY_DELETE},
|
||||
|
||||
{ 0x1402, KEY_1},
|
||||
{ 0x1403, KEY_2},
|
||||
{ 0x1404, KEY_3},
|
||||
{ 0x1405, KEY_4},
|
||||
{ 0x1406, KEY_5},
|
||||
{ 0x1407, KEY_6},
|
||||
{ 0x1408, KEY_7},
|
||||
{ 0x1409, KEY_8},
|
||||
{ 0x140a, KEY_9},
|
||||
{ 0x140c, KEY_0},
|
||||
|
||||
{ 0x140b, KEY_TUNER}, /* AV */
|
||||
{ 0x140d, KEY_MODE}, /* A.B */
|
||||
|
||||
{ 0x1446, KEY_TV},
|
||||
{ 0x1447, KEY_DVD},
|
||||
{ 0x1449, KEY_VIDEO},
|
||||
{ 0x144a, KEY_RADIO}, /* Music */
|
||||
{ 0x144b, KEY_CAMERA}, /* PIC */
|
||||
|
||||
{ 0x1410, KEY_UP},
|
||||
{ 0x1411, KEY_LEFT},
|
||||
{ 0x1412, KEY_OK},
|
||||
{ 0x1413, KEY_RIGHT},
|
||||
{ 0x1414, KEY_DOWN},
|
||||
|
||||
{ 0x140f, KEY_EPG},
|
||||
{ 0x1416, KEY_INFO},
|
||||
{ 0x144d, KEY_BACKSPACE},
|
||||
|
||||
{ 0x141c, KEY_VOLUMEUP},
|
||||
{ 0x141e, KEY_VOLUMEDOWN},
|
||||
|
||||
{ 0x144c, KEY_PLAY},
|
||||
{ 0x141d, KEY_MUTE},
|
||||
|
||||
{ 0x141b, KEY_CHANNELUP},
|
||||
{ 0x141f, KEY_CHANNELDOWN},
|
||||
|
||||
{ 0x1417, KEY_RED},
|
||||
{ 0x1418, KEY_GREEN},
|
||||
{ 0x1419, KEY_YELLOW},
|
||||
{ 0x141a, KEY_BLUE},
|
||||
|
||||
{ 0x1458, KEY_RECORD},
|
||||
{ 0x1448, KEY_STOP},
|
||||
{ 0x1440, KEY_PAUSE},
|
||||
|
||||
{ 0x1454, KEY_LAST},
|
||||
{ 0x144e, KEY_REWIND},
|
||||
{ 0x144f, KEY_FASTFORWARD},
|
||||
{ 0x145c, KEY_NEXT},
|
||||
};
|
||||
struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = {
|
||||
.scan = ir_codes_nec_terratec_cinergy_xs,
|
||||
.size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs),
|
||||
.ir_type = IR_TYPE_NEC,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table);
|
||||
|
|
@ -1,10 +1,19 @@
|
|||
/* ir-register.c - handle IR scancode->keycode tables
|
||||
*
|
||||
* Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/usb/input.h>
|
||||
|
||||
#include <linux/usb/input.h>
|
||||
#include <media/ir-common.h>
|
||||
|
||||
#define IR_TAB_MIN_SIZE 32
|
||||
|
@ -72,6 +81,7 @@ int ir_roundup_tablesize(int n_elems)
|
|||
|
||||
return n_elems;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_roundup_tablesize);
|
||||
|
||||
/**
|
||||
* ir_copy_table() - copies a keytable, discarding the unused entries
|
||||
|
@ -100,6 +110,7 @@ int ir_copy_table(struct ir_scancode_table *destin,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_copy_table);
|
||||
|
||||
/**
|
||||
* ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
|
||||
|
@ -114,7 +125,8 @@ static int ir_getkeycode(struct input_dev *dev,
|
|||
int scancode, int *keycode)
|
||||
{
|
||||
int elem;
|
||||
struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
|
||||
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
|
||||
|
||||
elem = ir_seek_table(rc_tab, scancode);
|
||||
if (elem >= 0) {
|
||||
|
@ -136,7 +148,6 @@ static int ir_getkeycode(struct input_dev *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ir_is_resize_needed() - Check if the table needs rezise
|
||||
* @table: keycode table that may need to resize
|
||||
|
@ -286,7 +297,8 @@ static int ir_setkeycode(struct input_dev *dev,
|
|||
int scancode, int keycode)
|
||||
{
|
||||
int rc = 0;
|
||||
struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
|
||||
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
|
||||
struct ir_scancode *keymap = rc_tab->scan;
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -360,7 +372,8 @@ static int ir_setkeycode(struct input_dev *dev,
|
|||
*/
|
||||
u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
|
||||
{
|
||||
struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
|
||||
struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
|
||||
struct ir_scancode *keymap = rc_tab->scan;
|
||||
int elem;
|
||||
|
||||
|
@ -378,9 +391,10 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
|
|||
/* Reports userspace that an unknown keycode were got */
|
||||
return KEY_RESERVED;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_g_keycode_from_table);
|
||||
|
||||
/**
|
||||
* ir_set_keycode_table() - sets the IR keycode table and add the handlers
|
||||
* ir_input_register() - sets the IR keycode table and add the handlers
|
||||
* for keymap table get/set
|
||||
* @input_dev: the struct input_dev descriptor of the device
|
||||
* @rc_tab: the struct ir_scancode_table table of scancode/keymap
|
||||
|
@ -389,17 +403,34 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
|
|||
* an IR.
|
||||
* It should be called before registering the IR device.
|
||||
*/
|
||||
int ir_set_keycode_table(struct input_dev *input_dev,
|
||||
struct ir_scancode_table *rc_tab)
|
||||
int ir_input_register(struct input_dev *input_dev,
|
||||
struct ir_scancode_table *rc_tab)
|
||||
{
|
||||
struct ir_scancode *keymap = rc_tab->scan;
|
||||
int i;
|
||||
|
||||
spin_lock_init(&rc_tab->lock);
|
||||
struct ir_input_dev *ir_dev;
|
||||
struct ir_scancode *keymap = rc_tab->scan;
|
||||
int i, rc;
|
||||
|
||||
if (rc_tab->scan == NULL || !rc_tab->size)
|
||||
return -EINVAL;
|
||||
|
||||
ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL);
|
||||
if (!ir_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&rc_tab->lock);
|
||||
|
||||
ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size);
|
||||
ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size *
|
||||
sizeof(struct ir_scancode), GFP_KERNEL);
|
||||
if (!ir_dev->rc_tab.scan)
|
||||
return -ENOMEM;
|
||||
|
||||
IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
|
||||
ir_dev->rc_tab.size,
|
||||
ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan));
|
||||
|
||||
ir_copy_table(&ir_dev->rc_tab, rc_tab);
|
||||
|
||||
/* set the bits for the keys */
|
||||
IR_dprintk(1, "key map size: %d\n", rc_tab->size);
|
||||
for (i = 0; i < rc_tab->size; i++) {
|
||||
|
@ -407,23 +438,48 @@ int ir_set_keycode_table(struct input_dev *input_dev,
|
|||
i, keymap[i].keycode);
|
||||
set_bit(keymap[i].keycode, input_dev->keybit);
|
||||
}
|
||||
clear_bit(0, input_dev->keybit);
|
||||
|
||||
set_bit(EV_KEY, input_dev->evbit);
|
||||
|
||||
input_dev->getkeycode = ir_getkeycode;
|
||||
input_dev->setkeycode = ir_setkeycode;
|
||||
input_set_drvdata(input_dev, rc_tab);
|
||||
input_set_drvdata(input_dev, ir_dev);
|
||||
|
||||
return 0;
|
||||
rc = input_register_device(input_dev);
|
||||
if (rc < 0) {
|
||||
kfree(rc_tab->scan);
|
||||
kfree(ir_dev);
|
||||
input_set_drvdata(input_dev, NULL);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_input_register);
|
||||
|
||||
void ir_input_free(struct input_dev *dev)
|
||||
void ir_input_unregister(struct input_dev *dev)
|
||||
{
|
||||
struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
|
||||
struct ir_input_dev *ir_dev = input_get_drvdata(dev);
|
||||
struct ir_scancode_table *rc_tab;
|
||||
|
||||
if (!ir_dev)
|
||||
return;
|
||||
|
||||
IR_dprintk(1, "Freed keycode table\n");
|
||||
|
||||
rc_tab = &ir_dev->rc_tab;
|
||||
rc_tab->size = 0;
|
||||
kfree(rc_tab->scan);
|
||||
rc_tab->scan = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_input_free);
|
||||
|
||||
kfree(ir_dev);
|
||||
input_unregister_device(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ir_input_unregister);
|
||||
|
||||
int ir_core_debug; /* ir_debug level (0,1,2) */
|
||||
EXPORT_SYMBOL_GPL(ir_core_debug);
|
||||
module_param_named(debug, ir_core_debug, int, 0644);
|
||||
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -99,6 +99,7 @@ config VIDEO_MEDIA
|
|||
comment "Multimedia drivers"
|
||||
|
||||
source "drivers/media/common/Kconfig"
|
||||
source "drivers/media/IR/Kconfig"
|
||||
|
||||
#
|
||||
# Tuner drivers for DVB and V4L
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Makefile for the kernel multimedia device drivers.
|
||||
#
|
||||
|
||||
obj-y += common/ video/
|
||||
obj-y += common/ IR/ video/
|
||||
|
||||
obj-$(CONFIG_VIDEO_DEV) += radio/
|
||||
obj-$(CONFIG_DVB_CORE) += dvb/
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
saa7146-objs := saa7146_i2c.o saa7146_core.o
|
||||
saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
|
||||
ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o
|
||||
|
||||
obj-y += tuners/
|
||||
obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
|
||||
obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
|
||||
obj-$(CONFIG_VIDEO_IR) += ir-common.o
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <media/saa7146_vv.h>
|
||||
|
||||
#define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
|
||||
|
||||
/****************************************************************************/
|
||||
/* resource management functions, shamelessly stolen from saa7134 driver */
|
||||
|
||||
|
@ -194,43 +192,24 @@ void saa7146_buffer_timeout(unsigned long data)
|
|||
|
||||
static int fops_open(struct file *file)
|
||||
{
|
||||
unsigned int minor = video_devdata(file)->minor;
|
||||
struct saa7146_dev *h = NULL, *dev = NULL;
|
||||
struct list_head *list;
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_dev *dev = video_drvdata(file);
|
||||
struct saa7146_fh *fh = NULL;
|
||||
int result = 0;
|
||||
|
||||
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
enum v4l2_buf_type type;
|
||||
|
||||
DEB_EE(("file:%p, minor:%d\n", file, minor));
|
||||
DEB_EE(("file:%p, dev:%s\n", file, video_device_node_name(vdev)));
|
||||
|
||||
if (mutex_lock_interruptible(&saa7146_devices_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
list_for_each(list,&saa7146_devices) {
|
||||
h = list_entry(list, struct saa7146_dev, item);
|
||||
if( NULL == h->vv_data ) {
|
||||
DEB_D(("device %p has not registered video devices.\n",h));
|
||||
continue;
|
||||
}
|
||||
DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));
|
||||
|
||||
if (h->vv_data->video_minor == minor) {
|
||||
dev = h;
|
||||
}
|
||||
if (h->vv_data->vbi_minor == minor) {
|
||||
type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
dev = h;
|
||||
}
|
||||
}
|
||||
if (NULL == dev) {
|
||||
DEB_S(("no such video device.\n"));
|
||||
result = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEB_D(("using: %p\n",dev));
|
||||
|
||||
type = vdev->vfl_type == VFL_TYPE_GRABBER
|
||||
? V4L2_BUF_TYPE_VIDEO_CAPTURE
|
||||
: V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
|
||||
/* check if an extension is registered */
|
||||
if( NULL == dev->ext ) {
|
||||
DEB_S(("no extension registered for this device.\n"));
|
||||
|
@ -474,9 +453,6 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
|
|||
configuration data) */
|
||||
dev->ext_vv_data = ext_vv;
|
||||
|
||||
vv->video_minor = -1;
|
||||
vv->vbi_minor = -1;
|
||||
|
||||
vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);
|
||||
if( NULL == vv->d_clipping.cpu_addr ) {
|
||||
ERR(("out of memory. aborting.\n"));
|
||||
|
@ -515,7 +491,6 @@ EXPORT_SYMBOL_GPL(saa7146_vv_release);
|
|||
int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
|
||||
char *name, int type)
|
||||
{
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
struct video_device *vfd;
|
||||
int err;
|
||||
int i;
|
||||
|
@ -543,15 +518,8 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
|
|||
return err;
|
||||
}
|
||||
|
||||
if( VFL_TYPE_GRABBER == type ) {
|
||||
vv->video_minor = vfd->minor;
|
||||
INFO(("%s: registered device video%d [v4l2]\n",
|
||||
dev->name, vfd->num));
|
||||
} else {
|
||||
vv->vbi_minor = vfd->minor;
|
||||
INFO(("%s: registered device vbi%d [v4l2]\n",
|
||||
dev->name, vfd->num));
|
||||
}
|
||||
INFO(("%s: registered device %s [v4l2]\n",
|
||||
dev->name, video_device_node_name(vfd)));
|
||||
|
||||
*vid = vfd;
|
||||
return 0;
|
||||
|
@ -560,16 +528,8 @@ EXPORT_SYMBOL_GPL(saa7146_register_device);
|
|||
|
||||
int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
|
||||
{
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
|
||||
DEB_EE(("dev:%p\n",dev));
|
||||
|
||||
if ((*vid)->vfl_type == VFL_TYPE_GRABBER) {
|
||||
vv->video_minor = -1;
|
||||
} else {
|
||||
vv->vbi_minor = -1;
|
||||
}
|
||||
|
||||
video_unregister_device(*vid);
|
||||
*vid = NULL;
|
||||
|
||||
|
|
|
@ -589,7 +589,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
|
|||
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
|
||||
"pci-%s/ir0", pci_name(dm1105->pdev));
|
||||
|
||||
err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
|
||||
err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type);
|
||||
if (err < 0) {
|
||||
input_free_device(input_dev);
|
||||
return err;
|
||||
|
@ -611,20 +611,14 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
|
|||
|
||||
INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
|
||||
|
||||
err = input_register_device(input_dev);
|
||||
if (err) {
|
||||
ir_input_free(input_dev);
|
||||
input_free_device(input_dev);
|
||||
return err;
|
||||
}
|
||||
err = ir_input_register(input_dev, ir_codes);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
|
||||
{
|
||||
ir_input_free(dm1105->ir.input_dev);
|
||||
input_unregister_device(dm1105->ir.input_dev);
|
||||
ir_input_unregister(dm1105->ir.input_dev);
|
||||
}
|
||||
|
||||
static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
|
||||
|
|
|
@ -265,9 +265,13 @@ config DVB_USB_DW2102
|
|||
select DVB_TDA10021 if !DVB_FE_CUSTOMISE
|
||||
select DVB_MT312 if !DVB_FE_CUSTOMISE
|
||||
select DVB_ZL10039 if !DVB_FE_CUSTOMISE
|
||||
select DVB_DS3000 if !DVB_FE_CUSTOMISE
|
||||
select DVB_STB6100 if !DVB_FE_CUSTOMISE
|
||||
select DVB_STV6110 if !DVB_FE_CUSTOMISE
|
||||
select DVB_STV0900 if !DVB_FE_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
|
||||
and the TeVii S650, S630.
|
||||
Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
|
||||
receivers.
|
||||
|
||||
config DVB_USB_CINERGY_T2
|
||||
tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
|
||||
|
|
|
@ -20,20 +20,22 @@ extern int dvb_usb_dib0700_debug;
|
|||
#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
|
||||
#define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args)
|
||||
|
||||
#define REQUEST_I2C_READ 0x2
|
||||
#define REQUEST_I2C_WRITE 0x3
|
||||
#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
|
||||
#define REQUEST_JUMPRAM 0x8
|
||||
#define REQUEST_SET_CLOCK 0xB
|
||||
#define REQUEST_SET_GPIO 0xC
|
||||
#define REQUEST_ENABLE_VIDEO 0xF
|
||||
#define REQUEST_SET_USB_XFER_LEN 0x0 /* valid only for firmware version */
|
||||
/* higher than 1.21 */
|
||||
#define REQUEST_I2C_READ 0x2
|
||||
#define REQUEST_I2C_WRITE 0x3
|
||||
#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
|
||||
#define REQUEST_JUMPRAM 0x8
|
||||
#define REQUEST_SET_CLOCK 0xB
|
||||
#define REQUEST_SET_GPIO 0xC
|
||||
#define REQUEST_ENABLE_VIDEO 0xF
|
||||
// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
|
||||
// 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
|
||||
// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
|
||||
#define REQUEST_SET_RC 0x11
|
||||
#define REQUEST_NEW_I2C_READ 0x12
|
||||
#define REQUEST_NEW_I2C_WRITE 0x13
|
||||
#define REQUEST_GET_VERSION 0x15
|
||||
#define REQUEST_SET_RC 0x11
|
||||
#define REQUEST_NEW_I2C_READ 0x12
|
||||
#define REQUEST_NEW_I2C_WRITE 0x13
|
||||
#define REQUEST_GET_VERSION 0x15
|
||||
|
||||
struct dib0700_state {
|
||||
u8 channel_state;
|
||||
|
@ -44,6 +46,8 @@ struct dib0700_state {
|
|||
u8 is_dib7000pc;
|
||||
u8 fw_use_new_i2c_api;
|
||||
u8 disable_streaming_master_mode;
|
||||
u32 fw_version;
|
||||
u32 nb_packet_buffer_size;
|
||||
};
|
||||
|
||||
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
|
||||
|
|
|
@ -17,6 +17,14 @@ int dvb_usb_dib0700_ir_proto = 1;
|
|||
module_param(dvb_usb_dib0700_ir_proto, int, 0644);
|
||||
MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
|
||||
|
||||
static int nb_packet_buffer_size = 21;
|
||||
module_param(nb_packet_buffer_size, int, 0644);
|
||||
MODULE_PARM_DESC(nb_packet_buffer_size,
|
||||
"Set the dib0700 driver data buffer size. This parameter "
|
||||
"corresponds to the number of TS packets. The actual size of "
|
||||
"the data buffer corresponds to this parameter "
|
||||
"multiplied by 188 (default: 21)");
|
||||
|
||||
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
||||
|
||||
|
||||
|
@ -28,10 +36,14 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
|
|||
REQUEST_GET_VERSION,
|
||||
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
|
||||
b, sizeof(b), USB_CTRL_GET_TIMEOUT);
|
||||
*hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
|
||||
*romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
|
||||
*ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
|
||||
*fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
|
||||
if (hwversion != NULL)
|
||||
*hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
|
||||
if (romversion != NULL)
|
||||
*romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
|
||||
if (ramversion != NULL)
|
||||
*ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
|
||||
if (fwtype != NULL)
|
||||
*fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -97,6 +109,27 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
|
|||
return dib0700_ctrl_wr(d,buf,3);
|
||||
}
|
||||
|
||||
static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
|
||||
{
|
||||
struct dib0700_state *st = d->priv;
|
||||
u8 b[3];
|
||||
int ret;
|
||||
|
||||
if (st->fw_version >= 0x10201) {
|
||||
b[0] = REQUEST_SET_USB_XFER_LEN;
|
||||
b[1] = (nb_ts_packets >> 8)&0xff;
|
||||
b[2] = nb_ts_packets & 0xff;
|
||||
|
||||
deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
|
||||
|
||||
ret = dib0700_ctrl_wr(d, b, 3);
|
||||
} else {
|
||||
deb_info("this firmware does not allow to change the USB xfer len\n");
|
||||
ret = -EIO;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* I2C master xfer function (supported in 1.20 firmware)
|
||||
*/
|
||||
|
@ -328,7 +361,9 @@ static int dib0700_jumpram(struct usb_device *udev, u32 address)
|
|||
int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
|
||||
{
|
||||
struct hexline hx;
|
||||
int pos = 0, ret, act_len;
|
||||
int pos = 0, ret, act_len, i, adap_num;
|
||||
u8 b[16];
|
||||
u32 fw_version;
|
||||
|
||||
u8 buf[260];
|
||||
|
||||
|
@ -364,6 +399,34 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
|
|||
} else
|
||||
ret = -EIO;
|
||||
|
||||
/* the number of ts packet has to be at least 1 */
|
||||
if (nb_packet_buffer_size < 1)
|
||||
nb_packet_buffer_size = 1;
|
||||
|
||||
/* get the fimware version */
|
||||
usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||
REQUEST_GET_VERSION,
|
||||
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
|
||||
b, sizeof(b), USB_CTRL_GET_TIMEOUT);
|
||||
fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
|
||||
|
||||
/* set the buffer size - DVB-USB is allocating URB buffers
|
||||
* only after the firwmare download was successful */
|
||||
for (i = 0; i < dib0700_device_count; i++) {
|
||||
for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
|
||||
adap_num++) {
|
||||
if (fw_version >= 0x10201)
|
||||
dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
|
||||
else {
|
||||
/* for fw version older than 1.20.1,
|
||||
* the buffersize has to be n times 512 */
|
||||
dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
|
||||
if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512)
|
||||
dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -371,6 +434,18 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
|||
{
|
||||
struct dib0700_state *st = adap->dev->priv;
|
||||
u8 b[4];
|
||||
int ret;
|
||||
|
||||
if ((onoff != 0) && (st->fw_version >= 0x10201)) {
|
||||
/* for firmware later than 1.20.1,
|
||||
* the USB xfer length can be set */
|
||||
ret = dib0700_set_usb_xfer_len(adap->dev,
|
||||
st->nb_packet_buffer_size);
|
||||
if (ret < 0) {
|
||||
deb_info("can not set the USB xfer len\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
b[0] = REQUEST_ENABLE_VIDEO;
|
||||
b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
|
||||
|
@ -415,9 +490,21 @@ static int dib0700_probe(struct usb_interface *intf,
|
|||
|
||||
for (i = 0; i < dib0700_device_count; i++)
|
||||
if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
|
||||
&dev, adapter_nr) == 0)
|
||||
{
|
||||
&dev, adapter_nr) == 0) {
|
||||
struct dib0700_state *st = dev->priv;
|
||||
u32 hwversion, romversion, fw_version, fwtype;
|
||||
|
||||
dib0700_get_version(dev, &hwversion, &romversion,
|
||||
&fw_version, &fwtype);
|
||||
|
||||
deb_info("Firmware version: %x, %d, 0x%x, %d\n",
|
||||
hwversion, romversion, fw_version, fwtype);
|
||||
|
||||
st->fw_version = fw_version;
|
||||
st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
|
||||
|
||||
dib0700_rc_setup(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "xc5000.h"
|
||||
#include "s5h1411.h"
|
||||
#include "dib0070.h"
|
||||
#include "dib0090.h"
|
||||
#include "lgdt3305.h"
|
||||
#include "mxl5007t.h"
|
||||
|
||||
|
@ -130,93 +131,95 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
/* MT226x */
|
||||
static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
|
||||
{
|
||||
BAND_UHF, // band_caps
|
||||
BAND_UHF,
|
||||
|
||||
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
|
||||
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
|
||||
(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
|
||||
(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
|
||||
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
|
||||
|
||||
1130, // inv_gain
|
||||
21, // time_stabiliz
|
||||
1130,
|
||||
21,
|
||||
|
||||
0, // alpha_level
|
||||
118, // thlock
|
||||
0,
|
||||
118,
|
||||
|
||||
0, // wbd_inv
|
||||
3530, // wbd_ref
|
||||
1, // wbd_sel
|
||||
0, // wbd_alpha
|
||||
0,
|
||||
3530,
|
||||
1,
|
||||
0,
|
||||
|
||||
65535, // agc1_max
|
||||
33770, // agc1_min
|
||||
65535, // agc2_max
|
||||
23592, // agc2_min
|
||||
65535,
|
||||
33770,
|
||||
65535,
|
||||
23592,
|
||||
|
||||
0, // agc1_pt1
|
||||
62, // agc1_pt2
|
||||
255, // agc1_pt3
|
||||
64, // agc1_slope1
|
||||
64, // agc1_slope2
|
||||
132, // agc2_pt1
|
||||
192, // agc2_pt2
|
||||
80, // agc2_slope1
|
||||
80, // agc2_slope2
|
||||
0,
|
||||
62,
|
||||
255,
|
||||
64,
|
||||
64,
|
||||
132,
|
||||
192,
|
||||
80,
|
||||
80,
|
||||
|
||||
17, // alpha_mant
|
||||
27, // alpha_exp
|
||||
23, // beta_mant
|
||||
51, // beta_exp
|
||||
17,
|
||||
27,
|
||||
23,
|
||||
51,
|
||||
|
||||
1, // perform_agc_softsplit
|
||||
1,
|
||||
}, {
|
||||
BAND_VHF | BAND_LBAND, // band_caps
|
||||
BAND_VHF | BAND_LBAND,
|
||||
|
||||
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
|
||||
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
|
||||
(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
|
||||
(0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
|
||||
| (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
|
||||
|
||||
2372, // inv_gain
|
||||
21, // time_stabiliz
|
||||
2372,
|
||||
21,
|
||||
|
||||
0, // alpha_level
|
||||
118, // thlock
|
||||
0,
|
||||
118,
|
||||
|
||||
0, // wbd_inv
|
||||
3530, // wbd_ref
|
||||
1, // wbd_sel
|
||||
0, // wbd_alpha
|
||||
0,
|
||||
3530,
|
||||
1,
|
||||
0,
|
||||
|
||||
65535, // agc1_max
|
||||
0, // agc1_min
|
||||
65535, // agc2_max
|
||||
23592, // agc2_min
|
||||
65535,
|
||||
0,
|
||||
65535,
|
||||
23592,
|
||||
|
||||
0, // agc1_pt1
|
||||
128, // agc1_pt2
|
||||
128, // agc1_pt3
|
||||
128, // agc1_slope1
|
||||
0, // agc1_slope2
|
||||
128, // agc2_pt1
|
||||
253, // agc2_pt2
|
||||
81, // agc2_slope1
|
||||
0, // agc2_slope2
|
||||
0,
|
||||
128,
|
||||
128,
|
||||
128,
|
||||
0,
|
||||
128,
|
||||
253,
|
||||
81,
|
||||
0,
|
||||
|
||||
17, // alpha_mant
|
||||
27, // alpha_exp
|
||||
23, // beta_mant
|
||||
51, // beta_exp
|
||||
17,
|
||||
27,
|
||||
23,
|
||||
51,
|
||||
|
||||
1, // perform_agc_softsplit
|
||||
1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
|
||||
60000, 30000, // internal, sampling
|
||||
1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
|
||||
0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
|
||||
(3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
|
||||
0, // ifreq
|
||||
20452225, // timf
|
||||
60000, 30000,
|
||||
1, 8, 3, 1, 0,
|
||||
0, 0, 1, 1, 2,
|
||||
(3 << 14) | (1 << 12) | (524 << 0),
|
||||
0,
|
||||
20452225,
|
||||
};
|
||||
|
||||
static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
|
||||
|
@ -605,17 +608,17 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (actlen != sizeof(buf)) {
|
||||
/* We didn't get back the 6 byte message we expected */
|
||||
err("Unexpected RC response size [%d]", actlen);
|
||||
return -1;
|
||||
}
|
||||
if (actlen != sizeof(buf)) {
|
||||
/* We didn't get back the 6 byte message we expected */
|
||||
err("Unexpected RC response size [%d]", actlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
poll_reply.report_id = buf[0];
|
||||
poll_reply.data_state = buf[1];
|
||||
poll_reply.report_id = buf[0];
|
||||
poll_reply.data_state = buf[1];
|
||||
poll_reply.system = (buf[2] << 8) | buf[3];
|
||||
poll_reply.data = buf[4];
|
||||
poll_reply.not_data = buf[5];
|
||||
poll_reply.data = buf[4];
|
||||
poll_reply.not_data = buf[5];
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -632,7 +635,7 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
|
|||
/* Find the key in the map */
|
||||
for (i = 0; i < d->props.rc_key_map_size; i++) {
|
||||
if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) &&
|
||||
rc5_data(&keymap[i]) == poll_reply.data) {
|
||||
rc5_data(&keymap[i]) == poll_reply.data) {
|
||||
*event = keymap[i].event;
|
||||
found = 1;
|
||||
break;
|
||||
|
@ -641,8 +644,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
|
|||
|
||||
if (found == 0) {
|
||||
err("Unknown remote controller key: %04x %02x %02x",
|
||||
poll_reply.system,
|
||||
poll_reply.data, poll_reply.not_data);
|
||||
poll_reply.system,
|
||||
poll_reply.data, poll_reply.not_data);
|
||||
d->last_event = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -933,47 +936,48 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
|
|||
|
||||
/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
|
||||
static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
|
||||
BAND_UHF | BAND_VHF, // band_caps
|
||||
BAND_UHF | BAND_VHF,
|
||||
|
||||
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
|
||||
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
|
||||
(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
|
||||
(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
|
||||
| (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
|
||||
|
||||
712, // inv_gain
|
||||
41, // time_stabiliz
|
||||
712,
|
||||
41,
|
||||
|
||||
0, // alpha_level
|
||||
118, // thlock
|
||||
0,
|
||||
118,
|
||||
|
||||
0, // wbd_inv
|
||||
4095, // wbd_ref
|
||||
0, // wbd_sel
|
||||
0, // wbd_alpha
|
||||
0,
|
||||
4095,
|
||||
0,
|
||||
0,
|
||||
|
||||
42598, // agc1_max
|
||||
17694, // agc1_min
|
||||
45875, // agc2_max
|
||||
2621, // agc2_min
|
||||
0, // agc1_pt1
|
||||
76, // agc1_pt2
|
||||
139, // agc1_pt3
|
||||
52, // agc1_slope1
|
||||
59, // agc1_slope2
|
||||
107, // agc2_pt1
|
||||
172, // agc2_pt2
|
||||
57, // agc2_slope1
|
||||
70, // agc2_slope2
|
||||
42598,
|
||||
17694,
|
||||
45875,
|
||||
2621,
|
||||
0,
|
||||
76,
|
||||
139,
|
||||
52,
|
||||
59,
|
||||
107,
|
||||
172,
|
||||
57,
|
||||
70,
|
||||
|
||||
21, // alpha_mant
|
||||
25, // alpha_exp
|
||||
28, // beta_mant
|
||||
48, // beta_exp
|
||||
21,
|
||||
25,
|
||||
28,
|
||||
48,
|
||||
|
||||
1, // perform_agc_softsplit
|
||||
{ 0, // split_min
|
||||
107, // split_max
|
||||
51800, // global_split_min
|
||||
24700 // global_split_max
|
||||
1,
|
||||
{ 0,
|
||||
107,
|
||||
51800,
|
||||
24700
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -982,54 +986,55 @@ static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
|
|||
|
||||
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
|
||||
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
|
||||
(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
|
||||
(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
|
||||
| (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
|
||||
|
||||
712, // inv_gain
|
||||
41, // time_stabiliz
|
||||
712,
|
||||
41,
|
||||
|
||||
0, // alpha_level
|
||||
118, // thlock
|
||||
0,
|
||||
118,
|
||||
|
||||
0, // wbd_inv
|
||||
4095, // wbd_ref
|
||||
0, // wbd_sel
|
||||
0, // wbd_alpha
|
||||
0,
|
||||
4095,
|
||||
0,
|
||||
0,
|
||||
|
||||
42598, // agc1_max
|
||||
16384, // agc1_min
|
||||
42598, // agc2_max
|
||||
0, // agc2_min
|
||||
42598,
|
||||
16384,
|
||||
42598,
|
||||
0,
|
||||
|
||||
0, // agc1_pt1
|
||||
137, // agc1_pt2
|
||||
255, // agc1_pt3
|
||||
0,
|
||||
137,
|
||||
255,
|
||||
|
||||
0, // agc1_slope1
|
||||
255, // agc1_slope2
|
||||
0,
|
||||
255,
|
||||
|
||||
0, // agc2_pt1
|
||||
0, // agc2_pt2
|
||||
0,
|
||||
0,
|
||||
|
||||
0, // agc2_slope1
|
||||
41, // agc2_slope2
|
||||
0,
|
||||
41,
|
||||
|
||||
15, // alpha_mant
|
||||
25, // alpha_exp
|
||||
15,
|
||||
25,
|
||||
|
||||
28, // beta_mant
|
||||
48, // beta_exp
|
||||
28,
|
||||
48,
|
||||
|
||||
0, // perform_agc_softsplit
|
||||
0,
|
||||
};
|
||||
|
||||
static struct dibx000_bandwidth_config stk7700p_pll_config = {
|
||||
60000, 30000, // internal, sampling
|
||||
1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
|
||||
0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
|
||||
(3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
|
||||
60258167, // ifreq
|
||||
20452225, // timf
|
||||
30000000, // xtal
|
||||
60000, 30000,
|
||||
1, 8, 3, 1, 0,
|
||||
0, 0, 1, 1, 0,
|
||||
(3 << 14) | (1 << 12) | (524 << 0),
|
||||
60258167,
|
||||
20452225,
|
||||
30000000,
|
||||
};
|
||||
|
||||
static struct dib7000m_config stk7700p_dib7000m_config = {
|
||||
|
@ -1115,41 +1120,42 @@ static struct dibx000_agc_config dib7070_agc_config = {
|
|||
BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
|
||||
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
|
||||
* P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
|
||||
(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
|
||||
(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
|
||||
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
|
||||
|
||||
600, // inv_gain
|
||||
10, // time_stabiliz
|
||||
600,
|
||||
10,
|
||||
|
||||
0, // alpha_level
|
||||
118, // thlock
|
||||
0,
|
||||
118,
|
||||
|
||||
0, // wbd_inv
|
||||
3530, // wbd_ref
|
||||
1, // wbd_sel
|
||||
5, // wbd_alpha
|
||||
0,
|
||||
3530,
|
||||
1,
|
||||
5,
|
||||
|
||||
65535, // agc1_max
|
||||
0, // agc1_min
|
||||
65535,
|
||||
0,
|
||||
|
||||
65535, // agc2_max
|
||||
0, // agc2_min
|
||||
65535,
|
||||
0,
|
||||
|
||||
0, // agc1_pt1
|
||||
40, // agc1_pt2
|
||||
183, // agc1_pt3
|
||||
206, // agc1_slope1
|
||||
255, // agc1_slope2
|
||||
72, // agc2_pt1
|
||||
152, // agc2_pt2
|
||||
88, // agc2_slope1
|
||||
90, // agc2_slope2
|
||||
0,
|
||||
40,
|
||||
183,
|
||||
206,
|
||||
255,
|
||||
72,
|
||||
152,
|
||||
88,
|
||||
90,
|
||||
|
||||
17, // alpha_mant
|
||||
27, // alpha_exp
|
||||
23, // beta_mant
|
||||
51, // beta_exp
|
||||
17,
|
||||
27,
|
||||
23,
|
||||
51,
|
||||
|
||||
0, // perform_agc_softsplit
|
||||
0,
|
||||
};
|
||||
|
||||
static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
|
||||
|
@ -1276,13 +1282,13 @@ static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
|
|||
}
|
||||
|
||||
static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
|
||||
60000, 15000, // internal, sampling
|
||||
1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
|
||||
0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
|
||||
(3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
|
||||
(0 << 25) | 0, // ifreq = 0.000000 MHz
|
||||
20452225, // timf
|
||||
12000000, // xtal_hz
|
||||
60000, 15000,
|
||||
1, 20, 3, 1, 0,
|
||||
0, 0, 1, 1, 2,
|
||||
(3 << 14) | (1 << 12) | (524 << 0),
|
||||
(0 << 25) | 0,
|
||||
20452225,
|
||||
12000000,
|
||||
};
|
||||
|
||||
static struct dib7000p_config dib7070p_dib7000p_config = {
|
||||
|
@ -1476,12 +1482,12 @@ static struct dib8000_config dib807x_dib8000_config[2] = {
|
|||
}
|
||||
};
|
||||
|
||||
static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
|
||||
static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
|
||||
{
|
||||
return dib8000_set_gpio(fe, 5, 0, !onoff);
|
||||
}
|
||||
|
||||
static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
|
||||
static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
|
||||
{
|
||||
return dib8000_set_gpio(fe, 0, 0, onoff);
|
||||
}
|
||||
|
@ -1494,8 +1500,8 @@ static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
|
|||
static struct dib0070_config dib807x_dib0070_config[2] = {
|
||||
{
|
||||
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
|
||||
.reset = dib807x_tuner_reset,
|
||||
.sleep = dib807x_tuner_sleep,
|
||||
.reset = dib80xx_tuner_reset,
|
||||
.sleep = dib80xx_tuner_sleep,
|
||||
.clock_khz = 12000,
|
||||
.clock_pad_drive = 4,
|
||||
.vga_filter = 1,
|
||||
|
@ -1508,8 +1514,8 @@ static struct dib0070_config dib807x_dib0070_config[2] = {
|
|||
.freq_offset_khz_vhf = -100,
|
||||
}, {
|
||||
.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
|
||||
.reset = dib807x_tuner_reset,
|
||||
.sleep = dib807x_tuner_sleep,
|
||||
.reset = dib80xx_tuner_reset,
|
||||
.sleep = dib80xx_tuner_sleep,
|
||||
.clock_khz = 12000,
|
||||
.clock_pad_drive = 2,
|
||||
.vga_filter = 1,
|
||||
|
@ -1566,12 +1572,14 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
|
||||
static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
|
||||
u16 pid, int onoff)
|
||||
{
|
||||
return dib8000_pid_filter(adapter->fe, index, pid, onoff);
|
||||
}
|
||||
|
||||
static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
|
||||
static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
|
||||
int onoff)
|
||||
{
|
||||
return dib8000_pid_filter_ctrl(adapter->fe, onoff);
|
||||
}
|
||||
|
@ -1624,7 +1632,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
|
|||
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
||||
|
||||
/* initialize IC 0 */
|
||||
dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
|
||||
dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80);
|
||||
|
||||
adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
|
||||
&dib807x_dib8000_config[0]);
|
||||
|
@ -1635,7 +1643,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
|
|||
static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
/* initialize IC 1 */
|
||||
dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
|
||||
dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82);
|
||||
|
||||
adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
|
||||
&dib807x_dib8000_config[1]);
|
||||
|
@ -1643,6 +1651,245 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
|
|||
return adap->fe == NULL ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
/* STK8096GP */
|
||||
struct dibx000_agc_config dib8090_agc_config[2] = {
|
||||
{
|
||||
BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
|
||||
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
|
||||
* P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
|
||||
* P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
|
||||
(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
|
||||
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
|
||||
|
||||
787,
|
||||
10,
|
||||
|
||||
0,
|
||||
118,
|
||||
|
||||
0,
|
||||
3530,
|
||||
1,
|
||||
5,
|
||||
|
||||
65535,
|
||||
0,
|
||||
|
||||
65535,
|
||||
0,
|
||||
|
||||
0,
|
||||
32,
|
||||
114,
|
||||
143,
|
||||
144,
|
||||
114,
|
||||
227,
|
||||
116,
|
||||
117,
|
||||
|
||||
28,
|
||||
26,
|
||||
31,
|
||||
51,
|
||||
|
||||
0,
|
||||
},
|
||||
{
|
||||
BAND_CBAND,
|
||||
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
|
||||
* P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
|
||||
* P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
|
||||
(0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
|
||||
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
|
||||
|
||||
787,
|
||||
10,
|
||||
|
||||
0,
|
||||
118,
|
||||
|
||||
0,
|
||||
3530,
|
||||
1,
|
||||
5,
|
||||
|
||||
0,
|
||||
0,
|
||||
|
||||
65535,
|
||||
0,
|
||||
|
||||
0,
|
||||
32,
|
||||
114,
|
||||
143,
|
||||
144,
|
||||
114,
|
||||
227,
|
||||
116,
|
||||
117,
|
||||
|
||||
28,
|
||||
26,
|
||||
31,
|
||||
51,
|
||||
|
||||
0,
|
||||
}
|
||||
};
|
||||
|
||||
static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
|
||||
54000, 13500,
|
||||
1, 18, 3, 1, 0,
|
||||
0, 0, 1, 1, 2,
|
||||
(3 << 14) | (1 << 12) | (599 << 0),
|
||||
(0 << 25) | 0,
|
||||
20199727,
|
||||
12000000,
|
||||
};
|
||||
|
||||
static int dib8090_get_adc_power(struct dvb_frontend *fe)
|
||||
{
|
||||
return dib8000_get_adc_power(fe, 1);
|
||||
}
|
||||
|
||||
static struct dib8000_config dib809x_dib8000_config = {
|
||||
.output_mpeg2_in_188_bytes = 1,
|
||||
|
||||
.agc_config_count = 2,
|
||||
.agc = dib8090_agc_config,
|
||||
.agc_control = dib0090_dcc_freq,
|
||||
.pll = &dib8090_pll_config_12mhz,
|
||||
.tuner_is_baseband = 1,
|
||||
|
||||
.gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
|
||||
.gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
|
||||
.gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
|
||||
|
||||
.hostbus_diversity = 1,
|
||||
.div_cfg = 0x31,
|
||||
.output_mode = OUTMODE_MPEG2_FIFO,
|
||||
.drives = 0x2d98,
|
||||
.diversity_delay = 144,
|
||||
.refclksel = 3,
|
||||
};
|
||||
|
||||
static struct dib0090_config dib809x_dib0090_config = {
|
||||
.io.pll_bypass = 1,
|
||||
.io.pll_range = 1,
|
||||
.io.pll_prediv = 1,
|
||||
.io.pll_loopdiv = 20,
|
||||
.io.adc_clock_ratio = 8,
|
||||
.io.pll_int_loop_filt = 0,
|
||||
.io.clock_khz = 12000,
|
||||
.reset = dib80xx_tuner_reset,
|
||||
.sleep = dib80xx_tuner_sleep,
|
||||
.clkouttobamse = 1,
|
||||
.analog_output = 1,
|
||||
.i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
|
||||
.wbd_vhf_offset = 100,
|
||||
.wbd_cband_offset = 450,
|
||||
.use_pwm_agc = 1,
|
||||
.clkoutdrive = 1,
|
||||
.get_adc_power = dib8090_get_adc_power,
|
||||
.freq_offset_khz_uhf = 0,
|
||||
.freq_offset_khz_vhf = -143,
|
||||
};
|
||||
|
||||
static int dib8096_set_param_override(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *fep)
|
||||
{
|
||||
struct dvb_usb_adapter *adap = fe->dvb->priv;
|
||||
struct dib0700_adapter_state *state = adap->priv;
|
||||
u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
|
||||
u16 offset;
|
||||
int ret = 0;
|
||||
enum frontend_tune_state tune_state = CT_SHUTDOWN;
|
||||
u16 ltgain, rf_gain_limit;
|
||||
|
||||
ret = state->set_param_save(fe, fep);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (band) {
|
||||
case BAND_VHF:
|
||||
offset = 100;
|
||||
break;
|
||||
case BAND_UHF:
|
||||
offset = 550;
|
||||
break;
|
||||
default:
|
||||
offset = 0;
|
||||
break;
|
||||
}
|
||||
offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
|
||||
dib8000_set_wbd_ref(fe, offset);
|
||||
|
||||
|
||||
if (band == BAND_CBAND) {
|
||||
deb_info("tuning in CBAND - soft-AGC startup\n");
|
||||
/* TODO specific wbd target for dib0090 - needed for startup ? */
|
||||
dib0090_set_tune_state(fe, CT_AGC_START);
|
||||
do {
|
||||
ret = dib0090_gain_control(fe);
|
||||
msleep(ret);
|
||||
tune_state = dib0090_get_tune_state(fe);
|
||||
if (tune_state == CT_AGC_STEP_0)
|
||||
dib8000_set_gpio(fe, 6, 0, 1);
|
||||
else if (tune_state == CT_AGC_STEP_1) {
|
||||
dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain);
|
||||
if (rf_gain_limit == 0)
|
||||
dib8000_set_gpio(fe, 6, 0, 0);
|
||||
}
|
||||
} while (tune_state < CT_AGC_STOP);
|
||||
dib0090_pwm_gain_reset(fe);
|
||||
dib8000_pwm_agc_reset(fe);
|
||||
dib8000_set_tune_state(fe, CT_DEMOD_START);
|
||||
} else {
|
||||
deb_info("not tuning in CBAND - standard AGC startup\n");
|
||||
dib0090_pwm_gain_reset(fe);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct dib0700_adapter_state *st = adap->priv;
|
||||
struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
|
||||
|
||||
if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
st->set_param_save = adap->fe->ops.tuner_ops.set_params;
|
||||
adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
|
||||
msleep(10);
|
||||
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
|
||||
dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
|
||||
|
||||
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
|
||||
|
||||
dib0700_ctrl_clock(adap->dev, 72, 1);
|
||||
|
||||
msleep(10);
|
||||
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
|
||||
msleep(10);
|
||||
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
|
||||
|
||||
dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
|
||||
|
||||
adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config);
|
||||
|
||||
return adap->fe == NULL ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
/* STK7070PD */
|
||||
static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
|
||||
|
@ -1929,14 +2176,17 @@ struct usb_device_id dib0700_usb_id_table[] = {
|
|||
{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
|
||||
/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
|
||||
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
|
||||
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
|
||||
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
|
||||
{ USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV73ESE) },
|
||||
{ USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV282E) },
|
||||
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
|
||||
/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
|
||||
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
|
||||
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
|
||||
{ USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
|
||||
{ USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
|
||||
/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
|
||||
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
|
||||
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
|
||||
{ 0 } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
|
||||
|
@ -2238,11 +2488,11 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
{ NULL },
|
||||
},
|
||||
{ "Pinnacle PCTV 73e SE",
|
||||
{ &dib0700_usb_id_table[57], NULL },
|
||||
{ &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "Pinnacle PCTV 282e",
|
||||
{ &dib0700_usb_id_table[58], NULL },
|
||||
{ &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
},
|
||||
|
@ -2471,8 +2721,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = stk807x_pid_filter,
|
||||
.pid_filter_ctrl = stk807x_pid_filter_ctrl,
|
||||
.pid_filter = stk80xx_pid_filter,
|
||||
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
||||
.frontend_attach = stk807x_frontend_attach,
|
||||
.tuner_attach = dib807x_tuner_attach,
|
||||
|
||||
|
@ -2510,8 +2760,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = stk807x_pid_filter,
|
||||
.pid_filter_ctrl = stk807x_pid_filter_ctrl,
|
||||
.pid_filter = stk80xx_pid_filter,
|
||||
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
||||
.frontend_attach = stk807xpvr_frontend_attach0,
|
||||
.tuner_attach = dib807x_tuner_attach,
|
||||
|
||||
|
@ -2523,8 +2773,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = stk807x_pid_filter,
|
||||
.pid_filter_ctrl = stk807x_pid_filter_ctrl,
|
||||
.pid_filter = stk80xx_pid_filter,
|
||||
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
||||
.frontend_attach = stk807xpvr_frontend_attach1,
|
||||
.tuner_attach = dib807x_tuner_attach,
|
||||
|
||||
|
@ -2543,6 +2793,37 @@ struct dvb_usb_device_properties dib0700_devices[] = {
|
|||
},
|
||||
},
|
||||
|
||||
.rc_interval = DEFAULT_RC_INTERVAL,
|
||||
.rc_key_map = dib0700_rc_keys,
|
||||
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
|
||||
.rc_query = dib0700_rc_query
|
||||
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
|
||||
.num_adapters = 1,
|
||||
.adapter = {
|
||||
{
|
||||
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
|
||||
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
|
||||
.pid_filter_count = 32,
|
||||
.pid_filter = stk80xx_pid_filter,
|
||||
.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
|
||||
.frontend_attach = stk809x_frontend_attach,
|
||||
.tuner_attach = dib809x_tuner_attach,
|
||||
|
||||
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
|
||||
|
||||
.size_of_priv =
|
||||
sizeof(struct dib0700_adapter_state),
|
||||
},
|
||||
},
|
||||
|
||||
.num_device_descs = 1,
|
||||
.devices = {
|
||||
{ "DiBcom STK8096GP reference design",
|
||||
{ &dib0700_usb_id_table[67], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
},
|
||||
|
||||
.rc_interval = DEFAULT_RC_INTERVAL,
|
||||
.rc_key_map = dib0700_rc_keys,
|
||||
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
|
||||
|
|
|
@ -142,8 +142,13 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
|
|||
} else if ((msg[i].flags & I2C_M_RD) == 0) {
|
||||
if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
} else if (msg[i].addr != 0x50) {
|
||||
/* 0x50 is the address of the eeprom - we need to protect it
|
||||
* from dibusb's bad i2c implementation: reads without
|
||||
* writing the offset before are forbidden */
|
||||
if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
|
@ -243,6 +248,12 @@ static struct dib3000mc_config mod3000p_dib3000p_config = {
|
|||
|
||||
int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
|
||||
adap->dev->udev->descriptor.idProduct ==
|
||||
USB_PID_LITEON_DVB_T_WARM) {
|
||||
msleep(1000);
|
||||
}
|
||||
|
||||
if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL ||
|
||||
(adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) {
|
||||
if (adap->priv != NULL) {
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#define USB_VID_MSI_2 0x1462
|
||||
#define USB_VID_OPERA1 0x695c
|
||||
#define USB_VID_PINNACLE 0x2304
|
||||
#define USB_VID_PCTV 0x2013
|
||||
#define USB_VID_PIXELVIEW 0x1554
|
||||
#define USB_VID_TECHNOTREND 0x0b48
|
||||
#define USB_VID_TERRATEC 0x0ccd
|
||||
|
@ -101,6 +102,7 @@
|
|||
#define USB_PID_DIBCOM_STK7070PD 0x1ebe
|
||||
#define USB_PID_DIBCOM_STK807XP 0x1f90
|
||||
#define USB_PID_DIBCOM_STK807XPVR 0x1f98
|
||||
#define USB_PID_DIBCOM_STK8096GP 0x1fa0
|
||||
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
|
||||
#define USB_PID_DIBCOM_STK7770P 0x1e80
|
||||
#define USB_PID_DPOSH_M9206_COLD 0x9206
|
||||
|
@ -211,6 +213,7 @@
|
|||
#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
|
||||
#define USB_PID_PINNACLE_PCTV73A 0x0243
|
||||
#define USB_PID_PINNACLE_PCTV73ESE 0x0245
|
||||
#define USB_PID_PINNACLE_PCTV74E 0x0246
|
||||
#define USB_PID_PINNACLE_PCTV282E 0x0248
|
||||
#define USB_PID_PIXELVIEW_SBTVD 0x5010
|
||||
#define USB_PID_PCTV_200E 0x020e
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#include "tda1002x.h"
|
||||
#include "mt312.h"
|
||||
#include "zl10039.h"
|
||||
#include "ds3000.h"
|
||||
#include "stv0900.h"
|
||||
#include "stv6110.h"
|
||||
#include "stb6100.h"
|
||||
#include "stb6100_proc.h"
|
||||
|
||||
#ifndef USB_PID_DW2102
|
||||
#define USB_PID_DW2102 0x2102
|
||||
|
@ -37,12 +42,20 @@
|
|||
#define USB_PID_CINERGY_S 0x0064
|
||||
#endif
|
||||
|
||||
#ifndef USB_PID_TEVII_S630
|
||||
#define USB_PID_TEVII_S630 0xd630
|
||||
#endif
|
||||
|
||||
#ifndef USB_PID_TEVII_S650
|
||||
#define USB_PID_TEVII_S650 0xd650
|
||||
#endif
|
||||
|
||||
#ifndef USB_PID_TEVII_S630
|
||||
#define USB_PID_TEVII_S630 0xd630
|
||||
#ifndef USB_PID_TEVII_S660
|
||||
#define USB_PID_TEVII_S660 0xd660
|
||||
#endif
|
||||
|
||||
#ifndef USB_PID_PROF_1100
|
||||
#define USB_PID_PROF_1100 0xb012
|
||||
#endif
|
||||
|
||||
#define DW210X_READ_MSG 0
|
||||
|
@ -55,6 +68,10 @@
|
|||
#define DW2102_VOLTAGE_CTRL (0x1800)
|
||||
#define DW2102_RC_QUERY (0x1a00)
|
||||
|
||||
#define err_str "did not find the firmware file. (%s) " \
|
||||
"Please see linux/Documentation/dvb/ for more details " \
|
||||
"on firmware-problems."
|
||||
|
||||
struct dvb_usb_rc_keys_table {
|
||||
struct dvb_usb_rc_key *rc_keys;
|
||||
int rc_keys_size;
|
||||
|
@ -71,6 +88,12 @@ static int ir_keymap;
|
|||
module_param_named(keymap, ir_keymap, int, 0644);
|
||||
MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ...");
|
||||
|
||||
/* demod probe */
|
||||
static int demod_probe = 1;
|
||||
module_param_named(demod, demod_probe, int, 0644);
|
||||
MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
|
||||
"4=stv0903+stb6100(or-able)).");
|
||||
|
||||
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
||||
|
||||
static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
|
||||
|
@ -183,7 +206,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
|
|||
switch (num) {
|
||||
case 2:
|
||||
/* read si2109 register by number */
|
||||
buf6[0] = 0xd0;
|
||||
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,
|
||||
|
@ -198,7 +221,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
|
|||
switch (msg[0].addr) {
|
||||
case 0x68:
|
||||
/* write to si2109 register */
|
||||
buf6[0] = 0xd0;
|
||||
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,
|
||||
|
@ -239,7 +262,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
|||
/* read */
|
||||
/* first write first register number */
|
||||
u8 ibuf[msg[1].len + 2], obuf[3];
|
||||
obuf[0] = 0xd0;
|
||||
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,
|
||||
|
@ -256,7 +279,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
|||
case 0x68: {
|
||||
/* write to register */
|
||||
u8 obuf[msg[0].len + 2];
|
||||
obuf[0] = 0xd0;
|
||||
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,
|
||||
|
@ -266,7 +289,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
|
|||
case 0x61: {
|
||||
/* write to tuner */
|
||||
u8 obuf[msg[0].len + 2];
|
||||
obuf[0] = 0xc2;
|
||||
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,
|
||||
|
@ -301,78 +324,78 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i
|
|||
{
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
int ret = 0;
|
||||
int len, i;
|
||||
int len, i, j;
|
||||
|
||||
if (!d)
|
||||
return -ENODEV;
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
switch (num) {
|
||||
case 2: {
|
||||
/* read */
|
||||
/* first write first register number */
|
||||
u8 ibuf[msg[1].len + 2], obuf[3];
|
||||
obuf[0] = 0xaa;
|
||||
obuf[1] = msg[0].len;
|
||||
obuf[2] = msg[0].buf[0];
|
||||
ret = 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, 0xab , 0,
|
||||
ibuf, msg[1].len + 2, DW210X_READ_MSG);
|
||||
memcpy(msg[1].buf, ibuf + 2, msg[1].len);
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
switch (msg[0].addr) {
|
||||
case 0x55: {
|
||||
if (msg[0].buf[0] == 0xf7) {
|
||||
/* firmware */
|
||||
/* Write in small blocks */
|
||||
u8 obuf[19];
|
||||
obuf[0] = 0xaa;
|
||||
obuf[1] = 0x11;
|
||||
obuf[2] = 0xf7;
|
||||
len = msg[0].len - 1;
|
||||
i = 1;
|
||||
do {
|
||||
memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
|
||||
i += 16;
|
||||
len -= 16;
|
||||
} while (len > 0);
|
||||
} else {
|
||||
/* write to register */
|
||||
u8 obuf[msg[0].len + 2];
|
||||
obuf[0] = 0xaa;
|
||||
obuf[1] = msg[0].len;
|
||||
memcpy(obuf + 2, msg[0].buf, msg[0].len);
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < num; j++) {
|
||||
switch (msg[j].addr) {
|
||||
case(DW2102_RC_QUERY): {
|
||||
u8 ibuf[2];
|
||||
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
ibuf, 2, DW210X_READ_MSG);
|
||||
memcpy(msg[0].buf, ibuf , 2);
|
||||
memcpy(msg[j].buf, ibuf , 2);
|
||||
break;
|
||||
}
|
||||
case(DW2102_VOLTAGE_CTRL): {
|
||||
u8 obuf[2];
|
||||
obuf[0] = 0x30;
|
||||
obuf[1] = msg[0].buf[0];
|
||||
obuf[1] = msg[j].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
|
||||
obuf, 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
/*case 0x55: cx24116
|
||||
case 0x6a: stv0903
|
||||
case 0x68: ds3000, stv0903
|
||||
case 0x60: ts2020, stv6110, stb6100 */
|
||||
default: {
|
||||
if (msg[j].flags == I2C_M_RD) {
|
||||
/* read registers */
|
||||
u8 ibuf[msg[j].len + 2];
|
||||
ret = dw210x_op_rw(d->udev, 0xc3,
|
||||
(msg[j].addr << 1) + 1, 0,
|
||||
ibuf, msg[j].len + 2,
|
||||
DW210X_READ_MSG);
|
||||
memcpy(msg[j].buf, ibuf + 2, msg[j].len);
|
||||
mdelay(10);
|
||||
} else if (((msg[j].buf[0] == 0xb0) &&
|
||||
(msg[j].addr == 0x68)) ||
|
||||
((msg[j].buf[0] == 0xf7) &&
|
||||
(msg[j].addr == 0x55))) {
|
||||
/* write firmware */
|
||||
u8 obuf[19];
|
||||
obuf[0] = msg[j].addr << 1;
|
||||
obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
|
||||
obuf[2] = msg[j].buf[0];
|
||||
len = msg[j].len - 1;
|
||||
i = 1;
|
||||
do {
|
||||
memcpy(obuf + 3, msg[j].buf + i,
|
||||
(len > 16 ? 16 : len));
|
||||
ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
|
||||
obuf, (len > 16 ? 16 : len) + 3,
|
||||
DW210X_WRITE_MSG);
|
||||
i += 16;
|
||||
len -= 16;
|
||||
} while (len > 0);
|
||||
} else {
|
||||
/* write registers */
|
||||
u8 obuf[msg[j].len + 2];
|
||||
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,
|
||||
obuf, msg[j].len + 2,
|
||||
DW210X_WRITE_MSG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
|
@ -442,63 +465,85 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
|||
return num;
|
||||
}
|
||||
|
||||
static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
|
||||
static int s6x0_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)
|
||||
return -ENODEV;
|
||||
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
switch (num) {
|
||||
case 2: { /* read */
|
||||
u8 ibuf[msg[1].len], obuf[3];
|
||||
obuf[0] = msg[1].len;
|
||||
obuf[1] = (msg[0].addr << 1);
|
||||
obuf[2] = msg[0].buf[0];
|
||||
|
||||
ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
|
||||
obuf, 3, DW210X_WRITE_MSG);
|
||||
msleep(5);
|
||||
ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
|
||||
ibuf, msg[1].len, DW210X_READ_MSG);
|
||||
memcpy(msg[1].buf, ibuf, msg[1].len);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
switch (msg[0].addr) {
|
||||
case 0x60:
|
||||
case 0x0e: {
|
||||
/* write to zl10313, zl10039 register, */
|
||||
u8 obuf[msg[0].len + 2];
|
||||
obuf[0] = msg[0].len + 1;
|
||||
obuf[1] = (msg[0].addr << 1);
|
||||
memcpy(obuf + 2, msg[0].buf, msg[0].len);
|
||||
ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
|
||||
obuf, msg[0].len + 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < num; j++) {
|
||||
switch (msg[j].addr) {
|
||||
case (DW2102_RC_QUERY): {
|
||||
u8 ibuf[4];
|
||||
ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
|
||||
ibuf, 4, DW210X_READ_MSG);
|
||||
msg[0].buf[0] = ibuf[3];
|
||||
memcpy(msg[j].buf, ibuf + 1, 2);
|
||||
break;
|
||||
}
|
||||
case (DW2102_VOLTAGE_CTRL): {
|
||||
u8 obuf[2];
|
||||
obuf[0] = 0x03;
|
||||
obuf[1] = msg[0].buf[0];
|
||||
obuf[0] = 3;
|
||||
obuf[1] = msg[j].buf[0];
|
||||
ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
|
||||
obuf, 2, DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
/*case 0x55: cx24116
|
||||
case 0x6a: stv0903
|
||||
case 0x68: ds3000, stv0903
|
||||
case 0x60: ts2020, stv6110, stb6100
|
||||
case 0xa0: eeprom */
|
||||
default: {
|
||||
if (msg[j].flags == I2C_M_RD) {
|
||||
/* read registers */
|
||||
u8 ibuf[msg[j].len];
|
||||
ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
|
||||
ibuf, msg[j].len,
|
||||
DW210X_READ_MSG);
|
||||
memcpy(msg[j].buf, ibuf, msg[j].len);
|
||||
break;
|
||||
} else if ((msg[j].buf[0] == 0xb0) &&
|
||||
(msg[j].addr == 0x68)) {
|
||||
/* write firmware */
|
||||
u8 obuf[19];
|
||||
obuf[0] = (msg[j].len > 16 ?
|
||||
18 : msg[j].len + 1);
|
||||
obuf[1] = msg[j].addr << 1;
|
||||
obuf[2] = msg[j].buf[0];
|
||||
len = msg[j].len - 1;
|
||||
i = 1;
|
||||
do {
|
||||
memcpy(obuf + 3, msg[j].buf + i,
|
||||
(len > 16 ? 16 : len));
|
||||
ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
|
||||
obuf, (len > 16 ? 16 : len) + 3,
|
||||
DW210X_WRITE_MSG);
|
||||
i += 16;
|
||||
len -= 16;
|
||||
} while (len > 0);
|
||||
} else {
|
||||
/* write registers */
|
||||
u8 obuf[msg[j].len + 2];
|
||||
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,
|
||||
(num > 1 ? 0x90 : 0x80), 0, 0,
|
||||
obuf, msg[j].len + 2,
|
||||
DW210X_WRITE_MSG);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
msleep(3);
|
||||
}
|
||||
|
||||
mutex_unlock(&d->i2c_mutex);
|
||||
|
@ -535,8 +580,8 @@ static struct i2c_algorithm dw3101_i2c_algo = {
|
|||
.functionality = dw210x_i2c_func,
|
||||
};
|
||||
|
||||
static struct i2c_algorithm s630_i2c_algo = {
|
||||
.master_xfer = s630_i2c_transfer,
|
||||
static struct i2c_algorithm s6x0_i2c_algo = {
|
||||
.master_xfer = s6x0_i2c_transfer,
|
||||
.functionality = dw210x_i2c_func,
|
||||
};
|
||||
|
||||
|
@ -564,25 +609,34 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
|
|||
return 0;
|
||||
};
|
||||
|
||||
static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
|
||||
static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
|
||||
{
|
||||
int i, ret;
|
||||
u8 buf[3], eeprom[256], eepromline[16];
|
||||
u8 ibuf[] = { 0 }, obuf[] = { 0 };
|
||||
u8 eeprom[256], eepromline[16];
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = 0xa0 >> 1,
|
||||
.flags = 0,
|
||||
.buf = obuf,
|
||||
.len = 1,
|
||||
}, {
|
||||
.addr = 0xa0 >> 1,
|
||||
.flags = I2C_M_RD,
|
||||
.buf = ibuf,
|
||||
.len = 1,
|
||||
}
|
||||
};
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
buf[0] = 1;
|
||||
buf[1] = 0xa0;
|
||||
buf[2] = i;
|
||||
ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
|
||||
buf, 3, DW210X_WRITE_MSG);
|
||||
ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
|
||||
buf, 1, DW210X_READ_MSG);
|
||||
if (ret < 0) {
|
||||
obuf[0] = i;
|
||||
ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
|
||||
if (ret != 2) {
|
||||
err("read eeprom failed.");
|
||||
return -1;
|
||||
} else {
|
||||
eepromline[i % 16] = buf[0];
|
||||
eeprom[i] = buf[0];
|
||||
eepromline[i % 16] = ibuf[0];
|
||||
eeprom[i] = ibuf[0];
|
||||
}
|
||||
|
||||
if ((i % 16) == 15) {
|
||||
|
@ -644,19 +698,104 @@ static struct mt312_config zl313_config = {
|
|||
.demod_address = 0x0e,
|
||||
};
|
||||
|
||||
static struct ds3000_config dw2104_ds3000_config = {
|
||||
.demod_address = 0x68,
|
||||
};
|
||||
|
||||
static struct stv0900_config dw2104a_stv0900_config = {
|
||||
.demod_address = 0x6a,
|
||||
.demod_mode = 0,
|
||||
.xtal = 27000000,
|
||||
.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
|
||||
.diseqc_mode = 2,/* 2/3 PWM */
|
||||
.tun1_maddress = 0,/* 0x60 */
|
||||
.tun1_adc = 0,/* 2 Vpp */
|
||||
.path1_mode = 3,
|
||||
};
|
||||
|
||||
static struct stb6100_config dw2104a_stb6100_config = {
|
||||
.tuner_address = 0x60,
|
||||
.refclock = 27000000,
|
||||
};
|
||||
|
||||
static struct stv0900_config dw2104_stv0900_config = {
|
||||
.demod_address = 0x68,
|
||||
.demod_mode = 0,
|
||||
.xtal = 8000000,
|
||||
.clkmode = 3,
|
||||
.diseqc_mode = 2,
|
||||
.tun1_maddress = 0,
|
||||
.tun1_adc = 1,/* 1 Vpp */
|
||||
.path1_mode = 3,
|
||||
};
|
||||
|
||||
static struct stv6110_config dw2104_stv6110_config = {
|
||||
.i2c_address = 0x60,
|
||||
.mclk = 16000000,
|
||||
.clk_div = 1,
|
||||
};
|
||||
|
||||
static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
|
||||
{
|
||||
if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
|
||||
&d->dev->i2c_adap)) != NULL) {
|
||||
struct dvb_tuner_ops *tuner_ops = NULL;
|
||||
|
||||
if (demod_probe & 4) {
|
||||
d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
|
||||
&d->dev->i2c_adap, 0);
|
||||
if (d->fe != NULL) {
|
||||
if (dvb_attach(stb6100_attach, d->fe,
|
||||
&dw2104a_stb6100_config,
|
||||
&d->dev->i2c_adap)) {
|
||||
tuner_ops = &d->fe->ops.tuner_ops;
|
||||
tuner_ops->set_frequency = stb6100_set_freq;
|
||||
tuner_ops->get_frequency = stb6100_get_freq;
|
||||
tuner_ops->set_bandwidth = stb6100_set_bandw;
|
||||
tuner_ops->get_bandwidth = stb6100_get_bandw;
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached STV0900+STB6100!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (demod_probe & 2) {
|
||||
d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
|
||||
&d->dev->i2c_adap, 0);
|
||||
if (d->fe != NULL) {
|
||||
if (dvb_attach(stv6110_attach, d->fe,
|
||||
&dw2104_stv6110_config,
|
||||
&d->dev->i2c_adap)) {
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached STV0900+STV6110A!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (demod_probe & 1) {
|
||||
d->fe = dvb_attach(cx24116_attach, &dw2104_config,
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe != NULL) {
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached cx24116!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe != NULL) {
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached cx24116!\n");
|
||||
info("Attached DS3000!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static struct dvb_usb_device_properties dw2102_properties;
|
||||
static struct dvb_usb_device_properties dw2104_properties;
|
||||
static struct dvb_usb_device_properties s6x0_properties;
|
||||
|
||||
static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
|
||||
{
|
||||
|
@ -670,14 +809,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
|
||||
/*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
|
||||
d->fe = dvb_attach(stv0288_attach, &earda_config,
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe != NULL) {
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached stv0288!\n");
|
||||
return 0;
|
||||
if (dvb_attach(stb6000_attach, d->fe, 0x61,
|
||||
&d->dev->i2c_adap)) {
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached stv0288!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -705,15 +847,38 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int s630_frontend_attach(struct dvb_usb_adapter *d)
|
||||
static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
|
||||
{
|
||||
d->fe = dvb_attach(mt312_attach, &zl313_config,
|
||||
&d->dev->i2c_adap);
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe != NULL) {
|
||||
if (dvb_attach(zl10039_attach, d->fe, 0x60,
|
||||
&d->dev->i2c_adap)) {
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached zl100313+zl10039!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
d->fe = dvb_attach(stv0288_attach, &earda_config,
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe != NULL) {
|
||||
if (dvb_attach(stb6000_attach, d->fe, 0x61,
|
||||
&d->dev->i2c_adap)) {
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached stv0288+stb6000!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe != NULL) {
|
||||
d->fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached zl10313!\n");
|
||||
info("Attached ds3000+ds2020!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -724,14 +889,6 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
dvb_attach(stb6000_attach, adap->fe, 0x61,
|
||||
&adap->dev->i2c_adap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
dvb_attach(dvb_pll_attach, adap->fe, 0x60,
|
||||
|
@ -740,14 +897,6 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
dvb_attach(zl10039_attach, adap->fe, 0x60,
|
||||
&adap->dev->i2c_adap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_usb_rc_key dw210x_rc_keys[] = {
|
||||
{ 0xf80a, KEY_Q }, /*power*/
|
||||
{ 0xf80c, KEY_M }, /*mute*/
|
||||
|
@ -922,6 +1071,8 @@ static struct usb_device_id dw2102_table[] = {
|
|||
{USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
|
||||
{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
|
||||
{USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
|
||||
{USB_DEVICE(0x3011, USB_PID_PROF_1100)},
|
||||
{USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -935,15 +1086,13 @@ static int dw2102_load_firmware(struct usb_device *dev,
|
|||
u8 reset;
|
||||
u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
|
||||
const struct firmware *fw;
|
||||
const char *filename = "dvb-usb-dw2101.fw";
|
||||
const char *fw_2101 = "dvb-usb-dw2101.fw";
|
||||
|
||||
switch (dev->descriptor.idProduct) {
|
||||
case 0x2101:
|
||||
ret = request_firmware(&fw, filename, &dev->dev);
|
||||
ret = request_firmware(&fw, fw_2101, &dev->dev);
|
||||
if (ret != 0) {
|
||||
err("did not find the firmware file. (%s) "
|
||||
"Please see linux/Documentation/dvb/ for more details "
|
||||
"on firmware-problems.", filename);
|
||||
err(err_str, fw_2101);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
@ -983,6 +1132,11 @@ static int dw2102_load_firmware(struct usb_device *dev,
|
|||
}
|
||||
/* init registers */
|
||||
switch (dev->descriptor.idProduct) {
|
||||
case USB_PID_PROF_1100:
|
||||
s6x0_properties.rc_key_map = tbs_rc_keys;
|
||||
s6x0_properties.rc_key_map_size =
|
||||
ARRAY_SIZE(tbs_rc_keys);
|
||||
break;
|
||||
case USB_PID_TEVII_S650:
|
||||
dw2104_properties.rc_key_map = tevii_rc_keys;
|
||||
dw2104_properties.rc_key_map_size =
|
||||
|
@ -1021,7 +1175,6 @@ static int dw2102_load_firmware(struct usb_device *dev,
|
|||
DW210X_READ_MSG);
|
||||
if (reset16[2] == 0x11) {
|
||||
dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
|
||||
dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1184,13 +1337,13 @@ static struct dvb_usb_device_properties dw3101_properties = {
|
|||
}
|
||||
};
|
||||
|
||||
static struct dvb_usb_device_properties s630_properties = {
|
||||
static struct dvb_usb_device_properties s6x0_properties = {
|
||||
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
|
||||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
.firmware = "dvb-usb-s630.fw",
|
||||
.no_reconnect = 1,
|
||||
|
||||
.i2c_algo = &s630_i2c_algo,
|
||||
.i2c_algo = &s6x0_i2c_algo,
|
||||
.rc_key_map = tevii_rc_keys,
|
||||
.rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
|
||||
.rc_interval = 150,
|
||||
|
@ -1199,12 +1352,12 @@ static struct dvb_usb_device_properties s630_properties = {
|
|||
.generic_bulk_ctrl_endpoint = 0x81,
|
||||
.num_adapters = 1,
|
||||
.download_firmware = dw2102_load_firmware,
|
||||
.read_mac_address = s630_read_mac_address,
|
||||
.read_mac_address = s6x0_read_mac_address,
|
||||
.adapter = {
|
||||
{
|
||||
.frontend_attach = s630_frontend_attach,
|
||||
.frontend_attach = s6x0_frontend_attach,
|
||||
.streaming_ctrl = NULL,
|
||||
.tuner_attach = s630_zl10039_tuner_attach,
|
||||
.tuner_attach = NULL,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 8,
|
||||
|
@ -1217,12 +1370,20 @@ static struct dvb_usb_device_properties s630_properties = {
|
|||
},
|
||||
}
|
||||
},
|
||||
.num_device_descs = 1,
|
||||
.num_device_descs = 3,
|
||||
.devices = {
|
||||
{"TeVii S630 USB",
|
||||
{&dw2102_table[6], NULL},
|
||||
{NULL},
|
||||
},
|
||||
{"Prof 1100 USB ",
|
||||
{&dw2102_table[7], NULL},
|
||||
{NULL},
|
||||
},
|
||||
{"TeVii S660 USB",
|
||||
{&dw2102_table[8], NULL},
|
||||
{NULL},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1235,10 +1396,10 @@ static int dw2102_probe(struct usb_interface *intf,
|
|||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, &dw3101_properties,
|
||||
THIS_MODULE, NULL, adapter_nr) ||
|
||||
0 == dvb_usb_device_init(intf, &s630_properties,
|
||||
THIS_MODULE, NULL, adapter_nr)) {
|
||||
0 == dvb_usb_device_init(intf, &s6x0_properties,
|
||||
THIS_MODULE, NULL, adapter_nr))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -1269,6 +1430,7 @@ module_exit(dw2102_module_exit);
|
|||
MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
|
||||
MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
|
||||
" DVB-C 3101 USB2.0,"
|
||||
" TeVii S600, S630, S650 USB2.0 devices");
|
||||
" TeVii S600, S630, S650, S660 USB2.0,"
|
||||
" Prof 1100 USB2.0 devices");
|
||||
MODULE_VERSION("0.1");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -134,11 +134,13 @@ static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
|
|||
deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
|
||||
state->frontend.ops.info.frequency_stepsize);
|
||||
/* freq -> oscilator frequency conversion. */
|
||||
/* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */
|
||||
/* add 400[1/7 MHZ] = 57.142857MHz. 57MHz for the IF, */
|
||||
/* 1/7MHz for center freq shift */
|
||||
/* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
|
||||
f = freq / state->frontend.ops.info.frequency_stepsize;
|
||||
f += 400;
|
||||
/* add 399[1/7 MHZ] = 57MHz for the IF */
|
||||
f += 399;
|
||||
/* add center frequency shift if necessary */
|
||||
if (f % 7 == 0)
|
||||
f++;
|
||||
pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
|
||||
pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
|
||||
pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
|
||||
|
|
|
@ -146,8 +146,8 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
|
|||
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DVBS:
|
||||
/* Only QPSK is supported for DVB-S */
|
||||
if (c->modulation != QPSK) {
|
||||
/* Allow QPSK and 8PSK (even for DVB-S) */
|
||||
if (c->modulation != QPSK && c->modulation != PSK_8) {
|
||||
deb_fe("%s: unsupported modulation selected (%d)\n",
|
||||
__func__, c->modulation);
|
||||
return -EOPNOTSUPP;
|
||||
|
|
|
@ -526,6 +526,15 @@ config DVB_TUNER_DIB0070
|
|||
This device is only used inside a SiP called together with a
|
||||
demodulator for now.
|
||||
|
||||
config DVB_TUNER_DIB0090
|
||||
tristate "DiBcom DiB0090 silicon base-band tuner"
|
||||
depends on I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon baseband tuner DiB0090 from DiBcom.
|
||||
This device is only used inside a SiP called together with a
|
||||
demodulator for now.
|
||||
|
||||
comment "SEC control devices for DVB-S"
|
||||
depends on DVB_CORE
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o
|
|||
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
|
||||
obj-$(CONFIG_DVB_TDA8261) += tda8261.o
|
||||
obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
|
||||
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
|
||||
|
|
|
@ -62,7 +62,7 @@ struct au8522_register_config {
|
|||
The values are as follows from left to right
|
||||
0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
|
||||
*/
|
||||
struct au8522_register_config filter_coef[] = {
|
||||
static const struct au8522_register_config filter_coef[] = {
|
||||
{AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
|
||||
{AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
|
||||
{AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
|
||||
|
@ -104,7 +104,7 @@ struct au8522_register_config filter_coef[] = {
|
|||
0="SIF" 1="ATVRF/ATVRF13"
|
||||
Note: the "ATVRF/ATVRF13" mode has never been tested
|
||||
*/
|
||||
struct au8522_register_config lpfilter_coef[] = {
|
||||
static const struct au8522_register_config lpfilter_coef[] = {
|
||||
{0x060b, {0x21, 0x0b} },
|
||||
{0x060c, {0xad, 0xad} },
|
||||
{0x060d, {0x70, 0xf0} },
|
||||
|
|
|
@ -49,21 +49,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
|
|||
#define DIB0070_P1G 0x03
|
||||
#define DIB0070S_P1A 0x02
|
||||
|
||||
enum frontend_tune_state {
|
||||
CT_TUNER_START = 10,
|
||||
CT_TUNER_STEP_0,
|
||||
CT_TUNER_STEP_1,
|
||||
CT_TUNER_STEP_2,
|
||||
CT_TUNER_STEP_3,
|
||||
CT_TUNER_STEP_4,
|
||||
CT_TUNER_STEP_5,
|
||||
CT_TUNER_STEP_6,
|
||||
CT_TUNER_STEP_7,
|
||||
CT_TUNER_STOP,
|
||||
};
|
||||
|
||||
#define FE_CALLBACK_TIME_NEVER 0xffffffff
|
||||
|
||||
struct dib0070_state {
|
||||
struct i2c_adapter *i2c;
|
||||
struct dvb_frontend *fe;
|
||||
|
@ -71,10 +56,10 @@ struct dib0070_state {
|
|||
u16 wbd_ff_offset;
|
||||
u8 revision;
|
||||
|
||||
enum frontend_tune_state tune_state;
|
||||
u32 current_rf;
|
||||
enum frontend_tune_state tune_state;
|
||||
u32 current_rf;
|
||||
|
||||
/* for the captrim binary search */
|
||||
/* for the captrim binary search */
|
||||
s8 step;
|
||||
u16 adc_diff;
|
||||
|
||||
|
@ -85,7 +70,7 @@ struct dib0070_state {
|
|||
const struct dib0070_tuning *current_tune_table_index;
|
||||
const struct dib0070_lna_match *lna_match;
|
||||
|
||||
u8 wbd_gain_current;
|
||||
u8 wbd_gain_current;
|
||||
u16 wbd_offset_3_3[2];
|
||||
};
|
||||
|
||||
|
@ -93,8 +78,8 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
|
|||
{
|
||||
u8 b[2];
|
||||
struct i2c_msg msg[2] = {
|
||||
{.addr = state->cfg->i2c_address,.flags = 0,.buf = ®,.len = 1},
|
||||
{.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2},
|
||||
{ .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 },
|
||||
{ .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 },
|
||||
};
|
||||
if (i2c_transfer(state->i2c, msg, 2) != 2) {
|
||||
printk(KERN_WARNING "DiB0070 I2C read failed\n");
|
||||
|
@ -106,7 +91,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
|
|||
static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
|
||||
{
|
||||
u8 b[3] = { reg, val >> 8, val & 0xff };
|
||||
struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 };
|
||||
struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
|
||||
if (i2c_transfer(state->i2c, &msg, 1) != 1) {
|
||||
printk(KERN_WARNING "DiB0070 I2C write failed\n");
|
||||
return -EREMOTEIO;
|
||||
|
@ -124,30 +109,30 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
|
|||
|
||||
static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
|
||||
|
||||
if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000)
|
||||
tmp |= (0 << 14);
|
||||
else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000)
|
||||
tmp |= (1 << 14);
|
||||
else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000)
|
||||
tmp |= (2 << 14);
|
||||
else
|
||||
tmp |= (3 << 14);
|
||||
if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
|
||||
tmp |= (0 << 14);
|
||||
else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
|
||||
tmp |= (1 << 14);
|
||||
else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
|
||||
tmp |= (2 << 14);
|
||||
else
|
||||
tmp |= (3 << 14);
|
||||
|
||||
dib0070_write_reg(state, 0x02, tmp);
|
||||
dib0070_write_reg(state, 0x02, tmp);
|
||||
|
||||
/* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
|
||||
if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
|
||||
u16 value = dib0070_read_reg(state, 0x17);
|
||||
/* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
|
||||
if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
|
||||
u16 value = dib0070_read_reg(state, 0x17);
|
||||
|
||||
dib0070_write_reg(state, 0x17, value & 0xfffc);
|
||||
tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
|
||||
dib0070_write_reg(state, 0x01, tmp | (60 << 9));
|
||||
dib0070_write_reg(state, 0x17, value & 0xfffc);
|
||||
tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
|
||||
dib0070_write_reg(state, 0x01, tmp | (60 << 9));
|
||||
|
||||
dib0070_write_reg(state, 0x17, value);
|
||||
}
|
||||
dib0070_write_reg(state, 0x17, value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -160,14 +145,14 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
|
|||
if (*tune_state == CT_TUNER_STEP_0) {
|
||||
|
||||
dib0070_write_reg(state, 0x0f, 0xed10);
|
||||
dib0070_write_reg(state, 0x17, 0x0034);
|
||||
dib0070_write_reg(state, 0x17, 0x0034);
|
||||
|
||||
dib0070_write_reg(state, 0x18, 0x0032);
|
||||
state->step = state->captrim = state->fcaptrim = 64;
|
||||
state->adc_diff = 3000;
|
||||
ret = 20;
|
||||
|
||||
*tune_state = CT_TUNER_STEP_1;
|
||||
*tune_state = CT_TUNER_STEP_1;
|
||||
} else if (*tune_state == CT_TUNER_STEP_1) {
|
||||
state->step /= 2;
|
||||
dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
|
||||
|
@ -178,7 +163,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
|
|||
|
||||
adc = dib0070_read_reg(state, 0x19);
|
||||
|
||||
dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024);
|
||||
dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
|
||||
|
||||
if (adc >= 400) {
|
||||
adc -= 400;
|
||||
|
@ -193,6 +178,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
|
|||
state->adc_diff = adc;
|
||||
state->fcaptrim = state->captrim;
|
||||
|
||||
|
||||
|
||||
}
|
||||
state->captrim += (step_sign * state->step);
|
||||
|
||||
|
@ -213,7 +200,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
|
|||
static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
|
||||
u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
|
||||
dprintk("CTRL_LO5: 0x%x", lo5);
|
||||
return dib0070_write_reg(state, 0x15, lo5);
|
||||
}
|
||||
|
@ -227,99 +214,99 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
|
|||
dib0070_write_reg(state, 0x1a, 0x0000);
|
||||
} else {
|
||||
dib0070_write_reg(state, 0x1b, 0x4112);
|
||||
if (state->cfg->vga_filter != 0) {
|
||||
dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
|
||||
dprintk("vga filter register is set to %x", state->cfg->vga_filter);
|
||||
} else
|
||||
dib0070_write_reg(state, 0x1a, 0x0009);
|
||||
if (state->cfg->vga_filter != 0) {
|
||||
dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
|
||||
dprintk("vga filter register is set to %x", state->cfg->vga_filter);
|
||||
} else
|
||||
dib0070_write_reg(state, 0x1a, 0x0009);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
|
||||
struct dib0070_tuning {
|
||||
u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
|
||||
u8 switch_trim;
|
||||
u8 vco_band;
|
||||
u8 hfdiv;
|
||||
u8 vco_multi;
|
||||
u8 presc;
|
||||
u8 wbdmux;
|
||||
u16 tuner_enable;
|
||||
u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
|
||||
u8 switch_trim;
|
||||
u8 vco_band;
|
||||
u8 hfdiv;
|
||||
u8 vco_multi;
|
||||
u8 presc;
|
||||
u8 wbdmux;
|
||||
u16 tuner_enable;
|
||||
};
|
||||
|
||||
struct dib0070_lna_match {
|
||||
u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
|
||||
u8 lna_band;
|
||||
u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
|
||||
u8 lna_band;
|
||||
};
|
||||
|
||||
static const struct dib0070_tuning dib0070s_tuning_table[] = {
|
||||
{570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800}, /* UHF */
|
||||
{700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800},
|
||||
{863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800},
|
||||
{1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND */
|
||||
{1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
|
||||
{2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
|
||||
{0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000}, /* SBAND */
|
||||
{ 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */
|
||||
{ 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
|
||||
{ 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
|
||||
{ 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */
|
||||
{ 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
|
||||
{ 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
|
||||
{ 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */
|
||||
};
|
||||
|
||||
static const struct dib0070_tuning dib0070_tuning_table[] = {
|
||||
{115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000}, /* FM below 92MHz cannot be tuned */
|
||||
{179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000}, /* VHF */
|
||||
{189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000},
|
||||
{250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000},
|
||||
{569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800}, /* UHF */
|
||||
{699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800},
|
||||
{863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800},
|
||||
{0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND or everything higher than UHF */
|
||||
{ 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */
|
||||
{ 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */
|
||||
{ 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
|
||||
{ 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
|
||||
{ 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */
|
||||
{ 699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800 },
|
||||
{ 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 },
|
||||
{ 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */
|
||||
};
|
||||
|
||||
static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
|
||||
{180000, 0}, /* VHF */
|
||||
{188000, 1},
|
||||
{196400, 2},
|
||||
{250000, 3},
|
||||
{550000, 0}, /* UHF */
|
||||
{590000, 1},
|
||||
{666000, 3},
|
||||
{864000, 5},
|
||||
{1500000, 0}, /* LBAND or everything higher than UHF */
|
||||
{1600000, 1},
|
||||
{2000000, 3},
|
||||
{0xffffffff, 7},
|
||||
{ 180000, 0 }, /* VHF */
|
||||
{ 188000, 1 },
|
||||
{ 196400, 2 },
|
||||
{ 250000, 3 },
|
||||
{ 550000, 0 }, /* UHF */
|
||||
{ 590000, 1 },
|
||||
{ 666000, 3 },
|
||||
{ 864000, 5 },
|
||||
{ 1500000, 0 }, /* LBAND or everything higher than UHF */
|
||||
{ 1600000, 1 },
|
||||
{ 2000000, 3 },
|
||||
{ 0xffffffff, 7 },
|
||||
};
|
||||
|
||||
static const struct dib0070_lna_match dib0070_lna[] = {
|
||||
{180000, 0}, /* VHF */
|
||||
{188000, 1},
|
||||
{196400, 2},
|
||||
{250000, 3},
|
||||
{550000, 2}, /* UHF */
|
||||
{650000, 3},
|
||||
{750000, 5},
|
||||
{850000, 6},
|
||||
{864000, 7},
|
||||
{1500000, 0}, /* LBAND or everything higher than UHF */
|
||||
{1600000, 1},
|
||||
{2000000, 3},
|
||||
{0xffffffff, 7},
|
||||
{ 180000, 0 }, /* VHF */
|
||||
{ 188000, 1 },
|
||||
{ 196400, 2 },
|
||||
{ 250000, 3 },
|
||||
{ 550000, 2 }, /* UHF */
|
||||
{ 650000, 3 },
|
||||
{ 750000, 5 },
|
||||
{ 850000, 6 },
|
||||
{ 864000, 7 },
|
||||
{ 1500000, 0 }, /* LBAND or everything higher than UHF */
|
||||
{ 1600000, 1 },
|
||||
{ 2000000, 3 },
|
||||
{ 0xffffffff, 7 },
|
||||
};
|
||||
|
||||
#define LPF 100 // define for the loop filter 100kHz by default 16-07-06
|
||||
#define LPF 100
|
||||
static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
|
||||
const struct dib0070_tuning *tune;
|
||||
const struct dib0070_lna_match *lna_match;
|
||||
const struct dib0070_tuning *tune;
|
||||
const struct dib0070_lna_match *lna_match;
|
||||
|
||||
enum frontend_tune_state *tune_state = &state->tune_state;
|
||||
int ret = 10; /* 1ms is the default delay most of the time */
|
||||
enum frontend_tune_state *tune_state = &state->tune_state;
|
||||
int ret = 10; /* 1ms is the default delay most of the time */
|
||||
|
||||
u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
|
||||
u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
|
||||
u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
|
||||
u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
|
||||
|
||||
#ifdef CONFIG_SYS_ISDBT
|
||||
if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
|
||||
if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
|
||||
if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
|
||||
&& (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
|
||||
|| (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
|
||||
|
@ -328,172 +315,180 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par
|
|||
&& (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
|
||||
freq += 850;
|
||||
#endif
|
||||
if (state->current_rf != freq) {
|
||||
|
||||
switch (state->revision) {
|
||||
case DIB0070S_P1A:
|
||||
tune = dib0070s_tuning_table;
|
||||
lna_match = dib0070_lna;
|
||||
break;
|
||||
default:
|
||||
tune = dib0070_tuning_table;
|
||||
if (state->cfg->flip_chip)
|
||||
lna_match = dib0070_lna_flip_chip;
|
||||
else
|
||||
lna_match = dib0070_lna;
|
||||
break;
|
||||
}
|
||||
while (freq > tune->max_freq) /* find the right one */
|
||||
tune++;
|
||||
while (freq > lna_match->max_freq) /* find the right one */
|
||||
lna_match++;
|
||||
|
||||
state->current_tune_table_index = tune;
|
||||
state->lna_match = lna_match;
|
||||
}
|
||||
|
||||
if (*tune_state == CT_TUNER_START) {
|
||||
dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
|
||||
if (state->current_rf != freq) {
|
||||
u8 REFDIV;
|
||||
u32 FBDiv, Rest, FREF, VCOF_kHz;
|
||||
u8 Den;
|
||||
|
||||
state->current_rf = freq;
|
||||
state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
|
||||
|
||||
|
||||
dib0070_write_reg(state, 0x17, 0x30);
|
||||
|
||||
|
||||
VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
|
||||
|
||||
switch (band) {
|
||||
case BAND_VHF:
|
||||
REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
|
||||
break;
|
||||
case BAND_FM:
|
||||
REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
|
||||
break;
|
||||
default:
|
||||
REFDIV = (u8) (state->cfg->clock_khz / 10000);
|
||||
break;
|
||||
}
|
||||
FREF = state->cfg->clock_khz / REFDIV;
|
||||
|
||||
|
||||
|
||||
switch (state->revision) {
|
||||
case DIB0070S_P1A:
|
||||
tune = dib0070s_tuning_table;
|
||||
lna_match = dib0070_lna;
|
||||
FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
|
||||
Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
|
||||
break;
|
||||
|
||||
case DIB0070_P1G:
|
||||
case DIB0070_P1F:
|
||||
default:
|
||||
tune = dib0070_tuning_table;
|
||||
if (state->cfg->flip_chip)
|
||||
lna_match = dib0070_lna_flip_chip;
|
||||
else
|
||||
lna_match = dib0070_lna;
|
||||
FBDiv = (freq / (FREF / 2));
|
||||
Rest = 2 * freq - FBDiv * FREF;
|
||||
break;
|
||||
}
|
||||
while (freq > tune->max_freq) /* find the right one */
|
||||
tune++;
|
||||
while (freq > lna_match->max_freq) /* find the right one */
|
||||
lna_match++;
|
||||
|
||||
state->current_tune_table_index = tune;
|
||||
state->lna_match = lna_match;
|
||||
}
|
||||
if (Rest < LPF)
|
||||
Rest = 0;
|
||||
else if (Rest < 2 * LPF)
|
||||
Rest = 2 * LPF;
|
||||
else if (Rest > (FREF - LPF)) {
|
||||
Rest = 0;
|
||||
FBDiv += 1;
|
||||
} else if (Rest > (FREF - 2 * LPF))
|
||||
Rest = FREF - 2 * LPF;
|
||||
Rest = (Rest * 6528) / (FREF / 10);
|
||||
|
||||
if (*tune_state == CT_TUNER_START) {
|
||||
dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
|
||||
if (state->current_rf != freq) {
|
||||
u8 REFDIV;
|
||||
u32 FBDiv, Rest, FREF, VCOF_kHz;
|
||||
u8 Den;
|
||||
|
||||
state->current_rf = freq;
|
||||
state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
|
||||
|
||||
dib0070_write_reg(state, 0x17, 0x30);
|
||||
|
||||
VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
|
||||
|
||||
switch (band) {
|
||||
case BAND_VHF:
|
||||
REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
|
||||
break;
|
||||
case BAND_FM:
|
||||
REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
|
||||
break;
|
||||
default:
|
||||
REFDIV = (u8) (state->cfg->clock_khz / 10000);
|
||||
break;
|
||||
}
|
||||
FREF = state->cfg->clock_khz / REFDIV;
|
||||
|
||||
switch (state->revision) {
|
||||
case DIB0070S_P1A:
|
||||
FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
|
||||
Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
|
||||
break;
|
||||
|
||||
case DIB0070_P1G:
|
||||
case DIB0070_P1F:
|
||||
default:
|
||||
FBDiv = (freq / (FREF / 2));
|
||||
Rest = 2 * freq - FBDiv * FREF;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Rest < LPF)
|
||||
Rest = 0;
|
||||
else if (Rest < 2 * LPF)
|
||||
Rest = 2 * LPF;
|
||||
else if (Rest > (FREF - LPF)) {
|
||||
Rest = 0;
|
||||
FBDiv += 1;
|
||||
} else if (Rest > (FREF - 2 * LPF))
|
||||
Rest = FREF - 2 * LPF;
|
||||
Rest = (Rest * 6528) / (FREF / 10);
|
||||
|
||||
Den = 1;
|
||||
if (Rest > 0) {
|
||||
state->lo4 |= (1 << 14) | (1 << 12);
|
||||
Den = 255;
|
||||
}
|
||||
|
||||
dib0070_write_reg(state, 0x11, (u16) FBDiv);
|
||||
dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
|
||||
dib0070_write_reg(state, 0x13, (u16) Rest);
|
||||
|
||||
if (state->revision == DIB0070S_P1A) {
|
||||
|
||||
if (band == BAND_SBAND) {
|
||||
dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
|
||||
dib0070_write_reg(state, 0x1d, 0xFFFF);
|
||||
} else
|
||||
dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
|
||||
}
|
||||
|
||||
dib0070_write_reg(state, 0x20,
|
||||
0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
|
||||
|
||||
dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
|
||||
dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
|
||||
dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
|
||||
dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
|
||||
dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
|
||||
dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
|
||||
|
||||
*tune_state = CT_TUNER_STEP_0;
|
||||
} else { /* we are already tuned to this frequency - the configuration is correct */
|
||||
ret = 50; /* wakeup time */
|
||||
*tune_state = CT_TUNER_STEP_5;
|
||||
Den = 1;
|
||||
if (Rest > 0) {
|
||||
state->lo4 |= (1 << 14) | (1 << 12);
|
||||
Den = 255;
|
||||
}
|
||||
} else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
|
||||
|
||||
ret = dib0070_captrim(state, tune_state);
|
||||
|
||||
} else if (*tune_state == CT_TUNER_STEP_4) {
|
||||
const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
|
||||
if (tmp != NULL) {
|
||||
while (freq / 1000 > tmp->freq) /* find the right one */
|
||||
tmp++;
|
||||
dib0070_write_reg(state, 0x0f,
|
||||
(0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
|
||||
current_tune_table_index->
|
||||
wbdmux << 0));
|
||||
state->wbd_gain_current = tmp->wbd_gain_val;
|
||||
} else {
|
||||
dib0070_write_reg(state, 0x11, (u16)FBDiv);
|
||||
dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
|
||||
dib0070_write_reg(state, 0x13, (u16) Rest);
|
||||
|
||||
if (state->revision == DIB0070S_P1A) {
|
||||
|
||||
if (band == BAND_SBAND) {
|
||||
dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
|
||||
dib0070_write_reg(state, 0x1d, 0xFFFF);
|
||||
} else
|
||||
dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
|
||||
}
|
||||
|
||||
dib0070_write_reg(state, 0x20,
|
||||
0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
|
||||
|
||||
dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
|
||||
dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
|
||||
dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
|
||||
dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
|
||||
dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
|
||||
dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
|
||||
|
||||
*tune_state = CT_TUNER_STEP_0;
|
||||
} else { /* we are already tuned to this frequency - the configuration is correct */
|
||||
ret = 50; /* wakeup time */
|
||||
*tune_state = CT_TUNER_STEP_5;
|
||||
}
|
||||
} else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
|
||||
|
||||
ret = dib0070_captrim(state, tune_state);
|
||||
|
||||
} else if (*tune_state == CT_TUNER_STEP_4) {
|
||||
const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
|
||||
if (tmp != NULL) {
|
||||
while (freq/1000 > tmp->freq) /* find the right one */
|
||||
tmp++;
|
||||
dib0070_write_reg(state, 0x0f,
|
||||
(0 << 15) | (1 << 14) | (3 << 12)
|
||||
| (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7)
|
||||
| (state->current_tune_table_index->wbdmux << 0));
|
||||
state->wbd_gain_current = tmp->wbd_gain_val;
|
||||
} else {
|
||||
dib0070_write_reg(state, 0x0f,
|
||||
(0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
|
||||
wbdmux << 0));
|
||||
state->wbd_gain_current = 6;
|
||||
}
|
||||
state->wbd_gain_current = 6;
|
||||
}
|
||||
|
||||
dib0070_write_reg(state, 0x06, 0x3fff);
|
||||
dib0070_write_reg(state, 0x06, 0x3fff);
|
||||
dib0070_write_reg(state, 0x07,
|
||||
(state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
|
||||
dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
|
||||
dib0070_write_reg(state, 0x0d, 0x0d80);
|
||||
dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
|
||||
dib0070_write_reg(state, 0x0d, 0x0d80);
|
||||
|
||||
dib0070_write_reg(state, 0x18, 0x07ff);
|
||||
dib0070_write_reg(state, 0x17, 0x0033);
|
||||
|
||||
*tune_state = CT_TUNER_STEP_5;
|
||||
} else if (*tune_state == CT_TUNER_STEP_5) {
|
||||
dib0070_set_bandwidth(fe, ch);
|
||||
*tune_state = CT_TUNER_STOP;
|
||||
} else {
|
||||
ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
|
||||
}
|
||||
return ret;
|
||||
dib0070_write_reg(state, 0x18, 0x07ff);
|
||||
dib0070_write_reg(state, 0x17, 0x0033);
|
||||
|
||||
|
||||
*tune_state = CT_TUNER_STEP_5;
|
||||
} else if (*tune_state == CT_TUNER_STEP_5) {
|
||||
dib0070_set_bandwidth(fe, ch);
|
||||
*tune_state = CT_TUNER_STOP;
|
||||
} else {
|
||||
ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
uint32_t ret;
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
uint32_t ret;
|
||||
|
||||
state->tune_state = CT_TUNER_START;
|
||||
state->tune_state = CT_TUNER_START;
|
||||
|
||||
do {
|
||||
ret = dib0070_tune_digital(fe, p);
|
||||
if (ret != FE_CALLBACK_TIME_NEVER)
|
||||
msleep(ret / 10);
|
||||
else
|
||||
break;
|
||||
} while (state->tune_state != CT_TUNER_STOP);
|
||||
do {
|
||||
ret = dib0070_tune_digital(fe, p);
|
||||
if (ret != FE_CALLBACK_TIME_NEVER)
|
||||
msleep(ret/10);
|
||||
else
|
||||
break;
|
||||
} while (state->tune_state != CT_TUNER_STOP);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dib0070_wakeup(struct dvb_frontend *fe)
|
||||
|
@ -512,92 +507,113 @@ static int dib0070_sleep(struct dvb_frontend *fe)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const u16 dib0070_p1f_defaults[] = {
|
||||
u8 dib0070_get_rf_output(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
|
||||
}
|
||||
EXPORT_SYMBOL(dib0070_get_rf_output);
|
||||
|
||||
int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
|
||||
if (no > 3)
|
||||
no = 3;
|
||||
if (no < 1)
|
||||
no = 1;
|
||||
return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
|
||||
}
|
||||
EXPORT_SYMBOL(dib0070_set_rf_output);
|
||||
|
||||
static const u16 dib0070_p1f_defaults[] =
|
||||
|
||||
{
|
||||
7, 0x02,
|
||||
0x0008,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0002,
|
||||
0x0100,
|
||||
0x0008,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0002,
|
||||
0x0100,
|
||||
|
||||
3, 0x0d,
|
||||
0x0d80,
|
||||
0x0001,
|
||||
0x0000,
|
||||
0x0d80,
|
||||
0x0001,
|
||||
0x0000,
|
||||
|
||||
4, 0x11,
|
||||
0x0000,
|
||||
0x0103,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0000,
|
||||
0x0103,
|
||||
0x0000,
|
||||
0x0000,
|
||||
|
||||
3, 0x16,
|
||||
0x0004 | 0x0040,
|
||||
0x0030,
|
||||
0x07ff,
|
||||
0x0004 | 0x0040,
|
||||
0x0030,
|
||||
0x07ff,
|
||||
|
||||
6, 0x1b,
|
||||
0x4112,
|
||||
0xff00,
|
||||
0xc07f,
|
||||
0x0000,
|
||||
0x0180,
|
||||
0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
|
||||
0x4112,
|
||||
0xff00,
|
||||
0xc07f,
|
||||
0x0000,
|
||||
0x0180,
|
||||
0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
|
||||
|
||||
0,
|
||||
};
|
||||
|
||||
static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
|
||||
{
|
||||
u16 tuner_en = dib0070_read_reg(state, 0x20);
|
||||
u16 offset;
|
||||
u16 tuner_en = dib0070_read_reg(state, 0x20);
|
||||
u16 offset;
|
||||
|
||||
dib0070_write_reg(state, 0x18, 0x07ff);
|
||||
dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
|
||||
dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
|
||||
msleep(9);
|
||||
offset = dib0070_read_reg(state, 0x19);
|
||||
dib0070_write_reg(state, 0x20, tuner_en);
|
||||
return offset;
|
||||
dib0070_write_reg(state, 0x18, 0x07ff);
|
||||
dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
|
||||
dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
|
||||
msleep(9);
|
||||
offset = dib0070_read_reg(state, 0x19);
|
||||
dib0070_write_reg(state, 0x20, tuner_en);
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
|
||||
{
|
||||
u8 gain;
|
||||
for (gain = 6; gain < 8; gain++) {
|
||||
state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
|
||||
dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]);
|
||||
}
|
||||
u8 gain;
|
||||
for (gain = 6; gain < 8; gain++) {
|
||||
state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
|
||||
dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]);
|
||||
}
|
||||
}
|
||||
|
||||
u16 dib0070_wbd_offset(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
|
||||
u32 freq = fe->dtv_property_cache.frequency / 1000;
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
|
||||
u32 freq = fe->dtv_property_cache.frequency/1000;
|
||||
|
||||
if (tmp != NULL) {
|
||||
while (freq / 1000 > tmp->freq) /* find the right one */
|
||||
tmp++;
|
||||
state->wbd_gain_current = tmp->wbd_gain_val;
|
||||
if (tmp != NULL) {
|
||||
while (freq/1000 > tmp->freq) /* find the right one */
|
||||
tmp++;
|
||||
state->wbd_gain_current = tmp->wbd_gain_val;
|
||||
} else
|
||||
state->wbd_gain_current = 6;
|
||||
state->wbd_gain_current = 6;
|
||||
|
||||
return state->wbd_offset_3_3[state->wbd_gain_current - 6];
|
||||
return state->wbd_offset_3_3[state->wbd_gain_current - 6];
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dib0070_wbd_offset);
|
||||
|
||||
#define pgm_read_word(w) (*w)
|
||||
static int dib0070_reset(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
u16 l, r, *n;
|
||||
|
||||
HARD_RESET(state);
|
||||
|
||||
|
||||
#ifndef FORCE_SBAND_TUNER
|
||||
if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
|
||||
state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
|
||||
|
@ -605,7 +621,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
|
|||
#else
|
||||
#warning forcing SBAND
|
||||
#endif
|
||||
state->revision = DIB0070S_P1A;
|
||||
state->revision = DIB0070S_P1A;
|
||||
|
||||
/* P1F or not */
|
||||
dprintk("Revision: %x", state->revision);
|
||||
|
@ -620,7 +636,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
|
|||
while (l) {
|
||||
r = pgm_read_word(n++);
|
||||
do {
|
||||
dib0070_write_reg(state, (u8) r, pgm_read_word(n++));
|
||||
dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
|
||||
r++;
|
||||
} while (--l);
|
||||
l = pgm_read_word(n++);
|
||||
|
@ -633,6 +649,7 @@ static int dib0070_reset(struct dvb_frontend *fe)
|
|||
else
|
||||
r = 2;
|
||||
|
||||
|
||||
r |= state->cfg->osc_buffer_state << 3;
|
||||
|
||||
dib0070_write_reg(state, 0x10, r);
|
||||
|
@ -643,16 +660,24 @@ static int dib0070_reset(struct dvb_frontend *fe)
|
|||
dib0070_write_reg(state, 0x02, r | (1 << 5));
|
||||
}
|
||||
|
||||
if (state->revision == DIB0070S_P1A)
|
||||
dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
|
||||
else
|
||||
if (state->revision == DIB0070S_P1A)
|
||||
dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
|
||||
else
|
||||
dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
|
||||
|
||||
dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
|
||||
|
||||
dib0070_wbd_offset_calibration(state);
|
||||
dib0070_wbd_offset_calibration(state);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
struct dib0070_state *state = fe->tuner_priv;
|
||||
|
||||
*frequency = 1000 * state->current_rf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dib0070_release(struct dvb_frontend *fe)
|
||||
|
@ -664,18 +689,18 @@ static int dib0070_release(struct dvb_frontend *fe)
|
|||
|
||||
static const struct dvb_tuner_ops dib0070_ops = {
|
||||
.info = {
|
||||
.name = "DiBcom DiB0070",
|
||||
.frequency_min = 45000000,
|
||||
.frequency_max = 860000000,
|
||||
.frequency_step = 1000,
|
||||
},
|
||||
.release = dib0070_release,
|
||||
.name = "DiBcom DiB0070",
|
||||
.frequency_min = 45000000,
|
||||
.frequency_max = 860000000,
|
||||
.frequency_step = 1000,
|
||||
},
|
||||
.release = dib0070_release,
|
||||
|
||||
.init = dib0070_wakeup,
|
||||
.sleep = dib0070_sleep,
|
||||
.set_params = dib0070_tune,
|
||||
.init = dib0070_wakeup,
|
||||
.sleep = dib0070_sleep,
|
||||
.set_params = dib0070_tune,
|
||||
|
||||
// .get_frequency = dib0070_get_frequency,
|
||||
.get_frequency = dib0070_get_frequency,
|
||||
// .get_bandwidth = dib0070_get_bandwidth
|
||||
};
|
||||
|
||||
|
@ -687,7 +712,7 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
|
|||
|
||||
state->cfg = cfg;
|
||||
state->i2c = i2c;
|
||||
state->fe = fe;
|
||||
state->fe = fe;
|
||||
fe->tuner_priv = state;
|
||||
|
||||
if (dib0070_reset(fe) != 0)
|
||||
|
@ -699,12 +724,11 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
|
|||
fe->tuner_priv = state;
|
||||
return fe;
|
||||
|
||||
free_mem:
|
||||
free_mem:
|
||||
kfree(state);
|
||||
fe->tuner_priv = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dib0070_attach);
|
||||
|
||||
MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
|
||||
|
|
|
@ -52,6 +52,8 @@ struct dib0070_config {
|
|||
extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
|
||||
extern u16 dib0070_wbd_offset(struct dvb_frontend *);
|
||||
extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
|
||||
extern u8 dib0070_get_rf_output(struct dvb_frontend *fe);
|
||||
extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no);
|
||||
#else
|
||||
static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
|
||||
{
|
||||
|
@ -62,7 +64,7 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struc
|
|||
static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
|
||||
|
|
1522
drivers/media/dvb/frontends/dib0090.c
Normal file
1522
drivers/media/dvb/frontends/dib0090.c
Normal file
File diff suppressed because it is too large
Load diff
108
drivers/media/dvb/frontends/dib0090.h
Normal file
108
drivers/media/dvb/frontends/dib0090.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
|
||||
*
|
||||
* Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
|
||||
*
|
||||
* 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, version 2.
|
||||
*/
|
||||
#ifndef DIB0090_H
|
||||
#define DIB0090_H
|
||||
|
||||
struct dvb_frontend;
|
||||
struct i2c_adapter;
|
||||
|
||||
#define DEFAULT_DIB0090_I2C_ADDRESS 0x60
|
||||
|
||||
struct dib0090_io_config {
|
||||
u32 clock_khz;
|
||||
|
||||
u8 pll_bypass:1;
|
||||
u8 pll_range:1;
|
||||
u8 pll_prediv:6;
|
||||
u8 pll_loopdiv:6;
|
||||
|
||||
u8 adc_clock_ratio; /* valid is 8, 7 ,6 */
|
||||
u16 pll_int_loop_filt;
|
||||
};
|
||||
|
||||
struct dib0090_config {
|
||||
struct dib0090_io_config io;
|
||||
int (*reset) (struct dvb_frontend *, int);
|
||||
int (*sleep) (struct dvb_frontend *, int);
|
||||
|
||||
/* offset in kHz */
|
||||
int freq_offset_khz_uhf;
|
||||
int freq_offset_khz_vhf;
|
||||
|
||||
int (*get_adc_power) (struct dvb_frontend *);
|
||||
|
||||
u8 clkouttobamse:1; /* activate or deactivate clock output */
|
||||
u8 analog_output;
|
||||
|
||||
u8 i2c_address;
|
||||
/* add drives and other things if necessary */
|
||||
u16 wbd_vhf_offset;
|
||||
u16 wbd_cband_offset;
|
||||
u8 use_pwm_agc;
|
||||
u8 clkoutdrive;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
|
||||
extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
|
||||
extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
|
||||
extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner);
|
||||
extern int dib0090_gain_control(struct dvb_frontend *fe);
|
||||
extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe);
|
||||
extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
|
||||
extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt);
|
||||
#else
|
||||
static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
}
|
||||
|
||||
static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
}
|
||||
|
||||
static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dib0090_gain_control(struct dvb_frontend *fe)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return CT_DONE;
|
||||
}
|
||||
|
||||
static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -28,18 +28,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
|
|||
|
||||
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
|
||||
|
||||
enum frontend_tune_state {
|
||||
CT_AGC_START = 20,
|
||||
CT_AGC_STEP_0,
|
||||
CT_AGC_STEP_1,
|
||||
CT_AGC_STEP_2,
|
||||
CT_AGC_STEP_3,
|
||||
CT_AGC_STEP_4,
|
||||
CT_AGC_STOP,
|
||||
|
||||
CT_DEMOD_START = 30,
|
||||
};
|
||||
|
||||
#define FE_STATUS_TUNE_FAILED 0
|
||||
|
||||
struct i2c_device {
|
||||
|
@ -133,104 +121,104 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
|
|||
return dib8000_i2c_write16(&state->i2c, reg, val);
|
||||
}
|
||||
|
||||
const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
|
||||
static const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
|
||||
(769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
|
||||
(920 << 5) | 0x09
|
||||
};
|
||||
|
||||
const int16_t coeff_2k_sb_1seg[8] = {
|
||||
static const int16_t coeff_2k_sb_1seg[8] = {
|
||||
(692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
|
||||
};
|
||||
|
||||
const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
|
||||
static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
|
||||
(832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
|
||||
(-931 << 5) | 0x0f
|
||||
};
|
||||
|
||||
const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
|
||||
static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
|
||||
(622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
|
||||
(982 << 5) | 0x0c
|
||||
};
|
||||
|
||||
const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
|
||||
static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
|
||||
(699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
|
||||
(-720 << 5) | 0x0d
|
||||
};
|
||||
|
||||
const int16_t coeff_2k_sb_3seg[8] = {
|
||||
static const int16_t coeff_2k_sb_3seg[8] = {
|
||||
(664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
|
||||
(-610 << 5) | 0x0a
|
||||
};
|
||||
|
||||
const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
|
||||
static const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
|
||||
(-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
|
||||
(-922 << 5) | 0x0d
|
||||
};
|
||||
|
||||
const int16_t coeff_4k_sb_1seg[8] = {
|
||||
static const int16_t coeff_4k_sb_1seg[8] = {
|
||||
(638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
|
||||
(-655 << 5) | 0x0a
|
||||
};
|
||||
|
||||
const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
|
||||
static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
|
||||
(-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
|
||||
(-958 << 5) | 0x13
|
||||
};
|
||||
|
||||
const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
|
||||
static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
|
||||
(-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
|
||||
(-568 << 5) | 0x0f
|
||||
};
|
||||
|
||||
const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
|
||||
static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
|
||||
(-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
|
||||
(-848 << 5) | 0x13
|
||||
};
|
||||
|
||||
const int16_t coeff_4k_sb_3seg[8] = {
|
||||
static const int16_t coeff_4k_sb_3seg[8] = {
|
||||
(612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
|
||||
(-869 << 5) | 0x13
|
||||
};
|
||||
|
||||
const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
|
||||
static const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
|
||||
(-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
|
||||
(-598 << 5) | 0x10
|
||||
};
|
||||
|
||||
const int16_t coeff_8k_sb_1seg[8] = {
|
||||
static const int16_t coeff_8k_sb_1seg[8] = {
|
||||
(673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
|
||||
(585 << 5) | 0x0f
|
||||
};
|
||||
|
||||
const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
|
||||
static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
|
||||
(863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
|
||||
(0 << 5) | 0x14
|
||||
};
|
||||
|
||||
const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
|
||||
static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
|
||||
(-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
|
||||
(-877 << 5) | 0x15
|
||||
};
|
||||
|
||||
const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
|
||||
static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
|
||||
(-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
|
||||
(-921 << 5) | 0x14
|
||||
};
|
||||
|
||||
const int16_t coeff_8k_sb_3seg[8] = {
|
||||
static const int16_t coeff_8k_sb_3seg[8] = {
|
||||
(514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
|
||||
(690 << 5) | 0x14
|
||||
};
|
||||
|
||||
const int16_t ana_fe_coeff_3seg[24] = {
|
||||
static const int16_t ana_fe_coeff_3seg[24] = {
|
||||
81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
|
||||
};
|
||||
|
||||
const int16_t ana_fe_coeff_1seg[24] = {
|
||||
static const int16_t ana_fe_coeff_1seg[24] = {
|
||||
249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
|
||||
};
|
||||
|
||||
const int16_t ana_fe_coeff_13seg[24] = {
|
||||
static const int16_t ana_fe_coeff_13seg[24] = {
|
||||
396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
|
||||
};
|
||||
|
||||
|
@ -852,6 +840,14 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dib8000_state *state = fe->demodulator_priv;
|
||||
dib8000_set_adc_state(state, DIBX000_ADC_ON);
|
||||
dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
|
||||
}
|
||||
EXPORT_SYMBOL(dib8000_pwm_agc_reset);
|
||||
|
||||
static int dib8000_agc_soft_split(struct dib8000_state *state)
|
||||
{
|
||||
u16 agc, split_offset;
|
||||
|
@ -939,6 +935,32 @@ static int dib8000_agc_startup(struct dvb_frontend *fe)
|
|||
|
||||
}
|
||||
|
||||
static const int32_t lut_1000ln_mant[] =
|
||||
{
|
||||
908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
|
||||
};
|
||||
|
||||
int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode)
|
||||
{
|
||||
struct dib8000_state *state = fe->demodulator_priv;
|
||||
uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0;
|
||||
int32_t val;
|
||||
|
||||
val = dib8000_read32(state, 384);
|
||||
/* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */
|
||||
if (mode) {
|
||||
tmp_val = val;
|
||||
while (tmp_val >>= 1)
|
||||
exp++;
|
||||
mant = (val * 1000 / (1<<exp));
|
||||
ix = (uint8_t)((mant-1000)/100); /* index of the LUT */
|
||||
val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */
|
||||
val = (val*256)/1000;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL(dib8000_get_adc_power);
|
||||
|
||||
static void dib8000_update_timf(struct dib8000_state *state)
|
||||
{
|
||||
u32 timf = state->timf = dib8000_read32(state, 435);
|
||||
|
@ -1401,10 +1423,9 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
|
||||
for (i = 0; i < 8; i++)
|
||||
dib8000_write_word(state, 343 + i, ncoeff[i]);
|
||||
}
|
||||
|
||||
// P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
|
||||
dib8000_write_word(state, 351,
|
||||
|
@ -1854,6 +1875,24 @@ static int dib8000_sleep(struct dvb_frontend *fe)
|
|||
}
|
||||
}
|
||||
|
||||
enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dib8000_state *state = fe->demodulator_priv;
|
||||
return state->tune_state;
|
||||
}
|
||||
EXPORT_SYMBOL(dib8000_get_tune_state);
|
||||
|
||||
int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
|
||||
{
|
||||
struct dib8000_state *state = fe->demodulator_priv;
|
||||
state->tune_state = tune_state;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dib8000_set_tune_state);
|
||||
|
||||
|
||||
|
||||
|
||||
static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
|
||||
{
|
||||
struct dib8000_state *state = fe->demodulator_priv;
|
||||
|
@ -2043,29 +2082,31 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
|
|||
|
||||
*stat = 0;
|
||||
|
||||
if ((lock >> 14) & 1) // AGC
|
||||
if ((lock >> 13) & 1)
|
||||
*stat |= FE_HAS_SIGNAL;
|
||||
|
||||
if ((lock >> 8) & 1) // Equal
|
||||
if ((lock >> 8) & 1) /* Equal */
|
||||
*stat |= FE_HAS_CARRIER;
|
||||
|
||||
if ((lock >> 3) & 1) // TMCC_SYNC
|
||||
if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */
|
||||
*stat |= FE_HAS_SYNC;
|
||||
|
||||
if ((lock >> 5) & 7) // FEC MPEG
|
||||
if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */
|
||||
*stat |= FE_HAS_LOCK;
|
||||
|
||||
lock = dib8000_read_word(state, 554); // Viterbi Layer A
|
||||
if (lock & 0x01)
|
||||
*stat |= FE_HAS_VITERBI;
|
||||
if ((lock >> 12) & 1) {
|
||||
lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
|
||||
if (lock & 0x01)
|
||||
*stat |= FE_HAS_VITERBI;
|
||||
|
||||
lock = dib8000_read_word(state, 555); // Viterbi Layer B
|
||||
if (lock & 0x01)
|
||||
*stat |= FE_HAS_VITERBI;
|
||||
lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
|
||||
if (lock & 0x01)
|
||||
*stat |= FE_HAS_VITERBI;
|
||||
|
||||
lock = dib8000_read_word(state, 556); // Viterbi Layer C
|
||||
if (lock & 0x01)
|
||||
*stat |= FE_HAS_VITERBI;
|
||||
lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
|
||||
if (lock & 0x01)
|
||||
*stat |= FE_HAS_VITERBI;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,10 @@ extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
|
|||
extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
|
||||
extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
|
||||
extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
|
||||
extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
|
||||
extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
|
||||
extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
|
||||
extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
|
||||
#else
|
||||
static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
|
||||
{
|
||||
|
@ -59,35 +63,53 @@ static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
|
||||
static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
|
||||
static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
|
||||
static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
|
||||
static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
|
||||
static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return CT_SHUTDOWN,
|
||||
}
|
||||
static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
}
|
||||
static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@ static int debug;
|
|||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
|
||||
|
||||
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0)
|
||||
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)
|
||||
|
||||
static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
|
|||
enum dibx000_i2c_interface intf)
|
||||
{
|
||||
if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
|
||||
dprintk("selecting interface: %d\n", intf);
|
||||
dprintk("selecting interface: %d", intf);
|
||||
mst->selected_interface = intf;
|
||||
return dibx000_write_word(mst, mst->base_reg + 4, intf);
|
||||
}
|
||||
|
@ -171,9 +171,18 @@ void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
|
|||
{
|
||||
i2c_del_adapter(&mst->gated_tuner_i2c_adap);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dibx000_exit_i2c_master);
|
||||
|
||||
|
||||
u32 systime()
|
||||
{
|
||||
struct timespec t;
|
||||
|
||||
t = current_kernel_time();
|
||||
return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
|
||||
}
|
||||
EXPORT_SYMBOL(systime);
|
||||
|
||||
MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
|
||||
MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -36,13 +36,17 @@ extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
|
|||
extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
|
||||
extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
|
||||
|
||||
extern u32 systime(void);
|
||||
|
||||
#define BAND_LBAND 0x01
|
||||
#define BAND_UHF 0x02
|
||||
#define BAND_VHF 0x04
|
||||
#define BAND_SBAND 0x08
|
||||
#define BAND_FM 0x10
|
||||
#define BAND_FM 0x10
|
||||
#define BAND_CBAND 0x20
|
||||
|
||||
#define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 115000 ? BAND_FM : \
|
||||
#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \
|
||||
(freq_kHz) <= 115000 ? BAND_FM : \
|
||||
(freq_kHz) <= 250000 ? BAND_VHF : \
|
||||
(freq_kHz) <= 863000 ? BAND_UHF : \
|
||||
(freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
|
||||
|
@ -149,4 +153,67 @@ enum dibx000_adc_states {
|
|||
#define OUTMODE_MPEG2_FIFO 5
|
||||
#define OUTMODE_ANALOG_ADC 6
|
||||
|
||||
enum frontend_tune_state {
|
||||
CT_TUNER_START = 10,
|
||||
CT_TUNER_STEP_0,
|
||||
CT_TUNER_STEP_1,
|
||||
CT_TUNER_STEP_2,
|
||||
CT_TUNER_STEP_3,
|
||||
CT_TUNER_STEP_4,
|
||||
CT_TUNER_STEP_5,
|
||||
CT_TUNER_STEP_6,
|
||||
CT_TUNER_STEP_7,
|
||||
CT_TUNER_STOP,
|
||||
|
||||
CT_AGC_START = 20,
|
||||
CT_AGC_STEP_0,
|
||||
CT_AGC_STEP_1,
|
||||
CT_AGC_STEP_2,
|
||||
CT_AGC_STEP_3,
|
||||
CT_AGC_STEP_4,
|
||||
CT_AGC_STOP,
|
||||
|
||||
CT_DEMOD_START = 30,
|
||||
CT_DEMOD_STEP_1,
|
||||
CT_DEMOD_STEP_2,
|
||||
CT_DEMOD_STEP_3,
|
||||
CT_DEMOD_STEP_4,
|
||||
CT_DEMOD_STEP_5,
|
||||
CT_DEMOD_STEP_6,
|
||||
CT_DEMOD_STEP_7,
|
||||
CT_DEMOD_STEP_8,
|
||||
CT_DEMOD_STEP_9,
|
||||
CT_DEMOD_STEP_10,
|
||||
CT_DEMOD_SEARCH_NEXT = 41,
|
||||
CT_DEMOD_STEP_LOCKED,
|
||||
CT_DEMOD_STOP,
|
||||
|
||||
CT_DONE = 100,
|
||||
CT_SHUTDOWN,
|
||||
|
||||
};
|
||||
|
||||
struct dvb_frontend_parametersContext {
|
||||
#define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01
|
||||
#define CHANNEL_STATUS_PARAMETERS_SET 0x02
|
||||
u8 status;
|
||||
u32 tune_time_estimation[2];
|
||||
s32 tps_available;
|
||||
u16 tps[9];
|
||||
};
|
||||
|
||||
#define FE_STATUS_TUNE_FAILED 0
|
||||
#define FE_STATUS_TUNE_TIMED_OUT -1
|
||||
#define FE_STATUS_TUNE_TIME_TOO_SHORT -2
|
||||
#define FE_STATUS_TUNE_PENDING -3
|
||||
#define FE_STATUS_STD_SUCCESS -4
|
||||
#define FE_STATUS_FFT_SUCCESS -5
|
||||
#define FE_STATUS_DEMOD_SUCCESS -6
|
||||
#define FE_STATUS_LOCKED -7
|
||||
#define FE_STATUS_DATA_LOCKED -8
|
||||
|
||||
#define FE_CALLBACK_TIME_NEVER 0xffffffff
|
||||
|
||||
#define ABS(x) ((x < 0) ? (-x) : (x))
|
||||
|
||||
#endif
|
||||
|
|
|
@ -199,7 +199,7 @@ static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
|
|||
|
||||
val = freq;
|
||||
if (freq != 0) {
|
||||
val *= (u64)1 << 32;
|
||||
val <<= 32;
|
||||
if (if_clk != 0)
|
||||
do_div(val, if_clk);
|
||||
v32 = val & 0xFFFFFFFF;
|
||||
|
@ -246,7 +246,7 @@ static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv)
|
|||
|
||||
val = v32;
|
||||
val *= priv->config->if_clk_freq;
|
||||
val /= (u64)1 << 32;
|
||||
val >>= 32;
|
||||
dprintk("AFC = %u kHz\n", (u32)val);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* lnbp21.c - driver for lnb supply and control ic lnbp21
|
||||
*
|
||||
* Copyright (C) 2006 Oliver Endriss
|
||||
* Copyright (C) 2006, 2009 Oliver Endriss <o.endriss@gmx.de>
|
||||
* Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -91,6 +91,31 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
|
|||
return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int lnbp21_set_tone(struct dvb_frontend *fe,
|
||||
fe_sec_tone_mode_t tone)
|
||||
{
|
||||
struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
|
||||
struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
|
||||
.buf = &lnbp21->config,
|
||||
.len = sizeof(lnbp21->config) };
|
||||
|
||||
switch (tone) {
|
||||
case SEC_TONE_OFF:
|
||||
lnbp21->config &= ~LNBP21_TEN;
|
||||
break;
|
||||
case SEC_TONE_ON:
|
||||
lnbp21->config |= LNBP21_TEN;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
lnbp21->config |= lnbp21->override_or;
|
||||
lnbp21->config &= lnbp21->override_and;
|
||||
|
||||
return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static void lnbp21_release(struct dvb_frontend *fe)
|
||||
{
|
||||
/* LNBP power off */
|
||||
|
@ -133,6 +158,7 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
|
|||
/* override frontend ops */
|
||||
fe->ops.set_voltage = lnbp21_set_voltage;
|
||||
fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
|
||||
fe->ops.set_tone = lnbp21_set_tone;
|
||||
printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
|
||||
|
||||
return fe;
|
||||
|
|
|
@ -1451,6 +1451,8 @@ static int stv0900_status(struct stv0900_internal *intp,
|
|||
{
|
||||
enum fe_stv0900_search_state demod_state;
|
||||
int locked = FALSE;
|
||||
u8 tsbitrate0_val, tsbitrate1_val;
|
||||
s32 bitrate;
|
||||
|
||||
demod_state = stv0900_get_bits(intp, HEADER_MODE);
|
||||
switch (demod_state) {
|
||||
|
@ -1473,6 +1475,17 @@ static int stv0900_status(struct stv0900_internal *intp,
|
|||
|
||||
dprintk("%s: locked = %d\n", __func__, locked);
|
||||
|
||||
if (stvdebug) {
|
||||
/* Print TS bitrate */
|
||||
tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0);
|
||||
tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1);
|
||||
/* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */
|
||||
bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000)
|
||||
* (tsbitrate1_val << 8 | tsbitrate0_val);
|
||||
bitrate /= 16384;
|
||||
dprintk("TS bitrate = %d Mbit/sec \n", bitrate);
|
||||
};
|
||||
|
||||
return locked;
|
||||
}
|
||||
|
||||
|
|
|
@ -3597,7 +3597,8 @@ static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma
|
|||
|
||||
reg = STV090x_READ_DEMOD(state, DISTXCTL);
|
||||
|
||||
STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 2);
|
||||
STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD,
|
||||
(state->config->diseqc_envelope_mode) ? 4 : 2);
|
||||
STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
|
||||
if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
|
||||
goto err;
|
||||
|
@ -3649,10 +3650,10 @@ static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t
|
|||
reg = STV090x_READ_DEMOD(state, DISTXCTL);
|
||||
|
||||
if (burst == SEC_MINI_A) {
|
||||
mode = 3;
|
||||
mode = (state->config->diseqc_envelope_mode) ? 5 : 3;
|
||||
value = 0x00;
|
||||
} else {
|
||||
mode = 2;
|
||||
mode = (state->config->diseqc_envelope_mode) ? 4 : 2;
|
||||
value = 0xFF;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,8 @@ struct stv090x_config {
|
|||
|
||||
enum stv090x_i2crpt repeater_level;
|
||||
|
||||
bool diseqc_envelope_mode;
|
||||
|
||||
int (*tuner_init) (struct dvb_frontend *fe);
|
||||
int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
|
||||
int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
|
||||
|
|
|
@ -662,7 +662,7 @@ adapter_error:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int smsdvb_module_init(void)
|
||||
static int __init smsdvb_module_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
@ -676,7 +676,7 @@ int smsdvb_module_init(void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
void smsdvb_module_exit(void)
|
||||
static void __exit smsdvb_module_exit(void)
|
||||
{
|
||||
smscore_unregister_hotplug(smsdvb_hotplug);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#define SMSSDIO_INT 0x04
|
||||
#define SMSSDIO_BLOCK_SIZE 128
|
||||
|
||||
static const struct sdio_device_id smssdio_ids[] = {
|
||||
static const struct sdio_device_id smssdio_ids[] __devinitconst = {
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
|
||||
.driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
|
||||
|
@ -222,7 +222,7 @@ static void smssdio_interrupt(struct sdio_func *func)
|
|||
smscore_onresponse(smsdev->coredev, cb);
|
||||
}
|
||||
|
||||
static int smssdio_probe(struct sdio_func *func,
|
||||
static int __devinit smssdio_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
@ -338,7 +338,7 @@ static struct sdio_driver smssdio_driver = {
|
|||
/* Module functions */
|
||||
/*******************************************************************/
|
||||
|
||||
int smssdio_module_init(void)
|
||||
static int __init smssdio_module_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -350,7 +350,7 @@ int smssdio_module_init(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void smssdio_module_exit(void)
|
||||
static void __exit smssdio_module_exit(void)
|
||||
{
|
||||
sdio_unregister_driver(&smssdio_driver);
|
||||
}
|
||||
|
|
|
@ -390,7 +390,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int smsusb_probe(struct usb_interface *intf,
|
||||
static int __devinit smsusb_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
|
@ -484,7 +484,7 @@ static int smsusb_resume(struct usb_interface *intf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct usb_device_id smsusb_id_table[] = {
|
||||
static const struct usb_device_id smsusb_id_table[] __devinitconst = {
|
||||
{ USB_DEVICE(0x187f, 0x0010),
|
||||
.driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
|
||||
{ USB_DEVICE(0x187f, 0x0100),
|
||||
|
@ -533,8 +533,18 @@ struct usb_device_id smsusb_id_table[] = {
|
|||
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
|
||||
{ USB_DEVICE(0x2040, 0xb910),
|
||||
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
|
||||
{ USB_DEVICE(0x2040, 0xb980),
|
||||
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
|
||||
{ USB_DEVICE(0x2040, 0xb990),
|
||||
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
|
||||
{ USB_DEVICE(0x2040, 0xc000),
|
||||
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
|
||||
{ USB_DEVICE(0x2040, 0xc010),
|
||||
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
|
||||
{ USB_DEVICE(0x2040, 0xc080),
|
||||
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
|
||||
{ USB_DEVICE(0x2040, 0xc090),
|
||||
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
@ -550,7 +560,7 @@ static struct usb_driver smsusb_driver = {
|
|||
.resume = smsusb_resume,
|
||||
};
|
||||
|
||||
int smsusb_module_init(void)
|
||||
static int __init smsusb_module_init(void)
|
||||
{
|
||||
int rc = usb_register(&smsusb_driver);
|
||||
if (rc)
|
||||
|
@ -561,7 +571,7 @@ int smsusb_module_init(void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
void smsusb_module_exit(void)
|
||||
static void __exit smsusb_module_exit(void)
|
||||
{
|
||||
/* Regular USB Cleanup */
|
||||
usb_deregister(&smsusb_driver);
|
||||
|
|
|
@ -190,12 +190,13 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
|
|||
struct saa7146_dev *saa = budget_ci->budget.dev;
|
||||
struct input_dev *input_dev = budget_ci->ir.dev;
|
||||
int error;
|
||||
struct ir_scancode_table *ir_codes;
|
||||
|
||||
|
||||
budget_ci->ir.dev = input_dev = input_allocate_device();
|
||||
if (!input_dev) {
|
||||
printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
|
||||
error = -ENOMEM;
|
||||
goto out1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
|
||||
|
@ -217,6 +218,11 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
|
|||
}
|
||||
input_dev->dev.parent = &saa->pci->dev;
|
||||
|
||||
if (rc5_device < 0)
|
||||
budget_ci->ir.rc5_device = IR_DEVICE_ANY;
|
||||
else
|
||||
budget_ci->ir.rc5_device = rc5_device;
|
||||
|
||||
/* Select keymap and address */
|
||||
switch (budget_ci->budget.dev->pci->subsystem_device) {
|
||||
case 0x100c:
|
||||
|
@ -224,53 +230,34 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
|
|||
case 0x1011:
|
||||
case 0x1012:
|
||||
/* The hauppauge keymap is a superset of these remotes */
|
||||
error = ir_input_init(input_dev, &budget_ci->ir.state,
|
||||
IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
|
||||
if (error < 0)
|
||||
goto out2;
|
||||
ir_codes = &ir_codes_hauppauge_new_table;
|
||||
|
||||
if (rc5_device < 0)
|
||||
budget_ci->ir.rc5_device = 0x1f;
|
||||
else
|
||||
budget_ci->ir.rc5_device = rc5_device;
|
||||
break;
|
||||
case 0x1010:
|
||||
case 0x1017:
|
||||
case 0x101a:
|
||||
/* for the Technotrend 1500 bundled remote */
|
||||
error = ir_input_init(input_dev, &budget_ci->ir.state,
|
||||
IR_TYPE_RC5, &ir_codes_tt_1500_table);
|
||||
if (error < 0)
|
||||
goto out2;
|
||||
|
||||
if (rc5_device < 0)
|
||||
budget_ci->ir.rc5_device = IR_DEVICE_ANY;
|
||||
else
|
||||
budget_ci->ir.rc5_device = rc5_device;
|
||||
ir_codes = &ir_codes_tt_1500_table;
|
||||
break;
|
||||
default:
|
||||
/* unknown remote */
|
||||
error = ir_input_init(input_dev, &budget_ci->ir.state,
|
||||
IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
|
||||
if (error < 0)
|
||||
goto out2;
|
||||
|
||||
if (rc5_device < 0)
|
||||
budget_ci->ir.rc5_device = IR_DEVICE_ANY;
|
||||
else
|
||||
budget_ci->ir.rc5_device = rc5_device;
|
||||
ir_codes = &ir_codes_budget_ci_old_table;
|
||||
break;
|
||||
}
|
||||
|
||||
ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5);
|
||||
|
||||
/* initialise the key-up timeout handler */
|
||||
init_timer(&budget_ci->ir.timer_keyup);
|
||||
budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
|
||||
budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
|
||||
budget_ci->ir.last_raw = 0xffff; /* An impossible value */
|
||||
error = input_register_device(input_dev);
|
||||
error = ir_input_register(input_dev, ir_codes);
|
||||
if (error) {
|
||||
printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
|
||||
goto out2;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* note: these must be after input_register_device */
|
||||
|
@ -284,12 +271,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
|
|||
saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
|
||||
|
||||
return 0;
|
||||
|
||||
out2:
|
||||
ir_input_free(input_dev);
|
||||
input_free_device(input_dev);
|
||||
out1:
|
||||
return error;
|
||||
}
|
||||
|
||||
static void msp430_ir_deinit(struct budget_ci *budget_ci)
|
||||
|
@ -304,8 +285,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
|
|||
del_timer_sync(&dev->timer);
|
||||
ir_input_nokey(dev, &budget_ci->ir.state);
|
||||
|
||||
ir_input_free(dev);
|
||||
input_unregister_device(dev);
|
||||
ir_input_unregister(dev);
|
||||
}
|
||||
|
||||
static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
|
||||
|
|
|
@ -215,13 +215,10 @@ config RADIO_MIROPCM20
|
|||
module will be called radio-miropcm20.
|
||||
|
||||
config RADIO_SF16FMI
|
||||
tristate "SF16FMI Radio"
|
||||
tristate "SF16-FMI/SF16-FMP Radio"
|
||||
depends on ISA && VIDEO_V4L2
|
||||
---help---
|
||||
Choose Y here if you have one of these FM radio cards. If you
|
||||
compile the driver into the kernel and your card is not PnP one, you
|
||||
have to add "sf16fm=<io>" to the kernel command line (I/O address is
|
||||
0x284 or 0x384).
|
||||
Choose Y here if you have one of these FM radio cards.
|
||||
|
||||
In order to control your radio card, you will need to use programs
|
||||
that are compatible with the Video For Linux API. Information on
|
||||
|
|
|
@ -268,6 +268,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct rtrack *rt = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
rt_setfreq(rt, f->frequency);
|
||||
return 0;
|
||||
}
|
||||
|
@ -277,6 +279,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct rtrack *rt = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = rt->curfreq;
|
||||
return 0;
|
||||
|
|
|
@ -254,6 +254,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct aztech *az = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
az_setfreq(az, f->frequency);
|
||||
return 0;
|
||||
}
|
||||
|
@ -263,6 +265,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct aztech *az = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = az->curfreq;
|
||||
return 0;
|
||||
|
|
|
@ -240,6 +240,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct gemtek_pci *card = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
if (f->frequency < GEMTEK_PCI_RANGE_LOW ||
|
||||
f->frequency > GEMTEK_PCI_RANGE_HIGH)
|
||||
return -EINVAL;
|
||||
|
@ -253,6 +255,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct gemtek_pci *card = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = card->current_frequency;
|
||||
return 0;
|
||||
|
|
|
@ -200,6 +200,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct maestro *dev = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
|
||||
return -EINVAL;
|
||||
mutex_lock(&dev->lock);
|
||||
|
@ -213,6 +215,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct maestro *dev = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
mutex_lock(&dev->lock);
|
||||
f->frequency = BITS2FREQ(radio_bits_get(dev));
|
||||
|
|
|
@ -262,6 +262,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct maxiradio *dev = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) {
|
||||
dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
|
||||
f->frequency / 16000,
|
||||
|
@ -285,6 +287,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct maxiradio *dev = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = dev->freq;
|
||||
|
||||
|
|
|
@ -374,6 +374,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct amradio_device *radio = file->private_data;
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
return amradio_setfreq(radio, f->frequency);
|
||||
}
|
||||
|
||||
|
@ -383,6 +385,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct amradio_device *radio = file->private_data;
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = radio->curfreq;
|
||||
|
||||
|
|
|
@ -167,6 +167,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct rtrack2 *rt = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
rt_setfreq(rt, f->frequency);
|
||||
return 0;
|
||||
}
|
||||
|
@ -176,6 +178,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct rtrack2 *rt = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = rt->curfreq;
|
||||
return 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* SF16FMI radio driver for Linux radio support
|
||||
/* SF16-FMI and SF16-FMP radio driver for Linux radio support
|
||||
* heavily based on rtrack driver...
|
||||
* (c) 1997 M. Kirkwood
|
||||
* (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz
|
||||
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
* Frequency control is done digitally -- ie out(port,encodefreq(95.8));
|
||||
* No volume control - only mute/unmute - you have to use line volume
|
||||
* control on SB-part of SF16FMI
|
||||
* control on SB-part of SF16-FMI/SF16-FMP
|
||||
*
|
||||
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||
*/
|
||||
|
@ -30,14 +30,14 @@
|
|||
#include <media/v4l2-ioctl.h>
|
||||
|
||||
MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
|
||||
MODULE_DESCRIPTION("A driver for the SF16MI radio.");
|
||||
MODULE_DESCRIPTION("A driver for the SF16-FMI and SF16-FMP radio.");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int io = -1;
|
||||
static int radio_nr = -1;
|
||||
|
||||
module_param(io, int, 0);
|
||||
MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
|
||||
MODULE_PARM_DESC(io, "I/O address of the SF16-FMI or SF16-FMP card (0x284 or 0x384)");
|
||||
module_param(radio_nr, int, 0);
|
||||
|
||||
#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
|
||||
|
@ -47,13 +47,14 @@ struct fmi
|
|||
struct v4l2_device v4l2_dev;
|
||||
struct video_device vdev;
|
||||
int io;
|
||||
int curvol; /* 1 or 0 */
|
||||
bool mute;
|
||||
unsigned long curfreq; /* freq in kHz */
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static struct fmi fmi_card;
|
||||
static struct pnp_dev *dev;
|
||||
bool pnp_attached;
|
||||
|
||||
/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
|
||||
/* It is only useful to give freq in interval of 800 (=0.05Mhz),
|
||||
|
@ -105,7 +106,7 @@ static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq)
|
|||
outbits(8, 0xC0, fmi->io);
|
||||
msleep(143); /* was schedule_timeout(HZ/7) */
|
||||
mutex_unlock(&fmi->lock);
|
||||
if (fmi->curvol)
|
||||
if (!fmi->mute)
|
||||
fmi_unmute(fmi);
|
||||
return 0;
|
||||
}
|
||||
|
@ -116,7 +117,7 @@ static inline int fmi_getsigstr(struct fmi *fmi)
|
|||
int res;
|
||||
|
||||
mutex_lock(&fmi->lock);
|
||||
val = fmi->curvol ? 0x08 : 0x00; /* unmute/mute */
|
||||
val = fmi->mute ? 0x00 : 0x08; /* mute/unmute */
|
||||
outb(val, fmi->io);
|
||||
outb(val | 0x10, fmi->io);
|
||||
msleep(143); /* was schedule_timeout(HZ/7) */
|
||||
|
@ -168,6 +169,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct fmi *fmi = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
if (f->frequency < RSF16_MINFREQ ||
|
||||
f->frequency > RSF16_MAXFREQ)
|
||||
return -EINVAL;
|
||||
|
@ -182,6 +185,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct fmi *fmi = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = fmi->curfreq;
|
||||
return 0;
|
||||
|
@ -204,7 +209,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
|
|||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
ctrl->value = fmi->curvol;
|
||||
ctrl->value = fmi->mute;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
|
@ -221,7 +226,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
|||
fmi_mute(fmi);
|
||||
else
|
||||
fmi_unmute(fmi);
|
||||
fmi->curvol = ctrl->value;
|
||||
fmi->mute = ctrl->value;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
|
@ -316,26 +321,54 @@ static int __init fmi_init(void)
|
|||
{
|
||||
struct fmi *fmi = &fmi_card;
|
||||
struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
|
||||
int res;
|
||||
int res, i;
|
||||
int probe_ports[] = { 0, 0x284, 0x384 };
|
||||
|
||||
if (io < 0) {
|
||||
for (i = 0; i < ARRAY_SIZE(probe_ports); i++) {
|
||||
io = probe_ports[i];
|
||||
if (io == 0) {
|
||||
io = isapnp_fmi_probe();
|
||||
if (io < 0)
|
||||
continue;
|
||||
pnp_attached = 1;
|
||||
}
|
||||
if (!request_region(io, 2, "radio-sf16fmi")) {
|
||||
if (pnp_attached)
|
||||
pnp_device_detach(dev);
|
||||
io = -1;
|
||||
continue;
|
||||
}
|
||||
if (pnp_attached ||
|
||||
((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0))
|
||||
break;
|
||||
release_region(io, 2);
|
||||
io = -1;
|
||||
}
|
||||
} else {
|
||||
if (!request_region(io, 2, "radio-sf16fmi")) {
|
||||
printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (inb(io) == 0xff) {
|
||||
printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io);
|
||||
release_region(io, 2);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
if (io < 0) {
|
||||
printk(KERN_ERR "radio-sf16fmi: no cards found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (io < 0)
|
||||
io = isapnp_fmi_probe();
|
||||
strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
|
||||
fmi->io = io;
|
||||
if (fmi->io < 0) {
|
||||
v4l2_err(v4l2_dev, "No PnP card found.\n");
|
||||
return fmi->io;
|
||||
}
|
||||
if (!request_region(io, 2, "radio-sf16fmi")) {
|
||||
v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
|
||||
pnp_device_detach(dev);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
res = v4l2_device_register(NULL, v4l2_dev);
|
||||
if (res < 0) {
|
||||
release_region(fmi->io, 2);
|
||||
pnp_device_detach(dev);
|
||||
if (pnp_attached)
|
||||
pnp_device_detach(dev);
|
||||
v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
|
||||
return res;
|
||||
}
|
||||
|
@ -352,7 +385,8 @@ static int __init fmi_init(void)
|
|||
if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
|
||||
v4l2_device_unregister(v4l2_dev);
|
||||
release_region(fmi->io, 2);
|
||||
pnp_device_detach(dev);
|
||||
if (pnp_attached)
|
||||
pnp_device_detach(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -369,7 +403,7 @@ static void __exit fmi_exit(void)
|
|||
video_unregister_device(&fmi->vdev);
|
||||
v4l2_device_unregister(&fmi->v4l2_dev);
|
||||
release_region(fmi->io, 2);
|
||||
if (dev)
|
||||
if (dev && pnp_attached)
|
||||
pnp_device_detach(dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -251,6 +251,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct fmr2 *fmr2 = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
if (f->frequency < RSF16_MINFREQ ||
|
||||
f->frequency > RSF16_MAXFREQ)
|
||||
return -EINVAL;
|
||||
|
@ -272,6 +274,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct fmr2 *fmr2 = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = fmr2->curfreq;
|
||||
return 0;
|
||||
|
|
|
@ -314,7 +314,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
|
|||
if (v->index > 0)
|
||||
return -EINVAL;
|
||||
|
||||
memset(v, 0, sizeof(v));
|
||||
memset(v, 0, sizeof(*v));
|
||||
strcpy(v->name, "FM");
|
||||
v->type = V4L2_TUNER_RADIO;
|
||||
tea5764_i2c_read(radio);
|
||||
|
@ -349,7 +349,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct tea5764_device *radio = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
if (f->frequency == 0) {
|
||||
/* We special case this as a power down control. */
|
||||
|
@ -370,8 +370,10 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
struct tea5764_device *radio = video_drvdata(file);
|
||||
struct tea5764_regs *r = &radio->regs;
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
tea5764_i2c_read(radio);
|
||||
memset(f, 0, sizeof(f));
|
||||
memset(f, 0, sizeof(*f));
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
if (r->tnctrl & TEA5764_TNCTRL_PUPD0)
|
||||
f->frequency = (tea5764_get_freq(radio) * 2) / 125;
|
||||
|
@ -458,12 +460,8 @@ static int vidioc_s_audio(struct file *file, void *priv,
|
|||
static int tea5764_open(struct file *file)
|
||||
{
|
||||
/* Currently we support only one device */
|
||||
int minor = video_devdata(file)->minor;
|
||||
struct tea5764_device *radio = video_drvdata(file);
|
||||
|
||||
if (radio->videodev->minor != minor)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&radio->mutex);
|
||||
/* Only exclusive access */
|
||||
if (radio->users) {
|
||||
|
|
|
@ -240,6 +240,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct terratec *tt = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
tt_setfreq(tt, f->frequency);
|
||||
return 0;
|
||||
}
|
||||
|
@ -249,6 +251,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct terratec *tt = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = tt->curfreq;
|
||||
return 0;
|
||||
|
|
|
@ -239,6 +239,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct trust *tr = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
tr_setfreq(tr, f->frequency);
|
||||
return 0;
|
||||
}
|
||||
|
@ -248,6 +250,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct trust *tr = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = tr->curfreq;
|
||||
return 0;
|
||||
|
|
|
@ -207,6 +207,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct typhoon *dev = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = dev->curfreq;
|
||||
return 0;
|
||||
|
@ -217,6 +219,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct typhoon *dev = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
dev->curfreq = f->frequency;
|
||||
typhoon_setfreq(dev, dev->curfreq);
|
||||
return 0;
|
||||
|
|
|
@ -266,6 +266,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct zoltrix *zol = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
if (zol_setfreq(zol, f->frequency) != 0)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
@ -276,6 +278,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
|
|||
{
|
||||
struct zoltrix *zol = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = zol->curfreq;
|
||||
return 0;
|
||||
|
|
|
@ -425,6 +425,104 @@ int si470x_rds_on(struct si470x_device *radio)
|
|||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* File Operations Interface
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* si470x_fops_read - read RDS data
|
||||
*/
|
||||
static ssize_t si470x_fops_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct si470x_device *radio = video_drvdata(file);
|
||||
int retval = 0;
|
||||
unsigned int block_count = 0;
|
||||
|
||||
/* switch on rds reception */
|
||||
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
|
||||
si470x_rds_on(radio);
|
||||
|
||||
/* block if no new data available */
|
||||
while (radio->wr_index == radio->rd_index) {
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
retval = -EWOULDBLOCK;
|
||||
goto done;
|
||||
}
|
||||
if (wait_event_interruptible(radio->read_queue,
|
||||
radio->wr_index != radio->rd_index) < 0) {
|
||||
retval = -EINTR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate block count from byte count */
|
||||
count /= 3;
|
||||
|
||||
/* copy RDS block out of internal buffer and to user buffer */
|
||||
mutex_lock(&radio->lock);
|
||||
while (block_count < count) {
|
||||
if (radio->rd_index == radio->wr_index)
|
||||
break;
|
||||
|
||||
/* always transfer rds complete blocks */
|
||||
if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
|
||||
/* retval = -EFAULT; */
|
||||
break;
|
||||
|
||||
/* increment and wrap read pointer */
|
||||
radio->rd_index += 3;
|
||||
if (radio->rd_index >= radio->buf_size)
|
||||
radio->rd_index = 0;
|
||||
|
||||
/* increment counters */
|
||||
block_count++;
|
||||
buf += 3;
|
||||
retval += 3;
|
||||
}
|
||||
mutex_unlock(&radio->lock);
|
||||
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_fops_poll - poll RDS data
|
||||
*/
|
||||
static unsigned int si470x_fops_poll(struct file *file,
|
||||
struct poll_table_struct *pts)
|
||||
{
|
||||
struct si470x_device *radio = video_drvdata(file);
|
||||
int retval = 0;
|
||||
|
||||
/* switch on rds reception */
|
||||
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
|
||||
si470x_rds_on(radio);
|
||||
|
||||
poll_wait(file, &radio->read_queue, pts);
|
||||
|
||||
if (radio->rd_index != radio->wr_index)
|
||||
retval = POLLIN | POLLRDNORM;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_fops - file operations interface
|
||||
*/
|
||||
static const struct v4l2_file_operations si470x_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = si470x_fops_read,
|
||||
.poll = si470x_fops_poll,
|
||||
.ioctl = video_ioctl2,
|
||||
.open = si470x_fops_open,
|
||||
.release = si470x_fops_release,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Video4Linux Interface
|
||||
**************************************************************************/
|
||||
|
|
|
@ -22,22 +22,17 @@
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ToDo:
|
||||
* - RDS support
|
||||
*/
|
||||
|
||||
|
||||
/* driver definitions */
|
||||
#define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>";
|
||||
#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0)
|
||||
#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 1)
|
||||
#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
|
||||
#define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers"
|
||||
#define DRIVER_VERSION "1.0.0"
|
||||
#define DRIVER_VERSION "1.0.1"
|
||||
|
||||
/* kernel includes */
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "radio-si470x.h"
|
||||
|
||||
|
@ -62,6 +57,20 @@ static int radio_nr = -1;
|
|||
module_param(radio_nr, int, 0444);
|
||||
MODULE_PARM_DESC(radio_nr, "Radio Nr");
|
||||
|
||||
/* RDS buffer blocks */
|
||||
static unsigned int rds_buf = 100;
|
||||
module_param(rds_buf, uint, 0444);
|
||||
MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
|
||||
|
||||
/* RDS maximum block errors */
|
||||
static unsigned short max_rds_errors = 1;
|
||||
/* 0 means 0 errors requiring correction */
|
||||
/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
|
||||
/* 2 means 3-5 errors requiring correction */
|
||||
/* 3 means 6+ errors or errors in checkword, correction not possible */
|
||||
module_param(max_rds_errors, ushort, 0644);
|
||||
MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -173,7 +182,7 @@ int si470x_disconnect_check(struct si470x_device *radio)
|
|||
/*
|
||||
* si470x_fops_open - file open
|
||||
*/
|
||||
static int si470x_fops_open(struct file *file)
|
||||
int si470x_fops_open(struct file *file)
|
||||
{
|
||||
struct si470x_device *radio = video_drvdata(file);
|
||||
int retval = 0;
|
||||
|
@ -181,12 +190,21 @@ static int si470x_fops_open(struct file *file)
|
|||
mutex_lock(&radio->lock);
|
||||
radio->users++;
|
||||
|
||||
if (radio->users == 1)
|
||||
if (radio->users == 1) {
|
||||
/* start radio */
|
||||
retval = si470x_start(radio);
|
||||
if (retval < 0)
|
||||
goto done;
|
||||
|
||||
/* enable RDS interrupt */
|
||||
radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
|
||||
radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
|
||||
radio->registers[SYSCONFIG1] |= 0x1 << 2;
|
||||
retval = si470x_set_register(radio, SYSCONFIG1);
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&radio->lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -194,7 +212,7 @@ static int si470x_fops_open(struct file *file)
|
|||
/*
|
||||
* si470x_fops_release - file release
|
||||
*/
|
||||
static int si470x_fops_release(struct file *file)
|
||||
int si470x_fops_release(struct file *file)
|
||||
{
|
||||
struct si470x_device *radio = video_drvdata(file);
|
||||
int retval = 0;
|
||||
|
@ -215,17 +233,6 @@ static int si470x_fops_release(struct file *file)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_fops - file operations interface
|
||||
*/
|
||||
const struct v4l2_file_operations si470x_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.ioctl = video_ioctl2,
|
||||
.open = si470x_fops_open,
|
||||
.release = si470x_fops_release,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Video4Linux Interface
|
||||
|
@ -252,6 +259,105 @@ int si470x_vidioc_querycap(struct file *file, void *priv,
|
|||
* I2C Interface
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* si470x_i2c_interrupt_work - rds processing function
|
||||
*/
|
||||
static void si470x_i2c_interrupt_work(struct work_struct *work)
|
||||
{
|
||||
struct si470x_device *radio = container_of(work,
|
||||
struct si470x_device, radio_work);
|
||||
unsigned char regnr;
|
||||
unsigned char blocknum;
|
||||
unsigned short bler; /* rds block errors */
|
||||
unsigned short rds;
|
||||
unsigned char tmpbuf[3];
|
||||
int retval = 0;
|
||||
|
||||
/* safety checks */
|
||||
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
|
||||
return;
|
||||
|
||||
/* Update RDS registers */
|
||||
for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) {
|
||||
retval = si470x_get_register(radio, STATUSRSSI + regnr);
|
||||
if (retval < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* get rds blocks */
|
||||
if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
|
||||
/* No RDS group ready, better luck next time */
|
||||
return;
|
||||
|
||||
for (blocknum = 0; blocknum < 4; blocknum++) {
|
||||
switch (blocknum) {
|
||||
default:
|
||||
bler = (radio->registers[STATUSRSSI] &
|
||||
STATUSRSSI_BLERA) >> 9;
|
||||
rds = radio->registers[RDSA];
|
||||
break;
|
||||
case 1:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERB) >> 14;
|
||||
rds = radio->registers[RDSB];
|
||||
break;
|
||||
case 2:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERC) >> 12;
|
||||
rds = radio->registers[RDSC];
|
||||
break;
|
||||
case 3:
|
||||
bler = (radio->registers[READCHAN] &
|
||||
READCHAN_BLERD) >> 10;
|
||||
rds = radio->registers[RDSD];
|
||||
break;
|
||||
};
|
||||
|
||||
/* Fill the V4L2 RDS buffer */
|
||||
put_unaligned_le16(rds, &tmpbuf);
|
||||
tmpbuf[2] = blocknum; /* offset name */
|
||||
tmpbuf[2] |= blocknum << 3; /* received offset */
|
||||
if (bler > max_rds_errors)
|
||||
tmpbuf[2] |= 0x80; /* uncorrectable errors */
|
||||
else if (bler > 0)
|
||||
tmpbuf[2] |= 0x40; /* corrected error(s) */
|
||||
|
||||
/* copy RDS block to internal buffer */
|
||||
memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
|
||||
radio->wr_index += 3;
|
||||
|
||||
/* wrap write pointer */
|
||||
if (radio->wr_index >= radio->buf_size)
|
||||
radio->wr_index = 0;
|
||||
|
||||
/* check for overflow */
|
||||
if (radio->wr_index == radio->rd_index) {
|
||||
/* increment and wrap read pointer */
|
||||
radio->rd_index += 3;
|
||||
if (radio->rd_index >= radio->buf_size)
|
||||
radio->rd_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (radio->wr_index != radio->rd_index)
|
||||
wake_up_interruptible(&radio->read_queue);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_i2c_interrupt - interrupt handler
|
||||
*/
|
||||
static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct si470x_device *radio = dev_id;
|
||||
|
||||
if (!work_pending(&radio->radio_work))
|
||||
schedule_work(&radio->radio_work);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_i2c_probe - probe for the device
|
||||
*/
|
||||
|
@ -268,6 +374,8 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
|
|||
retval = -ENOMEM;
|
||||
goto err_initial;
|
||||
}
|
||||
|
||||
INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work);
|
||||
radio->users = 0;
|
||||
radio->client = client;
|
||||
mutex_init(&radio->lock);
|
||||
|
@ -319,6 +427,26 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
|
|||
/* set initial frequency */
|
||||
si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
|
||||
|
||||
/* rds buffer allocation */
|
||||
radio->buf_size = rds_buf * 3;
|
||||
radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
|
||||
if (!radio->buffer) {
|
||||
retval = -EIO;
|
||||
goto err_video;
|
||||
}
|
||||
|
||||
/* rds buffer configuration */
|
||||
radio->wr_index = 0;
|
||||
radio->rd_index = 0;
|
||||
init_waitqueue_head(&radio->read_queue);
|
||||
|
||||
retval = request_irq(client->irq, si470x_i2c_interrupt,
|
||||
IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
|
||||
if (retval) {
|
||||
dev_err(&client->dev, "Failed to register interrupt\n");
|
||||
goto err_rds;
|
||||
}
|
||||
|
||||
/* register video device */
|
||||
retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
|
||||
radio_nr);
|
||||
|
@ -330,6 +458,9 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
|
|||
|
||||
return 0;
|
||||
err_all:
|
||||
free_irq(client->irq, radio);
|
||||
err_rds:
|
||||
kfree(radio->buffer);
|
||||
err_video:
|
||||
video_device_release(radio->videodev);
|
||||
err_radio:
|
||||
|
@ -346,6 +477,8 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
|
|||
{
|
||||
struct si470x_device *radio = i2c_get_clientdata(client);
|
||||
|
||||
free_irq(client->irq, radio);
|
||||
cancel_work_sync(&radio->radio_work);
|
||||
video_unregister_device(radio->videodev);
|
||||
kfree(radio);
|
||||
i2c_set_clientdata(client, NULL);
|
||||
|
@ -354,6 +487,44 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client)
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/*
|
||||
* si470x_i2c_suspend - suspend the device
|
||||
*/
|
||||
static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
{
|
||||
struct si470x_device *radio = i2c_get_clientdata(client);
|
||||
|
||||
/* power down */
|
||||
radio->registers[POWERCFG] |= POWERCFG_DISABLE;
|
||||
if (si470x_set_register(radio, POWERCFG) < 0)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_i2c_resume - resume the device
|
||||
*/
|
||||
static int si470x_i2c_resume(struct i2c_client *client)
|
||||
{
|
||||
struct si470x_device *radio = i2c_get_clientdata(client);
|
||||
|
||||
/* power up : need 110ms */
|
||||
radio->registers[POWERCFG] |= POWERCFG_ENABLE;
|
||||
if (si470x_set_register(radio, POWERCFG) < 0)
|
||||
return -EIO;
|
||||
msleep(110);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define si470x_i2c_suspend NULL
|
||||
#define si470x_i2c_resume NULL
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* si470x_i2c_driver - i2c driver interface
|
||||
*/
|
||||
|
@ -364,6 +535,8 @@ static struct i2c_driver si470x_i2c_driver = {
|
|||
},
|
||||
.probe = si470x_i2c_probe,
|
||||
.remove = __devexit_p(si470x_i2c_remove),
|
||||
.suspend = si470x_i2c_suspend,
|
||||
.resume = si470x_i2c_resume,
|
||||
.id_table = si470x_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -508,90 +508,10 @@ resubmit:
|
|||
* File Operations Interface
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* si470x_fops_read - read RDS data
|
||||
*/
|
||||
static ssize_t si470x_fops_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct si470x_device *radio = video_drvdata(file);
|
||||
int retval = 0;
|
||||
unsigned int block_count = 0;
|
||||
|
||||
/* switch on rds reception */
|
||||
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
|
||||
si470x_rds_on(radio);
|
||||
|
||||
/* block if no new data available */
|
||||
while (radio->wr_index == radio->rd_index) {
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
retval = -EWOULDBLOCK;
|
||||
goto done;
|
||||
}
|
||||
if (wait_event_interruptible(radio->read_queue,
|
||||
radio->wr_index != radio->rd_index) < 0) {
|
||||
retval = -EINTR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate block count from byte count */
|
||||
count /= 3;
|
||||
|
||||
/* copy RDS block out of internal buffer and to user buffer */
|
||||
mutex_lock(&radio->lock);
|
||||
while (block_count < count) {
|
||||
if (radio->rd_index == radio->wr_index)
|
||||
break;
|
||||
|
||||
/* always transfer rds complete blocks */
|
||||
if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
|
||||
/* retval = -EFAULT; */
|
||||
break;
|
||||
|
||||
/* increment and wrap read pointer */
|
||||
radio->rd_index += 3;
|
||||
if (radio->rd_index >= radio->buf_size)
|
||||
radio->rd_index = 0;
|
||||
|
||||
/* increment counters */
|
||||
block_count++;
|
||||
buf += 3;
|
||||
retval += 3;
|
||||
}
|
||||
mutex_unlock(&radio->lock);
|
||||
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_fops_poll - poll RDS data
|
||||
*/
|
||||
static unsigned int si470x_fops_poll(struct file *file,
|
||||
struct poll_table_struct *pts)
|
||||
{
|
||||
struct si470x_device *radio = video_drvdata(file);
|
||||
int retval = 0;
|
||||
|
||||
/* switch on rds reception */
|
||||
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
|
||||
si470x_rds_on(radio);
|
||||
|
||||
poll_wait(file, &radio->read_queue, pts);
|
||||
|
||||
if (radio->rd_index != radio->wr_index)
|
||||
retval = POLLIN | POLLRDNORM;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_fops_open - file open
|
||||
*/
|
||||
static int si470x_fops_open(struct file *file)
|
||||
int si470x_fops_open(struct file *file)
|
||||
{
|
||||
struct si470x_device *radio = video_drvdata(file);
|
||||
int retval;
|
||||
|
@ -645,7 +565,7 @@ done:
|
|||
/*
|
||||
* si470x_fops_release - file release
|
||||
*/
|
||||
static int si470x_fops_release(struct file *file)
|
||||
int si470x_fops_release(struct file *file)
|
||||
{
|
||||
struct si470x_device *radio = video_drvdata(file);
|
||||
int retval = 0;
|
||||
|
@ -688,19 +608,6 @@ done:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* si470x_fops - file operations interface
|
||||
*/
|
||||
const struct v4l2_file_operations si470x_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = si470x_fops_read,
|
||||
.poll = si470x_fops_poll,
|
||||
.ioctl = video_ioctl2,
|
||||
.open = si470x_fops_open,
|
||||
.release = si470x_fops_release,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Video4Linux Interface
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/input.h>
|
||||
|
@ -181,6 +182,7 @@ struct si470x_device {
|
|||
|
||||
#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
|
||||
struct i2c_client *client;
|
||||
struct work_struct radio_work;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -212,7 +214,6 @@ struct si470x_device {
|
|||
/**************************************************************************
|
||||
* Common Functions
|
||||
**************************************************************************/
|
||||
extern const struct v4l2_file_operations si470x_fops;
|
||||
extern struct video_device si470x_viddev_template;
|
||||
int si470x_get_register(struct si470x_device *radio, int regnr);
|
||||
int si470x_set_register(struct si470x_device *radio, int regnr);
|
||||
|
@ -221,5 +222,7 @@ int si470x_set_freq(struct si470x_device *radio, unsigned int freq);
|
|||
int si470x_start(struct si470x_device *radio);
|
||||
int si470x_stop(struct si470x_device *radio);
|
||||
int si470x_rds_on(struct si470x_device *radio);
|
||||
int si470x_fops_open(struct file *file);
|
||||
int si470x_fops_release(struct file *file);
|
||||
int si470x_vidioc_querycap(struct file *file, void *priv,
|
||||
struct v4l2_capability *capability);
|
||||
|
|
|
@ -37,10 +37,6 @@ config VIDEO_BTCX
|
|||
depends on PCI
|
||||
tristate
|
||||
|
||||
config VIDEO_IR
|
||||
tristate
|
||||
depends on INPUT
|
||||
|
||||
config VIDEO_TVEEPROM
|
||||
tristate
|
||||
depends on I2C
|
||||
|
@ -840,6 +836,12 @@ config SOC_CAMERA_MT9T031
|
|||
help
|
||||
This driver supports MT9T031 cameras from Micron.
|
||||
|
||||
config SOC_CAMERA_MT9T112
|
||||
tristate "mt9t112 support"
|
||||
depends on SOC_CAMERA && I2C
|
||||
help
|
||||
This driver supports MT9T112 cameras from Aptina.
|
||||
|
||||
config SOC_CAMERA_MT9V022
|
||||
tristate "mt9v022 support"
|
||||
depends on SOC_CAMERA && I2C
|
||||
|
|
|
@ -75,6 +75,7 @@ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
|
|||
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
|
||||
obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
|
||||
obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
|
||||
obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
|
||||
obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
|
||||
obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
|
||||
obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
|
||||
|
@ -149,7 +150,7 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
|
|||
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
|
||||
|
||||
obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
|
||||
obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
|
||||
obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o
|
||||
obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
|
||||
# soc-camera host drivers have to be linked after camera drivers
|
||||
obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
|
||||
|
|
|
@ -767,7 +767,6 @@ static struct video_device ar_template = {
|
|||
.name = "Colour AR VGA",
|
||||
.fops = &ar_fops,
|
||||
.release = ar_release,
|
||||
.minor = -1,
|
||||
};
|
||||
|
||||
#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
|
||||
|
@ -860,8 +859,8 @@ static int __init ar_init(void)
|
|||
goto out_dev;
|
||||
}
|
||||
|
||||
printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
|
||||
ar->vdev->num, M32R_IRQ_INT3, freq);
|
||||
printk("%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
|
||||
video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "au0828.h"
|
||||
#include "au0828-reg.h"
|
||||
|
||||
static LIST_HEAD(au0828_devlist);
|
||||
static DEFINE_MUTEX(au0828_sysfs_lock);
|
||||
|
||||
#define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1)
|
||||
|
@ -693,10 +692,8 @@ void au0828_analog_unregister(struct au0828_dev *dev)
|
|||
dprintk(1, "au0828_release_resources called\n");
|
||||
mutex_lock(&au0828_sysfs_lock);
|
||||
|
||||
if (dev->vdev) {
|
||||
list_del(&dev->au0828list);
|
||||
if (dev->vdev)
|
||||
video_unregister_device(dev->vdev);
|
||||
}
|
||||
if (dev->vbi_dev)
|
||||
video_unregister_device(dev->vbi_dev);
|
||||
|
||||
|
@ -737,29 +734,15 @@ static void res_free(struct au0828_fh *fh)
|
|||
|
||||
static int au0828_v4l2_open(struct file *filp)
|
||||
{
|
||||
int minor = video_devdata(filp)->minor;
|
||||
int ret = 0;
|
||||
struct au0828_dev *h, *dev = NULL;
|
||||
struct au0828_dev *dev = video_drvdata(filp);
|
||||
struct au0828_fh *fh;
|
||||
int type = 0;
|
||||
struct list_head *list;
|
||||
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
||||
list_for_each(list, &au0828_devlist) {
|
||||
h = list_entry(list, struct au0828_dev, au0828list);
|
||||
if (h->vdev->minor == minor) {
|
||||
dev = h;
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
}
|
||||
#ifdef VBI_IS_WORKING
|
||||
if (h->vbi_dev->minor == minor) {
|
||||
dev = h;
|
||||
type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
}
|
||||
if (video_devdata(filp)->vfl_type == VFL_TYPE_GRABBER)
|
||||
type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (NULL == dev)
|
||||
return -ENODEV;
|
||||
|
||||
fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
|
||||
if (NULL == fh) {
|
||||
|
@ -1587,7 +1570,6 @@ static const struct video_device au0828_video_template = {
|
|||
.fops = &au0828_v4l_fops,
|
||||
.release = video_device_release,
|
||||
.ioctl_ops = &video_ioctl_ops,
|
||||
.minor = -1,
|
||||
.tvnorms = V4L2_STD_NTSC_M,
|
||||
.current_norm = V4L2_STD_NTSC_M,
|
||||
};
|
||||
|
@ -1676,25 +1658,23 @@ int au0828_analog_register(struct au0828_dev *dev,
|
|||
strcpy(dev->vbi_dev->name, "au0828a vbi");
|
||||
#endif
|
||||
|
||||
list_add_tail(&dev->au0828list, &au0828_devlist);
|
||||
|
||||
/* Register the v4l2 device */
|
||||
video_set_drvdata(dev->vdev, dev);
|
||||
retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
|
||||
if (retval != 0) {
|
||||
dprintk(1, "unable to register video device (error = %d).\n",
|
||||
retval);
|
||||
list_del(&dev->au0828list);
|
||||
video_device_release(dev->vdev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifdef VBI_IS_WORKING
|
||||
/* Register the vbi device */
|
||||
video_set_drvdata(dev->vbi_dev, dev);
|
||||
retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
|
||||
if (retval != 0) {
|
||||
dprintk(1, "unable to register vbi device (error = %d).\n",
|
||||
retval);
|
||||
list_del(&dev->au0828list);
|
||||
video_device_release(dev->vbi_dev);
|
||||
video_device_release(dev->vdev);
|
||||
return -ENODEV;
|
||||
|
|
|
@ -192,7 +192,6 @@ struct au0828_dev {
|
|||
struct au0828_dvb dvb;
|
||||
|
||||
/* Analog */
|
||||
struct list_head au0828list;
|
||||
struct v4l2_device v4l2_dev;
|
||||
int users;
|
||||
unsigned int stream_on:1; /* Locks streams */
|
||||
|
|
|
@ -3206,24 +3206,24 @@ err:
|
|||
|
||||
static int bttv_open(struct file *file)
|
||||
{
|
||||
int minor = video_devdata(file)->minor;
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct bttv *btv = video_drvdata(file);
|
||||
struct bttv_fh *fh;
|
||||
enum v4l2_buf_type type = 0;
|
||||
|
||||
dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
|
||||
dprintk(KERN_DEBUG "bttv: open dev=%s\n", video_device_node_name(vdev));
|
||||
|
||||
lock_kernel();
|
||||
if (btv->video_dev->minor == minor) {
|
||||
if (vdev->vfl_type == VFL_TYPE_GRABBER) {
|
||||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
} else if (btv->vbi_dev->minor == minor) {
|
||||
} else if (vdev->vfl_type == VFL_TYPE_VBI) {
|
||||
type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
unlock_kernel();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
lock_kernel();
|
||||
|
||||
dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
|
||||
btv->c.nr,v4l2_type_names[type]);
|
||||
|
||||
|
@ -3397,7 +3397,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = {
|
|||
|
||||
static struct video_device bttv_video_template = {
|
||||
.fops = &bttv_fops,
|
||||
.minor = -1,
|
||||
.ioctl_ops = &bttv_ioctl_ops,
|
||||
.tvnorms = BTTV_NORMS,
|
||||
.current_norm = V4L2_STD_PAL,
|
||||
|
@ -3408,18 +3407,13 @@ static struct video_device bttv_video_template = {
|
|||
|
||||
static int radio_open(struct file *file)
|
||||
{
|
||||
int minor = video_devdata(file)->minor;
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct bttv *btv = video_drvdata(file);
|
||||
struct bttv_fh *fh;
|
||||
|
||||
dprintk("bttv: open minor=%d\n",minor);
|
||||
dprintk("bttv: open dev=%s\n", video_device_node_name(vdev));
|
||||
|
||||
lock_kernel();
|
||||
WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor);
|
||||
if (!btv->radio_dev || btv->radio_dev->minor != minor) {
|
||||
unlock_kernel();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dprintk("bttv%d: open called (radio)\n",btv->c.nr);
|
||||
|
||||
|
@ -3640,7 +3634,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
|
|||
|
||||
static struct video_device radio_template = {
|
||||
.fops = &radio_fops,
|
||||
.minor = -1,
|
||||
.ioctl_ops = &radio_ioctl_ops,
|
||||
};
|
||||
|
||||
|
@ -4208,21 +4201,21 @@ static struct video_device *vdev_init(struct bttv *btv,
|
|||
static void bttv_unregister_video(struct bttv *btv)
|
||||
{
|
||||
if (btv->video_dev) {
|
||||
if (-1 != btv->video_dev->minor)
|
||||
if (video_is_registered(btv->video_dev))
|
||||
video_unregister_device(btv->video_dev);
|
||||
else
|
||||
video_device_release(btv->video_dev);
|
||||
btv->video_dev = NULL;
|
||||
}
|
||||
if (btv->vbi_dev) {
|
||||
if (-1 != btv->vbi_dev->minor)
|
||||
if (video_is_registered(btv->vbi_dev))
|
||||
video_unregister_device(btv->vbi_dev);
|
||||
else
|
||||
video_device_release(btv->vbi_dev);
|
||||
btv->vbi_dev = NULL;
|
||||
}
|
||||
if (btv->radio_dev) {
|
||||
if (-1 != btv->radio_dev->minor)
|
||||
if (video_is_registered(btv->radio_dev))
|
||||
video_unregister_device(btv->radio_dev);
|
||||
else
|
||||
video_device_release(btv->radio_dev);
|
||||
|
@ -4244,8 +4237,8 @@ static int __devinit bttv_register_video(struct bttv *btv)
|
|||
if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER,
|
||||
video_nr[btv->c.nr]) < 0)
|
||||
goto err;
|
||||
printk(KERN_INFO "bttv%d: registered device video%d\n",
|
||||
btv->c.nr, btv->video_dev->num);
|
||||
printk(KERN_INFO "bttv%d: registered device %s\n",
|
||||
btv->c.nr, video_device_node_name(btv->video_dev));
|
||||
if (device_create_file(&btv->video_dev->dev,
|
||||
&dev_attr_card)<0) {
|
||||
printk(KERN_ERR "bttv%d: device_create_file 'card' "
|
||||
|
@ -4261,8 +4254,8 @@ static int __devinit bttv_register_video(struct bttv *btv)
|
|||
if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI,
|
||||
vbi_nr[btv->c.nr]) < 0)
|
||||
goto err;
|
||||
printk(KERN_INFO "bttv%d: registered device vbi%d\n",
|
||||
btv->c.nr, btv->vbi_dev->num);
|
||||
printk(KERN_INFO "bttv%d: registered device %s\n",
|
||||
btv->c.nr, video_device_node_name(btv->vbi_dev));
|
||||
|
||||
if (!btv->has_radio)
|
||||
return 0;
|
||||
|
@ -4273,8 +4266,8 @@ static int __devinit bttv_register_video(struct bttv *btv)
|
|||
if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,
|
||||
radio_nr[btv->c.nr]) < 0)
|
||||
goto err;
|
||||
printk(KERN_INFO "bttv%d: registered device radio%d\n",
|
||||
btv->c.nr, btv->radio_dev->num);
|
||||
printk(KERN_INFO "bttv%d: registered device %s\n",
|
||||
btv->c.nr, video_device_node_name(btv->radio_dev));
|
||||
|
||||
/* all done */
|
||||
return 0;
|
||||
|
|
|
@ -40,7 +40,7 @@ static int i2c_debug;
|
|||
static int i2c_hw;
|
||||
static int i2c_scan;
|
||||
module_param(i2c_debug, int, 0644);
|
||||
MODULE_PARM_DESC(i2c_hw,"configure i2c debug level");
|
||||
MODULE_PARM_DESC(i2c_debug, "configure i2c debug level");
|
||||
module_param(i2c_hw, int, 0444);
|
||||
MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, "
|
||||
"instead of software bitbang");
|
||||
|
@ -400,7 +400,7 @@ int __devinit init_bttv_i2c(struct bttv *btv)
|
|||
That's why we probe 0x1a (~0x34) first. CB
|
||||
*/
|
||||
const unsigned short addr_list[] = {
|
||||
0x1a, 0x18, 0x4b, 0x64, 0x30,
|
||||
0x1a, 0x18, 0x4b, 0x64, 0x30, 0x71,
|
||||
I2C_CLIENT_END
|
||||
};
|
||||
|
||||
|
|
|
@ -368,7 +368,7 @@ int bttv_input_init(struct bttv *btv)
|
|||
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
|
||||
pci_name(btv->c.pci));
|
||||
|
||||
err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
|
||||
err = ir_input_init(input_dev, &ir->ir, ir_type);
|
||||
if (err < 0)
|
||||
goto err_out_free;
|
||||
|
||||
|
@ -389,7 +389,7 @@ int bttv_input_init(struct bttv *btv)
|
|||
bttv_ir_start(btv, ir);
|
||||
|
||||
/* all done */
|
||||
err = input_register_device(btv->remote->dev);
|
||||
err = ir_input_register(btv->remote->dev, ir_codes);
|
||||
if (err)
|
||||
goto err_out_stop;
|
||||
|
||||
|
@ -403,8 +403,6 @@ int bttv_input_init(struct bttv *btv)
|
|||
bttv_ir_stop(btv);
|
||||
btv->remote = NULL;
|
||||
err_out_free:
|
||||
ir_input_free(input_dev);
|
||||
input_free_device(input_dev);
|
||||
kfree(ir);
|
||||
return err;
|
||||
}
|
||||
|
@ -415,8 +413,7 @@ void bttv_input_fini(struct bttv *btv)
|
|||
return;
|
||||
|
||||
bttv_ir_stop(btv);
|
||||
ir_input_free(btv->remote->dev);
|
||||
input_unregister_device(btv->remote->dev);
|
||||
ir_input_unregister(btv->remote->dev);
|
||||
kfree(btv->remote);
|
||||
btv->remote = NULL;
|
||||
}
|
||||
|
|
|
@ -809,8 +809,8 @@ static int init_cqcam(struct parport *port)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
|
||||
qcam->vdev.num, qcam->pport->name);
|
||||
printk(KERN_INFO "%s: Colour QuickCam found on %s\n",
|
||||
video_device_node_name(&qcam->vdev), qcam->pport->name);
|
||||
|
||||
qcams[num_cams++] = qcam;
|
||||
|
||||
|
|
|
@ -1723,7 +1723,6 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
|
|||
|
||||
static struct video_device cafe_v4l_template = {
|
||||
.name = "cafe",
|
||||
.minor = -1, /* Get one dynamically */
|
||||
.tvnorms = V4L2_STD_NTSC_M,
|
||||
.current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/ctype.h>
|
||||
|
@ -244,72 +245,67 @@ static void rvfree(void *mem, unsigned long size)
|
|||
#ifdef CONFIG_PROC_FS
|
||||
static struct proc_dir_entry *cpia_proc_root=NULL;
|
||||
|
||||
static int cpia_read_proc(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
static int cpia_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
char *out = page;
|
||||
int len, tmp;
|
||||
struct cam_data *cam = data;
|
||||
struct cam_data *cam = m->private;
|
||||
int tmp;
|
||||
char tmpstr[29];
|
||||
|
||||
/* IMPORTANT: This output MUST be kept under PAGE_SIZE
|
||||
* or we need to get more sophisticated. */
|
||||
|
||||
out += sprintf(out, "read-only\n-----------------------\n");
|
||||
out += sprintf(out, "V4L Driver version: %d.%d.%d\n",
|
||||
seq_printf(m, "read-only\n-----------------------\n");
|
||||
seq_printf(m, "V4L Driver version: %d.%d.%d\n",
|
||||
CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
|
||||
out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n",
|
||||
seq_printf(m, "CPIA Version: %d.%02d (%d.%d)\n",
|
||||
cam->params.version.firmwareVersion,
|
||||
cam->params.version.firmwareRevision,
|
||||
cam->params.version.vcVersion,
|
||||
cam->params.version.vcRevision);
|
||||
out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n",
|
||||
seq_printf(m, "CPIA PnP-ID: %04x:%04x:%04x\n",
|
||||
cam->params.pnpID.vendor, cam->params.pnpID.product,
|
||||
cam->params.pnpID.deviceRevision);
|
||||
out += sprintf(out, "VP-Version: %d.%d %04x\n",
|
||||
seq_printf(m, "VP-Version: %d.%d %04x\n",
|
||||
cam->params.vpVersion.vpVersion,
|
||||
cam->params.vpVersion.vpRevision,
|
||||
cam->params.vpVersion.cameraHeadID);
|
||||
|
||||
out += sprintf(out, "system_state: %#04x\n",
|
||||
seq_printf(m, "system_state: %#04x\n",
|
||||
cam->params.status.systemState);
|
||||
out += sprintf(out, "grab_state: %#04x\n",
|
||||
seq_printf(m, "grab_state: %#04x\n",
|
||||
cam->params.status.grabState);
|
||||
out += sprintf(out, "stream_state: %#04x\n",
|
||||
seq_printf(m, "stream_state: %#04x\n",
|
||||
cam->params.status.streamState);
|
||||
out += sprintf(out, "fatal_error: %#04x\n",
|
||||
seq_printf(m, "fatal_error: %#04x\n",
|
||||
cam->params.status.fatalError);
|
||||
out += sprintf(out, "cmd_error: %#04x\n",
|
||||
seq_printf(m, "cmd_error: %#04x\n",
|
||||
cam->params.status.cmdError);
|
||||
out += sprintf(out, "debug_flags: %#04x\n",
|
||||
seq_printf(m, "debug_flags: %#04x\n",
|
||||
cam->params.status.debugFlags);
|
||||
out += sprintf(out, "vp_status: %#04x\n",
|
||||
seq_printf(m, "vp_status: %#04x\n",
|
||||
cam->params.status.vpStatus);
|
||||
out += sprintf(out, "error_code: %#04x\n",
|
||||
seq_printf(m, "error_code: %#04x\n",
|
||||
cam->params.status.errorCode);
|
||||
/* QX3 specific entries */
|
||||
if (cam->params.qx3.qx3_detected) {
|
||||
out += sprintf(out, "button: %4d\n",
|
||||
seq_printf(m, "button: %4d\n",
|
||||
cam->params.qx3.button);
|
||||
out += sprintf(out, "cradled: %4d\n",
|
||||
seq_printf(m, "cradled: %4d\n",
|
||||
cam->params.qx3.cradled);
|
||||
}
|
||||
out += sprintf(out, "video_size: %s\n",
|
||||
seq_printf(m, "video_size: %s\n",
|
||||
cam->params.format.videoSize == VIDEOSIZE_CIF ?
|
||||
"CIF " : "QCIF");
|
||||
out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n",
|
||||
seq_printf(m, "roi: (%3d, %3d) to (%3d, %3d)\n",
|
||||
cam->params.roi.colStart*8,
|
||||
cam->params.roi.rowStart*4,
|
||||
cam->params.roi.colEnd*8,
|
||||
cam->params.roi.rowEnd*4);
|
||||
out += sprintf(out, "actual_fps: %3d\n", cam->fps);
|
||||
out += sprintf(out, "transfer_rate: %4dkB/s\n",
|
||||
seq_printf(m, "actual_fps: %3d\n", cam->fps);
|
||||
seq_printf(m, "transfer_rate: %4dkB/s\n",
|
||||
cam->transfer_rate);
|
||||
|
||||
out += sprintf(out, "\nread-write\n");
|
||||
out += sprintf(out, "----------------------- current min"
|
||||
seq_printf(m, "\nread-write\n");
|
||||
seq_printf(m, "----------------------- current min"
|
||||
" max default comment\n");
|
||||
out += sprintf(out, "brightness: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "brightness: %8d %8d %8d %8d\n",
|
||||
cam->params.colourParams.brightness, 0, 100, 50);
|
||||
if (cam->params.version.firmwareVersion == 1 &&
|
||||
cam->params.version.firmwareRevision == 2)
|
||||
|
@ -318,26 +314,26 @@ static int cpia_read_proc(char *page, char **start, off_t off,
|
|||
else
|
||||
tmp = 96;
|
||||
|
||||
out += sprintf(out, "contrast: %8d %8d %8d %8d"
|
||||
seq_printf(m, "contrast: %8d %8d %8d %8d"
|
||||
" steps of 8\n",
|
||||
cam->params.colourParams.contrast, 0, tmp, 48);
|
||||
out += sprintf(out, "saturation: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "saturation: %8d %8d %8d %8d\n",
|
||||
cam->params.colourParams.saturation, 0, 100, 50);
|
||||
tmp = (25000+5000*cam->params.sensorFps.baserate)/
|
||||
(1<<cam->params.sensorFps.divisor);
|
||||
out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n",
|
||||
seq_printf(m, "sensor_fps: %4d.%03d %8d %8d %8d\n",
|
||||
tmp/1000, tmp%1000, 3, 30, 15);
|
||||
out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "stream_start_line: %8d %8d %8d %8d\n",
|
||||
2*cam->params.streamStartLine, 0,
|
||||
cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144,
|
||||
cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120);
|
||||
out += sprintf(out, "sub_sample: %8s %8s %8s %8s\n",
|
||||
seq_printf(m, "sub_sample: %8s %8s %8s %8s\n",
|
||||
cam->params.format.subSample == SUBSAMPLE_420 ?
|
||||
"420" : "422", "420", "422", "422");
|
||||
out += sprintf(out, "yuv_order: %8s %8s %8s %8s\n",
|
||||
seq_printf(m, "yuv_order: %8s %8s %8s %8s\n",
|
||||
cam->params.format.yuvOrder == YUVORDER_YUYV ?
|
||||
"YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV");
|
||||
out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n",
|
||||
seq_printf(m, "ecp_timing: %8s %8s %8s %8s\n",
|
||||
cam->params.ecpTiming ? "slow" : "normal", "slow",
|
||||
"normal", "normal");
|
||||
|
||||
|
@ -346,13 +342,13 @@ static int cpia_read_proc(char *page, char **start, off_t off,
|
|||
} else {
|
||||
sprintf(tmpstr, "manual");
|
||||
}
|
||||
out += sprintf(out, "color_balance_mode: %8s %8s %8s"
|
||||
seq_printf(m, "color_balance_mode: %8s %8s %8s"
|
||||
" %8s\n", tmpstr, "manual", "auto", "auto");
|
||||
out += sprintf(out, "red_gain: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "red_gain: %8d %8d %8d %8d\n",
|
||||
cam->params.colourBalance.redGain, 0, 212, 32);
|
||||
out += sprintf(out, "green_gain: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "green_gain: %8d %8d %8d %8d\n",
|
||||
cam->params.colourBalance.greenGain, 0, 212, 6);
|
||||
out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "blue_gain: %8d %8d %8d %8d\n",
|
||||
cam->params.colourBalance.blueGain, 0, 212, 92);
|
||||
|
||||
if (cam->params.version.firmwareVersion == 1 &&
|
||||
|
@ -363,10 +359,10 @@ static int cpia_read_proc(char *page, char **start, off_t off,
|
|||
sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2);
|
||||
|
||||
if (cam->params.exposure.gainMode == 0)
|
||||
out += sprintf(out, "max_gain: unknown %28s"
|
||||
seq_printf(m, "max_gain: unknown %28s"
|
||||
" powers of 2\n", tmpstr);
|
||||
else
|
||||
out += sprintf(out, "max_gain: %8d %28s"
|
||||
seq_printf(m, "max_gain: %8d %28s"
|
||||
" 1,2,4 or 8 \n",
|
||||
1<<(cam->params.exposure.gainMode-1), tmpstr);
|
||||
|
||||
|
@ -382,12 +378,12 @@ static int cpia_read_proc(char *page, char **start, off_t off,
|
|||
sprintf(tmpstr, "unknown");
|
||||
break;
|
||||
}
|
||||
out += sprintf(out, "exposure_mode: %8s %8s %8s"
|
||||
seq_printf(m, "exposure_mode: %8s %8s %8s"
|
||||
" %8s\n", tmpstr, "manual", "auto", "auto");
|
||||
out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n",
|
||||
seq_printf(m, "centre_weight: %8s %8s %8s %8s\n",
|
||||
(2-cam->params.exposure.centreWeight) ? "on" : "off",
|
||||
"off", "on", "on");
|
||||
out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
|
||||
seq_printf(m, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
|
||||
1<<cam->params.exposure.gain, 1, 1);
|
||||
if (cam->params.version.firmwareVersion == 1 &&
|
||||
cam->params.version.firmwareRevision == 2)
|
||||
|
@ -396,7 +392,7 @@ static int cpia_read_proc(char *page, char **start, off_t off,
|
|||
else
|
||||
tmp = 510;
|
||||
|
||||
out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "fine_exp: %8d %8d %8d %8d\n",
|
||||
cam->params.exposure.fineExp*2, 0, tmp, 0);
|
||||
if (cam->params.version.firmwareVersion == 1 &&
|
||||
cam->params.version.firmwareRevision == 2)
|
||||
|
@ -405,127 +401,122 @@ static int cpia_read_proc(char *page, char **start, off_t off,
|
|||
else
|
||||
tmp = MAX_EXP;
|
||||
|
||||
out += sprintf(out, "coarse_exp: %8d %8d %8d"
|
||||
seq_printf(m, "coarse_exp: %8d %8d %8d"
|
||||
" %8d\n", cam->params.exposure.coarseExpLo+
|
||||
256*cam->params.exposure.coarseExpHi, 0, tmp, 185);
|
||||
out += sprintf(out, "red_comp: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "red_comp: %8d %8d %8d %8d\n",
|
||||
cam->params.exposure.redComp, COMP_RED, 255, COMP_RED);
|
||||
out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "green1_comp: %8d %8d %8d %8d\n",
|
||||
cam->params.exposure.green1Comp, COMP_GREEN1, 255,
|
||||
COMP_GREEN1);
|
||||
out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "green2_comp: %8d %8d %8d %8d\n",
|
||||
cam->params.exposure.green2Comp, COMP_GREEN2, 255,
|
||||
COMP_GREEN2);
|
||||
out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "blue_comp: %8d %8d %8d %8d\n",
|
||||
cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE);
|
||||
|
||||
out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
|
||||
seq_printf(m, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
|
||||
cam->params.apcor.gain1, 0, 0xff, 0x1c);
|
||||
out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
|
||||
seq_printf(m, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
|
||||
cam->params.apcor.gain2, 0, 0xff, 0x1a);
|
||||
out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
|
||||
seq_printf(m, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
|
||||
cam->params.apcor.gain4, 0, 0xff, 0x2d);
|
||||
out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
|
||||
seq_printf(m, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
|
||||
cam->params.apcor.gain8, 0, 0xff, 0x2a);
|
||||
out += sprintf(out, "vl_offset_gain1: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "vl_offset_gain1: %8d %8d %8d %8d\n",
|
||||
cam->params.vlOffset.gain1, 0, 255, 24);
|
||||
out += sprintf(out, "vl_offset_gain2: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "vl_offset_gain2: %8d %8d %8d %8d\n",
|
||||
cam->params.vlOffset.gain2, 0, 255, 28);
|
||||
out += sprintf(out, "vl_offset_gain4: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "vl_offset_gain4: %8d %8d %8d %8d\n",
|
||||
cam->params.vlOffset.gain4, 0, 255, 30);
|
||||
out += sprintf(out, "vl_offset_gain8: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "vl_offset_gain8: %8d %8d %8d %8d\n",
|
||||
cam->params.vlOffset.gain8, 0, 255, 30);
|
||||
out += sprintf(out, "flicker_control: %8s %8s %8s %8s\n",
|
||||
seq_printf(m, "flicker_control: %8s %8s %8s %8s\n",
|
||||
cam->params.flickerControl.flickerMode ? "on" : "off",
|
||||
"off", "on", "off");
|
||||
out += sprintf(out, "mains_frequency: %8d %8d %8d %8d"
|
||||
seq_printf(m, "mains_frequency: %8d %8d %8d %8d"
|
||||
" only 50/60\n",
|
||||
cam->mainsFreq ? 60 : 50, 50, 60, 50);
|
||||
if(cam->params.flickerControl.allowableOverExposure < 0)
|
||||
out += sprintf(out, "allowable_overexposure: %4dauto auto %8d auto\n",
|
||||
seq_printf(m, "allowable_overexposure: %4dauto auto %8d auto\n",
|
||||
-cam->params.flickerControl.allowableOverExposure,
|
||||
255);
|
||||
else
|
||||
out += sprintf(out, "allowable_overexposure: %8d auto %8d auto\n",
|
||||
seq_printf(m, "allowable_overexposure: %8d auto %8d auto\n",
|
||||
cam->params.flickerControl.allowableOverExposure,
|
||||
255);
|
||||
out += sprintf(out, "compression_mode: ");
|
||||
seq_printf(m, "compression_mode: ");
|
||||
switch(cam->params.compression.mode) {
|
||||
case CPIA_COMPRESSION_NONE:
|
||||
out += sprintf(out, "%8s", "none");
|
||||
seq_printf(m, "%8s", "none");
|
||||
break;
|
||||
case CPIA_COMPRESSION_AUTO:
|
||||
out += sprintf(out, "%8s", "auto");
|
||||
seq_printf(m, "%8s", "auto");
|
||||
break;
|
||||
case CPIA_COMPRESSION_MANUAL:
|
||||
out += sprintf(out, "%8s", "manual");
|
||||
seq_printf(m, "%8s", "manual");
|
||||
break;
|
||||
default:
|
||||
out += sprintf(out, "%8s", "unknown");
|
||||
seq_printf(m, "%8s", "unknown");
|
||||
break;
|
||||
}
|
||||
out += sprintf(out, " none,auto,manual auto\n");
|
||||
out += sprintf(out, "decimation_enable: %8s %8s %8s %8s\n",
|
||||
seq_printf(m, " none,auto,manual auto\n");
|
||||
seq_printf(m, "decimation_enable: %8s %8s %8s %8s\n",
|
||||
cam->params.compression.decimation ==
|
||||
DECIMATION_ENAB ? "on":"off", "off", "on",
|
||||
"off");
|
||||
out += sprintf(out, "compression_target: %9s %9s %9s %9s\n",
|
||||
seq_printf(m, "compression_target: %9s %9s %9s %9s\n",
|
||||
cam->params.compressionTarget.frTargeting ==
|
||||
CPIA_COMPRESSION_TARGET_FRAMERATE ?
|
||||
"framerate":"quality",
|
||||
"framerate", "quality", "quality");
|
||||
out += sprintf(out, "target_framerate: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "target_framerate: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionTarget.targetFR, 1, 30, 15);
|
||||
out += sprintf(out, "target_quality: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "target_quality: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionTarget.targetQ, 1, 64, 5);
|
||||
out += sprintf(out, "y_threshold: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "y_threshold: %8d %8d %8d %8d\n",
|
||||
cam->params.yuvThreshold.yThreshold, 0, 31, 6);
|
||||
out += sprintf(out, "uv_threshold: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "uv_threshold: %8d %8d %8d %8d\n",
|
||||
cam->params.yuvThreshold.uvThreshold, 0, 31, 6);
|
||||
out += sprintf(out, "hysteresis: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "hysteresis: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionParams.hysteresis, 0, 255, 3);
|
||||
out += sprintf(out, "threshold_max: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "threshold_max: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionParams.threshMax, 0, 255, 11);
|
||||
out += sprintf(out, "small_step: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "small_step: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionParams.smallStep, 0, 255, 1);
|
||||
out += sprintf(out, "large_step: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "large_step: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionParams.largeStep, 0, 255, 3);
|
||||
out += sprintf(out, "decimation_hysteresis: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "decimation_hysteresis: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionParams.decimationHysteresis,
|
||||
0, 255, 2);
|
||||
out += sprintf(out, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionParams.frDiffStepThresh,
|
||||
0, 255, 5);
|
||||
out += sprintf(out, "q_diff_step_thresh: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "q_diff_step_thresh: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionParams.qDiffStepThresh,
|
||||
0, 255, 3);
|
||||
out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n",
|
||||
seq_printf(m, "decimation_thresh_mod: %8d %8d %8d %8d\n",
|
||||
cam->params.compressionParams.decimationThreshMod,
|
||||
0, 255, 2);
|
||||
/* QX3 specific entries */
|
||||
if (cam->params.qx3.qx3_detected) {
|
||||
out += sprintf(out, "toplight: %8s %8s %8s %8s\n",
|
||||
seq_printf(m, "toplight: %8s %8s %8s %8s\n",
|
||||
cam->params.qx3.toplight ? "on" : "off",
|
||||
"off", "on", "off");
|
||||
out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n",
|
||||
seq_printf(m, "bottomlight: %8s %8s %8s %8s\n",
|
||||
cam->params.qx3.bottomlight ? "on" : "off",
|
||||
"off", "on", "off");
|
||||
}
|
||||
|
||||
len = out - page;
|
||||
len -= off;
|
||||
if (len < count) {
|
||||
*eof = 1;
|
||||
if (len <= 0) return 0;
|
||||
} else
|
||||
len = count;
|
||||
|
||||
*start = page + off;
|
||||
return len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpia_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, cpia_proc_show, PDE(inode)->data);
|
||||
}
|
||||
|
||||
static int match(char *checkstr, char **buffer, unsigned long *count,
|
||||
static int match(char *checkstr, char **buffer, size_t *count,
|
||||
int *find_colon, int *err)
|
||||
{
|
||||
int ret, colon_found = 1;
|
||||
|
@ -551,7 +542,7 @@ static int match(char *checkstr, char **buffer, unsigned long *count,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static unsigned long int value(char **buffer, unsigned long *count, int *err)
|
||||
static unsigned long int value(char **buffer, size_t *count, int *err)
|
||||
{
|
||||
char *p;
|
||||
unsigned long int ret;
|
||||
|
@ -565,10 +556,10 @@ static unsigned long int value(char **buffer, unsigned long *count, int *err)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int cpia_write_proc(struct file *file, const char __user *buf,
|
||||
unsigned long count, void *data)
|
||||
static ssize_t cpia_proc_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct cam_data *cam = data;
|
||||
struct cam_data *cam = PDE(file->f_path.dentry->d_inode)->data;
|
||||
struct cam_params new_params;
|
||||
char *page, *buffer;
|
||||
int retval, find_colon;
|
||||
|
@ -582,7 +573,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf,
|
|||
* from the comx driver
|
||||
*/
|
||||
if (count > PAGE_SIZE) {
|
||||
printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE);
|
||||
printk(KERN_ERR "count is %zu > %d!!!\n", count, (int)PAGE_SIZE);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
@ -1340,23 +1331,28 @@ out:
|
|||
return retval;
|
||||
}
|
||||
|
||||
static const struct file_operations cpia_proc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = cpia_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = cpia_proc_write,
|
||||
};
|
||||
|
||||
static void create_proc_cpia_cam(struct cam_data *cam)
|
||||
{
|
||||
char name[5 + 1 + 10 + 1];
|
||||
struct proc_dir_entry *ent;
|
||||
|
||||
if (!cpia_proc_root || !cam)
|
||||
return;
|
||||
|
||||
snprintf(name, sizeof(name), "video%d", cam->vdev.num);
|
||||
|
||||
ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root);
|
||||
ent = proc_create_data(video_device_node_name(&cam->vdev),
|
||||
S_IRUGO|S_IWUSR, cpia_proc_root,
|
||||
&cpia_proc_fops, cam);
|
||||
if (!ent)
|
||||
return;
|
||||
|
||||
ent->data = cam;
|
||||
ent->read_proc = cpia_read_proc;
|
||||
ent->write_proc = cpia_write_proc;
|
||||
/*
|
||||
size of the proc entry is 3736 bytes for the standard webcam;
|
||||
the extra features of the QX3 microscope add 189 bytes.
|
||||
|
@ -1368,13 +1364,10 @@ static void create_proc_cpia_cam(struct cam_data *cam)
|
|||
|
||||
static void destroy_proc_cpia_cam(struct cam_data *cam)
|
||||
{
|
||||
char name[5 + 1 + 10 + 1];
|
||||
|
||||
if (!cam || !cam->proc_entry)
|
||||
return;
|
||||
|
||||
snprintf(name, sizeof(name), "video%d", cam->vdev.num);
|
||||
remove_proc_entry(name, cpia_proc_root);
|
||||
remove_proc_entry(video_device_node_name(&cam->vdev), cpia_proc_root);
|
||||
cam->proc_entry = NULL;
|
||||
}
|
||||
|
||||
|
@ -3999,7 +3992,7 @@ void cpia_unregister_camera(struct cam_data *cam)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
DBG("destroying /proc/cpia/video%d\n", cam->vdev.num);
|
||||
DBG("destroying /proc/cpia/%s\n", video_device_node_name(&cam->vdev));
|
||||
destroy_proc_cpia_cam(cam);
|
||||
#endif
|
||||
if (!cam->open_count) {
|
||||
|
|
|
@ -38,17 +38,12 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/videodev.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
|
||||
#include "cpia2.h"
|
||||
#include "cpia2dev.h"
|
||||
|
||||
|
||||
//#define _CPIA2_DEBUG_
|
||||
|
||||
#define MAKE_STRING_1(x) #x
|
||||
#define MAKE_STRING(x) MAKE_STRING_1(x)
|
||||
|
||||
static int video_nr = -1;
|
||||
module_param(video_nr, int, 0);
|
||||
MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
|
||||
|
@ -60,26 +55,26 @@ MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k)
|
|||
static int num_buffers = 3;
|
||||
module_param(num_buffers, int, 0);
|
||||
MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-"
|
||||
MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)");
|
||||
__stringify(VIDEO_MAX_FRAME) ", default 3)");
|
||||
|
||||
static int alternate = DEFAULT_ALT;
|
||||
module_param(alternate, int, 0);
|
||||
MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-"
|
||||
MAKE_STRING(USBIF_ISO_6) ", default "
|
||||
MAKE_STRING(DEFAULT_ALT) ")");
|
||||
MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-"
|
||||
__stringify(USBIF_ISO_6) ", default "
|
||||
__stringify(DEFAULT_ALT) ")");
|
||||
|
||||
static int flicker_freq = 60;
|
||||
module_param(flicker_freq, int, 0);
|
||||
MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or"
|
||||
MAKE_STRING(60) ", default "
|
||||
MAKE_STRING(60) ")");
|
||||
MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or"
|
||||
__stringify(60) ", default "
|
||||
__stringify(60) ")");
|
||||
|
||||
static int flicker_mode = NEVER_FLICKER;
|
||||
module_param(flicker_mode, int, 0);
|
||||
MODULE_PARM_DESC(flicker_mode,
|
||||
"Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or"
|
||||
MAKE_STRING(ANTI_FLICKER_ON) ", default "
|
||||
MAKE_STRING(NEVER_FLICKER) ")");
|
||||
"Flicker supression (" __stringify(NEVER_FLICKER) "or"
|
||||
__stringify(ANTI_FLICKER_ON) ", default "
|
||||
__stringify(NEVER_FLICKER) ")");
|
||||
|
||||
MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>");
|
||||
MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras");
|
||||
|
@ -1926,7 +1921,6 @@ static const struct v4l2_file_operations fops_template = {
|
|||
static struct video_device cpia2_template = {
|
||||
/* I could not find any place for the old .initialize initializer?? */
|
||||
.name= "CPiA2 Camera",
|
||||
.minor= -1,
|
||||
.fops= &fops_template,
|
||||
.release= video_device_release,
|
||||
};
|
||||
|
@ -1967,9 +1961,9 @@ void cpia2_unregister_camera(struct camera_data *cam)
|
|||
if (!cam->open_count) {
|
||||
video_unregister_device(cam->vdev);
|
||||
} else {
|
||||
LOG("/dev/video%d removed while open, "
|
||||
"deferring video_unregister_device\n",
|
||||
cam->vdev->num);
|
||||
LOG("%s removed while open, deferring "
|
||||
"video_unregister_device\n",
|
||||
video_device_node_name(cam->vdev));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -758,8 +758,8 @@ int cx18_v4l2_open(struct file *filp)
|
|||
|
||||
mutex_lock(&cx->serialize_lock);
|
||||
if (cx18_init_on_first_open(cx)) {
|
||||
CX18_ERR("Failed to initialize on minor %d\n",
|
||||
video_dev->minor);
|
||||
CX18_ERR("Failed to initialize on %s\n",
|
||||
video_device_node_name(video_dev));
|
||||
mutex_unlock(&cx->serialize_lock);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
|
|
@ -219,6 +219,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
|
|||
{
|
||||
struct cx18_stream *s = &cx->streams[type];
|
||||
int vfl_type = cx18_stream_info[type].vfl_type;
|
||||
const char *name;
|
||||
int num, ret;
|
||||
|
||||
/* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
|
||||
|
@ -258,31 +259,30 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
|
|||
s->video_dev = NULL;
|
||||
return ret;
|
||||
}
|
||||
num = s->video_dev->num;
|
||||
|
||||
name = video_device_node_name(s->video_dev);
|
||||
|
||||
switch (vfl_type) {
|
||||
case VFL_TYPE_GRABBER:
|
||||
CX18_INFO("Registered device video%d for %s "
|
||||
"(%d x %d.%02d kB)\n",
|
||||
num, s->name, cx->stream_buffers[type],
|
||||
CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n",
|
||||
name, s->name, cx->stream_buffers[type],
|
||||
cx->stream_buf_size[type] / 1024,
|
||||
(cx->stream_buf_size[type] * 100 / 1024) % 100);
|
||||
break;
|
||||
|
||||
case VFL_TYPE_RADIO:
|
||||
CX18_INFO("Registered device radio%d for %s\n",
|
||||
num, s->name);
|
||||
CX18_INFO("Registered device %s for %s\n", name, s->name);
|
||||
break;
|
||||
|
||||
case VFL_TYPE_VBI:
|
||||
if (cx->stream_buffers[type])
|
||||
CX18_INFO("Registered device vbi%d for %s "
|
||||
CX18_INFO("Registered device %s for %s "
|
||||
"(%d x %d bytes)\n",
|
||||
num, s->name, cx->stream_buffers[type],
|
||||
name, s->name, cx->stream_buffers[type],
|
||||
cx->stream_buf_size[type]);
|
||||
else
|
||||
CX18_INFO("Registered device vbi%d for %s\n",
|
||||
num, s->name);
|
||||
CX18_INFO("Registered device %s for %s\n",
|
||||
name, s->name);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,19 +68,19 @@ struct cx231xx_board cx231xx_boards[] = {
|
|||
.type = CX231XX_VMUX_TELEVISION,
|
||||
.vmux = CX231XX_VIN_3_1,
|
||||
.amux = CX231XX_AMUX_VIDEO,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}, {
|
||||
.type = CX231XX_VMUX_COMPOSITE1,
|
||||
.vmux = CX231XX_VIN_2_1,
|
||||
.amux = CX231XX_AMUX_LINE_IN,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}, {
|
||||
.type = CX231XX_VMUX_SVIDEO,
|
||||
.vmux = CX231XX_VIN_1_1 |
|
||||
(CX231XX_VIN_1_2 << 8) |
|
||||
CX25840_SVIDEO_ON,
|
||||
.amux = CX231XX_AMUX_LINE_IN,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -107,19 +107,19 @@ struct cx231xx_board cx231xx_boards[] = {
|
|||
.type = CX231XX_VMUX_TELEVISION,
|
||||
.vmux = CX231XX_VIN_3_1,
|
||||
.amux = CX231XX_AMUX_VIDEO,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}, {
|
||||
.type = CX231XX_VMUX_COMPOSITE1,
|
||||
.vmux = CX231XX_VIN_2_1,
|
||||
.amux = CX231XX_AMUX_LINE_IN,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}, {
|
||||
.type = CX231XX_VMUX_SVIDEO,
|
||||
.vmux = CX231XX_VIN_1_1 |
|
||||
(CX231XX_VIN_1_2 << 8) |
|
||||
CX25840_SVIDEO_ON,
|
||||
.amux = CX231XX_AMUX_LINE_IN,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -147,19 +147,19 @@ struct cx231xx_board cx231xx_boards[] = {
|
|||
.type = CX231XX_VMUX_TELEVISION,
|
||||
.vmux = CX231XX_VIN_3_1,
|
||||
.amux = CX231XX_AMUX_VIDEO,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}, {
|
||||
.type = CX231XX_VMUX_COMPOSITE1,
|
||||
.vmux = CX231XX_VIN_2_1,
|
||||
.amux = CX231XX_AMUX_LINE_IN,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}, {
|
||||
.type = CX231XX_VMUX_SVIDEO,
|
||||
.vmux = CX231XX_VIN_1_1 |
|
||||
(CX231XX_VIN_1_2 << 8) |
|
||||
CX25840_SVIDEO_ON,
|
||||
.amux = CX231XX_AMUX_LINE_IN,
|
||||
.gpio = 0,
|
||||
.gpio = NULL,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -856,8 +856,9 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface)
|
|||
|
||||
if (dev->users) {
|
||||
cx231xx_warn
|
||||
("device /dev/video%d is open! Deregistration and memory "
|
||||
"deallocation are deferred on close.\n", dev->vdev->num);
|
||||
("device %s is open! Deregistration and memory "
|
||||
"deallocation are deferred on close.\n",
|
||||
video_device_node_name(dev->vdev));
|
||||
|
||||
dev->state |= DEV_MISCONFIGURED;
|
||||
cx231xx_uninit_isoc(dev);
|
||||
|
|
|
@ -66,32 +66,6 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
|
|||
static LIST_HEAD(cx231xx_devlist);
|
||||
static DEFINE_MUTEX(cx231xx_devlist_mutex);
|
||||
|
||||
struct cx231xx *cx231xx_get_device(int minor,
|
||||
enum v4l2_buf_type *fh_type, int *has_radio)
|
||||
{
|
||||
struct cx231xx *h, *dev = NULL;
|
||||
|
||||
*fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
*has_radio = 0;
|
||||
|
||||
mutex_lock(&cx231xx_devlist_mutex);
|
||||
list_for_each_entry(h, &cx231xx_devlist, devlist) {
|
||||
if (h->vdev->minor == minor)
|
||||
dev = h;
|
||||
if (h->vbi_dev->minor == minor) {
|
||||
dev = h;
|
||||
*fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
}
|
||||
if (h->radio_dev && h->radio_dev->minor == minor) {
|
||||
dev = h;
|
||||
*has_radio = 1;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&cx231xx_devlist_mutex);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* cx231xx_realease_resources()
|
||||
* unregisters the v4l2,i2c and usb devices
|
||||
|
|
|
@ -197,8 +197,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
|
|||
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
|
||||
strlcat(ir->phys, "/input0", sizeof(ir->phys));
|
||||
|
||||
err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
|
||||
dev->board.ir_codes);
|
||||
err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
|
||||
if (err < 0)
|
||||
goto err_out_free;
|
||||
|
||||
|
@ -217,7 +216,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
|
|||
cx231xx_ir_start(ir);
|
||||
|
||||
/* all done */
|
||||
err = input_register_device(ir->input);
|
||||
err = ir_input_register(ir->input, dev->board.ir_codes);
|
||||
if (err)
|
||||
goto err_out_stop;
|
||||
|
||||
|
@ -226,8 +225,6 @@ err_out_stop:
|
|||
cx231xx_ir_stop(ir);
|
||||
dev->ir = NULL;
|
||||
err_out_free:
|
||||
ir_input_free(input_dev);
|
||||
input_free_device(input_dev);
|
||||
kfree(ir);
|
||||
return err;
|
||||
}
|
||||
|
@ -241,8 +238,7 @@ int cx231xx_ir_fini(struct cx231xx *dev)
|
|||
return 0;
|
||||
|
||||
cx231xx_ir_stop(ir);
|
||||
ir_input_free(ir->input);
|
||||
input_unregister_device(ir->input);
|
||||
ir_input_unregister(ir->input);
|
||||
kfree(ir);
|
||||
|
||||
/* done */
|
||||
|
|
|
@ -1916,20 +1916,29 @@ static int radio_queryctrl(struct file *file, void *priv,
|
|||
*/
|
||||
static int cx231xx_v4l2_open(struct file *filp)
|
||||
{
|
||||
int minor = video_devdata(filp)->minor;
|
||||
int errCode = 0, radio = 0;
|
||||
struct cx231xx *dev = NULL;
|
||||
struct video_device *vdev = video_devdata(filp);
|
||||
struct cx231xx *dev = video_drvdata(filp);
|
||||
struct cx231xx_fh *fh;
|
||||
enum v4l2_buf_type fh_type = 0;
|
||||
|
||||
dev = cx231xx_get_device(minor, &fh_type, &radio);
|
||||
if (NULL == dev)
|
||||
return -ENODEV;
|
||||
switch (vdev->vfl_type) {
|
||||
case VFL_TYPE_GRABBER:
|
||||
fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
break;
|
||||
case VFL_TYPE_VBI:
|
||||
fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
break;
|
||||
case VFL_TYPE_RADIO:
|
||||
radio = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
|
||||
cx231xx_videodbg("open minor=%d type=%s users=%d\n",
|
||||
minor, v4l2_type_names[fh_type], dev->users);
|
||||
cx231xx_videodbg("open dev=%s type=%s users=%d\n",
|
||||
video_device_node_name(vdev), v4l2_type_names[fh_type],
|
||||
dev->users);
|
||||
|
||||
#if 0
|
||||
errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
|
||||
|
@ -2020,25 +2029,25 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)
|
|||
/*FIXME: I2C IR should be disconnected */
|
||||
|
||||
if (dev->radio_dev) {
|
||||
if (-1 != dev->radio_dev->minor)
|
||||
if (video_is_registered(dev->radio_dev))
|
||||
video_unregister_device(dev->radio_dev);
|
||||
else
|
||||
video_device_release(dev->radio_dev);
|
||||
dev->radio_dev = NULL;
|
||||
}
|
||||
if (dev->vbi_dev) {
|
||||
cx231xx_info("V4L2 device /dev/vbi%d deregistered\n",
|
||||
dev->vbi_dev->num);
|
||||
if (-1 != dev->vbi_dev->minor)
|
||||
cx231xx_info("V4L2 device %s deregistered\n",
|
||||
video_device_node_name(dev->vbi_dev));
|
||||
if (video_is_registered(dev->vbi_dev))
|
||||
video_unregister_device(dev->vbi_dev);
|
||||
else
|
||||
video_device_release(dev->vbi_dev);
|
||||
dev->vbi_dev = NULL;
|
||||
}
|
||||
if (dev->vdev) {
|
||||
cx231xx_info("V4L2 device /dev/video%d deregistered\n",
|
||||
dev->vdev->num);
|
||||
if (-1 != dev->vdev->minor)
|
||||
cx231xx_info("V4L2 device %s deregistered\n",
|
||||
video_device_node_name(dev->vdev));
|
||||
if (video_is_registered(dev->vdev))
|
||||
video_unregister_device(dev->vdev);
|
||||
else
|
||||
video_device_release(dev->vdev);
|
||||
|
@ -2268,7 +2277,6 @@ static const struct video_device cx231xx_video_template = {
|
|||
.fops = &cx231xx_v4l_fops,
|
||||
.release = video_device_release,
|
||||
.ioctl_ops = &video_ioctl_ops,
|
||||
.minor = -1,
|
||||
.tvnorms = V4L2_STD_ALL,
|
||||
.current_norm = V4L2_STD_PAL,
|
||||
};
|
||||
|
@ -2303,7 +2311,6 @@ static struct video_device cx231xx_radio_template = {
|
|||
.name = "cx231xx-radio",
|
||||
.fops = &radio_fops,
|
||||
.ioctl_ops = &radio_ioctl_ops,
|
||||
.minor = -1,
|
||||
};
|
||||
|
||||
/******************************** usb interface ******************************/
|
||||
|
@ -2319,13 +2326,13 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
|
|||
return NULL;
|
||||
|
||||
*vfd = *template;
|
||||
vfd->minor = -1;
|
||||
vfd->v4l2_dev = &dev->v4l2_dev;
|
||||
vfd->release = video_device_release;
|
||||
vfd->debug = video_debug;
|
||||
|
||||
snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
|
||||
|
||||
video_set_drvdata(vfd, dev);
|
||||
return vfd;
|
||||
}
|
||||
|
||||
|
@ -2374,8 +2381,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
cx231xx_info("%s/0: registered device video%d [v4l2]\n",
|
||||
dev->name, dev->vdev->num);
|
||||
cx231xx_info("%s/0: registered device %s [v4l2]\n",
|
||||
dev->name, video_device_node_name(dev->vdev));
|
||||
|
||||
/* Initialize VBI template */
|
||||
memcpy(&cx231xx_vbi_template, &cx231xx_video_template,
|
||||
|
@ -2393,8 +2400,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
cx231xx_info("%s/0: registered device vbi%d\n",
|
||||
dev->name, dev->vbi_dev->num);
|
||||
cx231xx_info("%s/0: registered device %s\n",
|
||||
dev->name, video_device_node_name(dev->vbi_dev));
|
||||
|
||||
if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) {
|
||||
dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template,
|
||||
|
@ -2409,12 +2416,13 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
|
|||
cx231xx_errdev("can't register radio device\n");
|
||||
return ret;
|
||||
}
|
||||
cx231xx_info("Registered radio device as /dev/radio%d\n",
|
||||
dev->radio_dev->num);
|
||||
cx231xx_info("Registered radio device as %s\n",
|
||||
video_device_node_name(dev->radio_dev));
|
||||
}
|
||||
|
||||
cx231xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
|
||||
dev->vdev->num, dev->vbi_dev->num);
|
||||
cx231xx_info("V4L2 device registered as %s and %s\n",
|
||||
video_device_node_name(dev->vdev),
|
||||
video_device_node_name(dev->vbi_dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -689,8 +689,6 @@ void cx231xx_release_analog_resources(struct cx231xx *dev);
|
|||
int cx231xx_register_analog_devices(struct cx231xx *dev);
|
||||
void cx231xx_remove_from_devlist(struct cx231xx *dev);
|
||||
void cx231xx_add_into_devlist(struct cx231xx *dev);
|
||||
struct cx231xx *cx231xx_get_device(int minor,
|
||||
enum v4l2_buf_type *fh_type, int *has_radio);
|
||||
void cx231xx_init_extension(struct cx231xx *dev);
|
||||
void cx231xx_close_extension(struct cx231xx *dev);
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#define NETUP_CI_CTL 0x04
|
||||
#define NETUP_CI_RD 1
|
||||
|
||||
#define NETUP_IRQ_DETAM 0x1
|
||||
#define NETUP_IRQ_IRQAM 0x4
|
||||
|
||||
static unsigned int ci_dbg;
|
||||
module_param(ci_dbg, int, 0644);
|
||||
|
@ -73,6 +75,9 @@ struct netup_ci_state {
|
|||
int status;
|
||||
struct work_struct work;
|
||||
void *priv;
|
||||
u8 current_irq_mode;
|
||||
int current_ci_flag;
|
||||
unsigned long next_status_checked_time;
|
||||
};
|
||||
|
||||
|
||||
|
@ -169,24 +174,26 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
|
|||
if (0 != slot)
|
||||
return -EINVAL;
|
||||
|
||||
ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &store, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (state->current_ci_flag != flag) {
|
||||
ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &store, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
store &= ~0x0c;
|
||||
store |= flag;
|
||||
store &= ~0x0c;
|
||||
store |= flag;
|
||||
|
||||
ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &store, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &store, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
};
|
||||
state->current_ci_flag = flag;
|
||||
|
||||
mutex_lock(&dev->gpio_lock);
|
||||
|
||||
/* write addr */
|
||||
cx_write(MC417_OEN, NETUP_EN_ALL);
|
||||
msleep(2);
|
||||
cx_write(MC417_RWD, NETUP_CTRL_OFF |
|
||||
NETUP_ADLO | (0xff & addr));
|
||||
cx_clear(MC417_RWD, NETUP_ADLO);
|
||||
|
@ -196,7 +203,6 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
|
|||
|
||||
if (read) { /* data in */
|
||||
cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
|
||||
msleep(2);
|
||||
} else /* data out */
|
||||
cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
|
||||
|
||||
|
@ -213,8 +219,8 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
|
|||
if (mem < 0)
|
||||
return -EREMOTEIO;
|
||||
|
||||
ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
|
||||
(read) ? "read" : "write", addr,
|
||||
ci_dbg_print("%s: %s: chipaddr=[0x%x] addr=[0x%02x], %s=%x\n", __func__,
|
||||
(read) ? "read" : "write", state->ci_i2c_addr, addr,
|
||||
(flag == NETUP_CI_CTL) ? "ctl" : "mem",
|
||||
(read) ? mem : data);
|
||||
|
||||
|
@ -283,14 +289,39 @@ int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode)
|
||||
{
|
||||
struct netup_ci_state *state = en50221->data;
|
||||
int ret;
|
||||
|
||||
if (irq_mode == state->current_irq_mode)
|
||||
return 0;
|
||||
|
||||
ci_dbg_print("%s: chipaddr=[0x%x] setting ci IRQ to [0x%x] \n",
|
||||
__func__, state->ci_i2c_addr, irq_mode);
|
||||
ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0x1b, &irq_mode, 1);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
state->current_irq_mode = irq_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
|
||||
{
|
||||
struct netup_ci_state *state = en50221->data;
|
||||
u8 buf = 0x60;
|
||||
u8 buf;
|
||||
|
||||
if (0 != slot)
|
||||
return -EINVAL;
|
||||
|
||||
netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &buf, 1);
|
||||
buf |= 0x60;
|
||||
|
||||
return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &buf, 1);
|
||||
}
|
||||
|
@ -303,21 +334,35 @@ static void netup_read_ci_status(struct work_struct *work)
|
|||
u8 buf[33];
|
||||
int ret;
|
||||
|
||||
ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &buf[0], 33);
|
||||
/* CAM module IRQ processing. fast operation */
|
||||
dvb_ca_en50221_frda_irq(&state->ca, 0);
|
||||
|
||||
if (ret != 0)
|
||||
return;
|
||||
/* CAM module INSERT/REMOVE processing. slow operation because of i2c
|
||||
* transfers */
|
||||
if (time_after(jiffies, state->next_status_checked_time)
|
||||
|| !state->status) {
|
||||
ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &buf[0], 33);
|
||||
|
||||
ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, "
|
||||
"TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0],
|
||||
buf[32]);
|
||||
state->next_status_checked_time = jiffies
|
||||
+ msecs_to_jiffies(1000);
|
||||
|
||||
if (buf[0] & 1)
|
||||
state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
|
||||
DVB_CA_EN50221_POLL_CAM_READY;
|
||||
else
|
||||
state->status = 0;
|
||||
if (ret != 0)
|
||||
return;
|
||||
|
||||
ci_dbg_print("%s: Slot Status Addr=[0x%04x], "
|
||||
"Reg=[0x%02x], data=%02x, "
|
||||
"TS config = %02x\n", __func__,
|
||||
state->ci_i2c_addr, 0, buf[0],
|
||||
buf[0]);
|
||||
|
||||
|
||||
if (buf[0] & 1)
|
||||
state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
|
||||
DVB_CA_EN50221_POLL_CAM_READY;
|
||||
else
|
||||
state->status = 0;
|
||||
};
|
||||
}
|
||||
|
||||
/* CI irq handler */
|
||||
|
@ -347,6 +392,9 @@ int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open
|
|||
if (0 != slot)
|
||||
return -EINVAL;
|
||||
|
||||
netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | NETUP_IRQ_IRQAM)
|
||||
: NETUP_IRQ_DETAM);
|
||||
|
||||
return state->status;
|
||||
}
|
||||
|
||||
|
@ -381,8 +429,8 @@ int netup_ci_init(struct cx23885_tsport *port)
|
|||
0x01, /* power on (use it like store place) */
|
||||
0x00, /* RFU */
|
||||
0x00, /* int status read only */
|
||||
0x01, /* all int unmasked */
|
||||
0x04, /* int config */
|
||||
NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */
|
||||
0x05, /* EXTINT=active-high, INT=push-pull */
|
||||
0x00, /* USCG1 */
|
||||
0x04, /* ack active low */
|
||||
0x00, /* LOCK = 0 */
|
||||
|
@ -422,6 +470,7 @@ int netup_ci_init(struct cx23885_tsport *port)
|
|||
state->ca.poll_slot_status = netup_poll_ci_slot_status;
|
||||
state->ca.data = state;
|
||||
state->priv = port;
|
||||
state->current_irq_mode = NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM;
|
||||
|
||||
ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
|
||||
0, &cimax_init[0], 34);
|
||||
|
|
|
@ -1568,28 +1568,11 @@ static int vidioc_queryctrl(struct file *file, void *priv,
|
|||
|
||||
static int mpeg_open(struct file *file)
|
||||
{
|
||||
int minor = video_devdata(file)->minor;
|
||||
struct cx23885_dev *h, *dev = NULL;
|
||||
struct list_head *list;
|
||||
struct cx23885_dev *dev = video_drvdata(file);
|
||||
struct cx23885_fh *fh;
|
||||
|
||||
dprintk(2, "%s()\n", __func__);
|
||||
|
||||
lock_kernel();
|
||||
list_for_each(list, &cx23885_devlist) {
|
||||
h = list_entry(list, struct cx23885_dev, devlist);
|
||||
if (h->v4l_device &&
|
||||
h->v4l_device->minor == minor) {
|
||||
dev = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev == NULL) {
|
||||
unlock_kernel();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* allocate + initialize per filehandle data */
|
||||
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
|
||||
if (NULL == fh) {
|
||||
|
@ -1597,6 +1580,8 @@ static int mpeg_open(struct file *file)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
lock_kernel();
|
||||
|
||||
file->private_data = fh;
|
||||
fh->dev = dev;
|
||||
|
||||
|
@ -1736,7 +1721,6 @@ static struct video_device cx23885_mpeg_template = {
|
|||
.name = "cx23885",
|
||||
.fops = &mpeg_fops,
|
||||
.ioctl_ops = &mpeg_ioctl_ops,
|
||||
.minor = -1,
|
||||
.tvnorms = CX23885_NORMS,
|
||||
.current_norm = V4L2_STD_NTSC_M,
|
||||
};
|
||||
|
@ -1746,7 +1730,7 @@ void cx23885_417_unregister(struct cx23885_dev *dev)
|
|||
dprintk(1, "%s()\n", __func__);
|
||||
|
||||
if (dev->v4l_device) {
|
||||
if (-1 != dev->v4l_device->minor)
|
||||
if (video_is_registered(dev->v4l_device))
|
||||
video_unregister_device(dev->v4l_device);
|
||||
else
|
||||
video_device_release(dev->v4l_device);
|
||||
|
@ -1803,6 +1787,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
|
|||
/* Allocate and initialize V4L video device */
|
||||
dev->v4l_device = cx23885_video_dev_alloc(tsport,
|
||||
dev->pci, &cx23885_mpeg_template, "mpeg");
|
||||
video_set_drvdata(dev->v4l_device, dev);
|
||||
err = video_register_device(dev->v4l_device,
|
||||
VFL_TYPE_GRABBER, -1);
|
||||
if (err < 0) {
|
||||
|
@ -1810,8 +1795,8 @@ int cx23885_417_register(struct cx23885_dev *dev)
|
|||
return err;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
|
||||
dev->name, dev->v4l_device->num);
|
||||
printk(KERN_INFO "%s: registered device %s [mpeg]\n",
|
||||
dev->name, video_device_node_name(dev->v4l_device));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue