Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: "The main set of series of patches for media subsystem, including: - document RC sysfs class - added an API to setup scancode to allow waking up systems using the Remote Controller - add API for SDR devices. Drivers are still on staging - some API improvements for getting EDID data from media inputs/outputs - new DVB frontend driver for drx-j (ATSC) - one driver (it913x/it9137) got removed, in favor of an improvement on another driver (af9035) - added a skeleton V4L2 PCI driver at documentation - added a dual flash driver (lm3646) - added a new IR driver (img-ir) - added an IR scancode decoder for the Sharp protocol - some improvements at the usbtv driver, to allow its core to be reused. - added a new SDR driver (rtl2832u_sdr) - added a new tuner driver (msi001) - several improvements at em28xx driver to fix PM support, device removal and to split the V4L2 specific bits into a separate sub-driver - one driver got converted to videobuf2 (s2255drv) - the e4000 tuner driver now follows an improved binding model - some fixes at V4L2 compat32 code - several fixes and enhancements at videobuf2 code - some cleanups at V4L2 API documentation - usual driver enhancements, new board additions and misc fixups" [ NOTE! This merge effective drops commit4329b93b28
("of: Reduce indentation in of_graph_get_next_endpoint"). The of_graph_get_next_endpoint() function was moved and renamed by commitfd9fdb78a9
("[media] of: move graph helpers from drivers/media/v4l2-core to drivers/of"). It was originally called v4l2_of_get_next_endpoint() and lived in the file drivers/media/v4l2-core/v4l2-of.c. In that original location, it was then fixed to support empty port nodes by commitb9db140c1e
("[media] v4l: of: Support empty port nodes"), and that commit clashes badly with the dropped "Reduce intendation" commit. I had to choose one or the other, and decided that the "Support empty port nodes" commit was more important ] * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (426 commits) [media] em28xx-dvb: fix PCTV 461e tuner I2C binding Revert "[media] em28xx-dvb: fix PCTV 461e tuner I2C binding" [media] em28xx: fix PCTV 290e LNA oops [media] em28xx-dvb: fix PCTV 461e tuner I2C binding [media] m88ds3103: fix bug on .set_tone() [media] saa7134: fix WARN_ON during resume [media] v4l2-dv-timings: add module name, description, license [media] videodev2.h: add parenthesis around macro arguments [media] saa6752hs: depends on CRC32 [media] si4713: fix Kconfig dependencies [media] Sensoray 2255 uses videobuf2 [media] adv7180: free an interrupt on failure paths in init_device() [media] e4000: make VIDEO_V4L2 dependency optional [media] af9033: Don't export functions for the hardware filter [media] af9035: use af9033 PID filters [media] af9033: implement PID filter [media] rtl2832_sdr: do not use dynamic stack allocation [media] e4000: fix 32-bit build error [media] em28xx-audio: make sure audio is unmuted on open() [media] DocBook media: v4l2_format_sdr was renamed to v4l2_sdr_format ...
This commit is contained in:
commit
3c83e61e67
7
CREDITS
7
CREDITS
@ -630,6 +630,13 @@ N: Michael Elizabeth Chastain
|
||||
E: mec@shout.net
|
||||
D: Configure, Menuconfig, xconfig
|
||||
|
||||
N: Mauro Carvalho Chehab
|
||||
E: m.chehab@samsung.org
|
||||
E: mchehab@infradead.org
|
||||
D: Media subsystem (V4L/DVB) drivers and core
|
||||
D: EDAC drivers and EDAC 3.0 core rework
|
||||
S: Brazil
|
||||
|
||||
N: Raymond Chen
|
||||
E: raymondc@microsoft.com
|
||||
D: Author of Configure script
|
||||
|
111
Documentation/ABI/testing/sysfs-class-rc
Normal file
111
Documentation/ABI/testing/sysfs-class-rc
Normal file
@ -0,0 +1,111 @@
|
||||
What: /sys/class/rc/
|
||||
Date: Apr 2010
|
||||
KernelVersion: 2.6.35
|
||||
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
Description:
|
||||
The rc/ class sub-directory belongs to the Remote Controller
|
||||
core and provides a sysfs interface for configuring infrared
|
||||
remote controller receivers.
|
||||
|
||||
What: /sys/class/rc/rcN/
|
||||
Date: Apr 2010
|
||||
KernelVersion: 2.6.35
|
||||
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
Description:
|
||||
A /sys/class/rc/rcN directory is created for each remote
|
||||
control receiver device where N is the number of the receiver.
|
||||
|
||||
What: /sys/class/rc/rcN/protocols
|
||||
Date: Jun 2010
|
||||
KernelVersion: 2.6.36
|
||||
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
Description:
|
||||
Reading this file returns a list of available protocols,
|
||||
something like:
|
||||
"rc5 [rc6] nec jvc [sony]"
|
||||
Enabled protocols are shown in [] brackets.
|
||||
Writing "+proto" will add a protocol to the list of enabled
|
||||
protocols.
|
||||
Writing "-proto" will remove a protocol from the list of enabled
|
||||
protocols.
|
||||
Writing "proto" will enable only "proto".
|
||||
Writing "none" will disable all protocols.
|
||||
Write fails with EINVAL if an invalid protocol combination or
|
||||
unknown protocol name is used.
|
||||
|
||||
What: /sys/class/rc/rcN/filter
|
||||
Date: Jan 2014
|
||||
KernelVersion: 3.15
|
||||
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
Description:
|
||||
Sets the scancode filter expected value.
|
||||
Use in combination with /sys/class/rc/rcN/filter_mask to set the
|
||||
expected value of the bits set in the filter mask.
|
||||
If the hardware supports it then scancodes which do not match
|
||||
the filter will be ignored. Otherwise the write will fail with
|
||||
an error.
|
||||
This value may be reset to 0 if the current protocol is altered.
|
||||
|
||||
What: /sys/class/rc/rcN/filter_mask
|
||||
Date: Jan 2014
|
||||
KernelVersion: 3.15
|
||||
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
Description:
|
||||
Sets the scancode filter mask of bits to compare.
|
||||
Use in combination with /sys/class/rc/rcN/filter to set the bits
|
||||
of the scancode which should be compared against the expected
|
||||
value. A value of 0 disables the filter to allow all valid
|
||||
scancodes to be processed.
|
||||
If the hardware supports it then scancodes which do not match
|
||||
the filter will be ignored. Otherwise the write will fail with
|
||||
an error.
|
||||
This value may be reset to 0 if the current protocol is altered.
|
||||
|
||||
What: /sys/class/rc/rcN/wakeup_protocols
|
||||
Date: Feb 2014
|
||||
KernelVersion: 3.15
|
||||
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
Description:
|
||||
Reading this file returns a list of available protocols to use
|
||||
for the wakeup filter, something like:
|
||||
"rc5 rc6 nec jvc [sony]"
|
||||
The enabled wakeup protocol is shown in [] brackets.
|
||||
Writing "+proto" will add a protocol to the list of enabled
|
||||
wakeup protocols.
|
||||
Writing "-proto" will remove a protocol from the list of enabled
|
||||
wakeup protocols.
|
||||
Writing "proto" will use "proto" for wakeup events.
|
||||
Writing "none" will disable wakeup.
|
||||
Write fails with EINVAL if an invalid protocol combination or
|
||||
unknown protocol name is used, or if wakeup is not supported by
|
||||
the hardware.
|
||||
|
||||
What: /sys/class/rc/rcN/wakeup_filter
|
||||
Date: Jan 2014
|
||||
KernelVersion: 3.15
|
||||
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
Description:
|
||||
Sets the scancode wakeup filter expected value.
|
||||
Use in combination with /sys/class/rc/rcN/wakeup_filter_mask to
|
||||
set the expected value of the bits set in the wakeup filter mask
|
||||
to trigger a system wake event.
|
||||
If the hardware supports it and wakeup_filter_mask is not 0 then
|
||||
scancodes which match the filter will wake the system from e.g.
|
||||
suspend to RAM or power off.
|
||||
Otherwise the write will fail with an error.
|
||||
This value may be reset to 0 if the wakeup protocol is altered.
|
||||
|
||||
What: /sys/class/rc/rcN/wakeup_filter_mask
|
||||
Date: Jan 2014
|
||||
KernelVersion: 3.15
|
||||
Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
Description:
|
||||
Sets the scancode wakeup filter mask of bits to compare.
|
||||
Use in combination with /sys/class/rc/rcN/wakeup_filter to set
|
||||
the bits of the scancode which should be compared against the
|
||||
expected value to trigger a system wake event.
|
||||
If the hardware supports it and wakeup_filter_mask is not 0 then
|
||||
scancodes which match the filter will wake the system from e.g.
|
||||
suspend to RAM or power off.
|
||||
Otherwise the write will fail with an error.
|
||||
This value may be reset to 0 if the wakeup protocol is altered.
|
@ -1042,7 +1042,14 @@ role="subsection"><title>DMX_ADD_PID</title>
|
||||
</para>
|
||||
<informaltable><tgroup cols="1"><tbody><row><entry
|
||||
align="char">
|
||||
<para>This ioctl is undocumented. Documentation is welcome.</para>
|
||||
<para>This ioctl call allows to add multiple PIDs to a transport stream filter
|
||||
previously set up with DMX_SET_PES_FILTER and output equal to DMX_OUT_TSDEMUX_TAP.
|
||||
</para></entry></row><row><entry align="char"><para>
|
||||
It is used by readers of /dev/dvb/adapterX/demuxY.
|
||||
</para></entry></row><row><entry align="char"><para>
|
||||
It may be called at any time, i.e. before or after the first filter on the
|
||||
shared file descriptor was started. It makes it possible to record multiple
|
||||
services without the need to de-multiplex or re-multiplex TS packets.</para>
|
||||
</entry>
|
||||
</row></tbody></tgroup></informaltable>
|
||||
<para>SYNOPSIS
|
||||
@ -1075,7 +1082,7 @@ role="subsection"><title>DMX_ADD_PID</title>
|
||||
</para>
|
||||
</entry><entry
|
||||
align="char">
|
||||
<para>Undocumented.</para>
|
||||
<para>PID number to be filtered.</para>
|
||||
</entry>
|
||||
</row></tbody></tgroup></informaltable>
|
||||
&return-value-dvb;
|
||||
@ -1087,7 +1094,15 @@ role="subsection"><title>DMX_REMOVE_PID</title>
|
||||
</para>
|
||||
<informaltable><tgroup cols="1"><tbody><row><entry
|
||||
align="char">
|
||||
<para>This ioctl is undocumented. Documentation is welcome.</para>
|
||||
<para>This ioctl call allows to remove a PID when multiple PIDs are set on a
|
||||
transport stream filter, e. g. a filter previously set up with output equal to
|
||||
DMX_OUT_TSDEMUX_TAP, created via either DMX_SET_PES_FILTER or DMX_ADD_PID.
|
||||
</para></entry></row><row><entry align="char"><para>
|
||||
It is used by readers of /dev/dvb/adapterX/demuxY.
|
||||
</para></entry></row><row><entry align="char"><para>
|
||||
It may be called at any time, i.e. before or after the first filter on the
|
||||
shared file descriptor was started. It makes it possible to record multiple
|
||||
services without the need to de-multiplex or re-multiplex TS packets.</para>
|
||||
</entry>
|
||||
</row></tbody></tgroup></informaltable>
|
||||
<para>SYNOPSIS
|
||||
@ -1120,7 +1135,7 @@ role="subsection"><title>DMX_REMOVE_PID</title>
|
||||
</para>
|
||||
</entry><entry
|
||||
align="char">
|
||||
<para>Undocumented.</para>
|
||||
<para>PID of the PES filter to be removed.</para>
|
||||
</entry>
|
||||
</row></tbody></tgroup></informaltable>
|
||||
&return-value-dvb;
|
||||
|
@ -18,7 +18,7 @@
|
||||
<firstname>Mauro</firstname>
|
||||
<othername role="mi">Carvalho</othername>
|
||||
<surname>Chehab</surname>
|
||||
<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
|
||||
<affiliation><address><email>m.chehab@samsung.com</email></address></affiliation>
|
||||
<contrib>Ported document to Docbook XML.</contrib>
|
||||
</author>
|
||||
</authorgroup>
|
||||
@ -28,7 +28,7 @@
|
||||
<holder>Convergence GmbH</holder>
|
||||
</copyright>
|
||||
<copyright>
|
||||
<year>2009-2012</year>
|
||||
<year>2009-2014</year>
|
||||
<holder>Mauro Carvalho Chehab</holder>
|
||||
</copyright>
|
||||
|
||||
|
@ -744,7 +744,7 @@ typedef enum fe_hierarchy {
|
||||
</para>
|
||||
<informaltable><tgroup cols="1"><tbody><row><entry
|
||||
align="char">
|
||||
<para>int ioctl(int fd, int request = <link linkend="FE_READ_SNR">FE_READ_SNR</link>, int16_t
|
||||
<para>int ioctl(int fd, int request = <link linkend="FE_READ_SNR">FE_READ_SNR</link>, uint16_t
|
||||
⋆snr);</para>
|
||||
</entry>
|
||||
</row></tbody></tgroup></informaltable>
|
||||
@ -766,7 +766,7 @@ typedef enum fe_hierarchy {
|
||||
</entry>
|
||||
</row><row><entry
|
||||
align="char">
|
||||
<para>int16_t *snr</para>
|
||||
<para>uint16_t *snr</para>
|
||||
</entry><entry
|
||||
align="char">
|
||||
<para>The signal-to-noise ratio is stored into *snr.</para>
|
||||
@ -791,7 +791,7 @@ typedef enum fe_hierarchy {
|
||||
<informaltable><tgroup cols="1"><tbody><row><entry
|
||||
align="char">
|
||||
<para>int ioctl( int fd, int request =
|
||||
<link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>, int16_t ⋆strength);</para>
|
||||
<link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>, uint16_t ⋆strength);</para>
|
||||
</entry>
|
||||
</row></tbody></tgroup></informaltable>
|
||||
|
||||
@ -814,7 +814,7 @@ typedef enum fe_hierarchy {
|
||||
</entry>
|
||||
</row><row><entry
|
||||
align="char">
|
||||
<para>int16_t *strength</para>
|
||||
<para>uint16_t *strength</para>
|
||||
</entry><entry
|
||||
align="char">
|
||||
<para>The signal strength value is stored into *strength.</para>
|
||||
|
@ -38,70 +38,41 @@ the basic concepts applicable to all devices.</para>
|
||||
|
||||
<para>V4L2 drivers are implemented as kernel modules, loaded
|
||||
manually by the system administrator or automatically when a device is
|
||||
first opened. The driver modules plug into the "videodev" kernel
|
||||
first discovered. The driver modules plug into the "videodev" kernel
|
||||
module. It provides helper functions and a common application
|
||||
interface specified in this document.</para>
|
||||
|
||||
<para>Each driver thus loaded registers one or more device nodes
|
||||
with major number 81 and a minor number between 0 and 255. Assigning
|
||||
minor numbers to V4L2 devices is entirely up to the system administrator,
|
||||
this is primarily intended to solve conflicts between devices.<footnote>
|
||||
<para>Access permissions are associated with character
|
||||
device special files, hence we must ensure device numbers cannot
|
||||
change with the module load order. To this end minor numbers are no
|
||||
longer automatically assigned by the "videodev" module as in V4L but
|
||||
requested by the driver. The defaults will suffice for most people
|
||||
unless two drivers compete for the same minor numbers.</para>
|
||||
</footnote> The module options to select minor numbers are named
|
||||
after the device special file with a "_nr" suffix. For example "video_nr"
|
||||
for <filename>/dev/video</filename> video capture devices. The number is
|
||||
an offset to the base minor number associated with the device type.
|
||||
<footnote>
|
||||
<para>In earlier versions of the V4L2 API the module options
|
||||
where named after the device special file with a "unit_" prefix, expressing
|
||||
the minor number itself, not an offset. Rationale for this change is unknown.
|
||||
Lastly the naming and semantics are just a convention among driver writers,
|
||||
the point to note is that minor numbers are not supposed to be hardcoded
|
||||
into drivers.</para>
|
||||
</footnote> When the driver supports multiple devices of the same
|
||||
type more than one minor number can be assigned, separated by commas:
|
||||
<informalexample>
|
||||
with major number 81 and a minor number between 0 and 255. Minor numbers
|
||||
are allocated dynamically unless the kernel is compiled with the kernel
|
||||
option CONFIG_VIDEO_FIXED_MINOR_RANGES. In that case minor numbers are
|
||||
allocated in ranges depending on the device node type (video, radio, etc.).</para>
|
||||
|
||||
<para>Many drivers support "video_nr", "radio_nr" or "vbi_nr"
|
||||
module options to select specific video/radio/vbi node numbers. This allows
|
||||
the user to request that the device node is named e.g. /dev/video5 instead
|
||||
of leaving it to chance. When the driver supports multiple devices of the same
|
||||
type more than one device node number can be assigned, separated by commas:
|
||||
<informalexample>
|
||||
<screen>
|
||||
> insmod mydriver.o video_nr=0,1 radio_nr=0,1</screen>
|
||||
> modprobe mydriver video_nr=0,1 radio_nr=0,1</screen>
|
||||
</informalexample></para>
|
||||
|
||||
<para>In <filename>/etc/modules.conf</filename> this may be
|
||||
written as: <informalexample>
|
||||
<screen>
|
||||
alias char-major-81-0 mydriver
|
||||
alias char-major-81-1 mydriver
|
||||
alias char-major-81-64 mydriver <co id="alias" />
|
||||
options mydriver video_nr=0,1 radio_nr=0,1 <co id="options" />
|
||||
options mydriver video_nr=0,1 radio_nr=0,1
|
||||
</screen>
|
||||
<calloutlist>
|
||||
<callout arearefs="alias">
|
||||
<para>When an application attempts to open a device
|
||||
special file with major number 81 and minor number 0, 1, or 64, load
|
||||
"mydriver" (and the "videodev" module it depends upon).</para>
|
||||
</callout>
|
||||
<callout arearefs="options">
|
||||
<para>Register the first two video capture devices with
|
||||
minor number 0 and 1 (base number is 0), the first two radio device
|
||||
with minor number 64 and 65 (base 64).</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</informalexample> When no minor number is given as module
|
||||
option the driver supplies a default. <xref linkend="devices" />
|
||||
recommends the base minor numbers to be used for the various device
|
||||
types. Obviously minor numbers must be unique. When the number is
|
||||
already in use the <emphasis>offending device</emphasis> will not be
|
||||
registered. <!-- Blessed by Linus Torvalds on
|
||||
linux-kernel@vger.kernel.org, 2002-11-20. --></para>
|
||||
</informalexample> When no device node number is given as module
|
||||
option the driver supplies a default.</para>
|
||||
|
||||
<para>By convention system administrators create various
|
||||
character device special files with these major and minor numbers in
|
||||
the <filename>/dev</filename> directory. The names recommended for the
|
||||
different V4L2 device types are listed in <xref linkend="devices" />.
|
||||
<para>Normally udev will create the device nodes in /dev automatically
|
||||
for you. If udev is not installed, then you need to enable the
|
||||
CONFIG_VIDEO_FIXED_MINOR_RANGES kernel option in order to be able to correctly
|
||||
relate a minor number to a device node number. I.e., you need to be certain
|
||||
that minor number 5 maps to device node name video5. With this kernel option
|
||||
different device types have different minor number ranges. These ranges are
|
||||
listed in <xref linkend="devices" />.
|
||||
</para>
|
||||
|
||||
<para>The creation of character special files (with
|
||||
@ -110,85 +81,66 @@ devices cannot be opened by major and minor number. That means
|
||||
applications cannot <emphasis>reliable</emphasis> scan for loaded or
|
||||
installed drivers. The user must enter a device name, or the
|
||||
application can try the conventional device names.</para>
|
||||
|
||||
<para>Under the device filesystem (devfs) the minor number
|
||||
options are ignored. V4L2 drivers (or by proxy the "videodev" module)
|
||||
automatically create the required device files in the
|
||||
<filename>/dev/v4l</filename> directory using the conventional device
|
||||
names above.</para>
|
||||
</section>
|
||||
|
||||
<section id="related">
|
||||
<title>Related Devices</title>
|
||||
|
||||
<para>Devices can support several related functions. For example
|
||||
video capturing, video overlay and VBI capturing are related because
|
||||
these functions share, amongst other, the same video input and tuner
|
||||
frequency. V4L and earlier versions of V4L2 used the same device name
|
||||
and minor number for video capturing and overlay, but different ones
|
||||
for VBI. Experience showed this approach has several problems<footnote>
|
||||
<para>Given a device file name one cannot reliable find
|
||||
related devices. For once names are arbitrary and in a system with
|
||||
multiple devices, where only some support VBI capturing, a
|
||||
<filename>/dev/video2</filename> is not necessarily related to
|
||||
<filename>/dev/vbi2</filename>. The V4L
|
||||
<constant>VIDIOCGUNIT</constant> ioctl would require a search for a
|
||||
device file with a particular major and minor number.</para>
|
||||
</footnote>, and to make things worse the V4L videodev module
|
||||
used to prohibit multiple opens of a device.</para>
|
||||
<para>Devices can support several functions. For example
|
||||
video capturing, VBI capturing and radio support.</para>
|
||||
|
||||
<para>As a remedy the present version of the V4L2 API relaxed the
|
||||
concept of device types with specific names and minor numbers. For
|
||||
compatibility with old applications drivers must still register different
|
||||
minor numbers to assign a default function to the device. But if related
|
||||
functions are supported by the driver they must be available under all
|
||||
registered minor numbers. The desired function can be selected after
|
||||
opening the device as described in <xref linkend="devices" />.</para>
|
||||
<para>The V4L2 API creates different nodes for each of these functions.</para>
|
||||
|
||||
<para>Imagine a driver supporting video capturing, video
|
||||
overlay, raw VBI capturing, and FM radio reception. It registers three
|
||||
devices with minor number 0, 64 and 224 (this numbering scheme is
|
||||
inherited from the V4L API). Regardless if
|
||||
<filename>/dev/video</filename> (81, 0) or
|
||||
<filename>/dev/vbi</filename> (81, 224) is opened the application can
|
||||
select any one of the video capturing, overlay or VBI capturing
|
||||
functions. Without programming (e. g. reading from the device
|
||||
with <application>dd</application> or <application>cat</application>)
|
||||
<filename>/dev/video</filename> captures video images, while
|
||||
<filename>/dev/vbi</filename> captures raw VBI data.
|
||||
<filename>/dev/radio</filename> (81, 64) is invariable a radio device,
|
||||
unrelated to the video functions. Being unrelated does not imply the
|
||||
devices can be used at the same time, however. The &func-open;
|
||||
function may very well return an &EBUSY;.</para>
|
||||
<para>The V4L2 API was designed with the idea that one device node could support
|
||||
all functions. However, in practice this never worked: this 'feature'
|
||||
was never used by applications and many drivers did not support it and if
|
||||
they did it was certainly never tested. In addition, switching a device
|
||||
node between different functions only works when using the streaming I/O
|
||||
API, not with the read()/write() API.</para>
|
||||
|
||||
<para>Today each device node supports just one function.</para>
|
||||
|
||||
<para>Besides video input or output the hardware may also
|
||||
support audio sampling or playback. If so, these functions are
|
||||
implemented as OSS or ALSA PCM devices and eventually OSS or ALSA
|
||||
audio mixer. The V4L2 API makes no provisions yet to find these
|
||||
related devices. If you have an idea please write to the linux-media
|
||||
mailing list: &v4l-ml;.</para>
|
||||
implemented as ALSA PCM devices with optional ALSA audio mixer
|
||||
devices.</para>
|
||||
|
||||
<para>One problem with all these devices is that the V4L2 API
|
||||
makes no provisions to find these related devices. Some really
|
||||
complex devices use the Media Controller (see <xref linkend="media_controller" />)
|
||||
which can be used for this purpose. But most drivers do not use it,
|
||||
and while some code exists that uses sysfs to discover related devices
|
||||
(see libmedia_dev in the <ulink url="http://git.linuxtv.org/v4l-utils/">v4l-utils</ulink>
|
||||
git repository), there is no library yet that can provide a single API towards
|
||||
both Media Controller-based devices and devices that do not use the Media Controller.
|
||||
If you want to work on this please write to the linux-media mailing list: &v4l-ml;.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Multiple Opens</title>
|
||||
|
||||
<para>In general, V4L2 devices can be opened more than once.
|
||||
<para>V4L2 devices can be opened more than once.<footnote><para>
|
||||
There are still some old and obscure drivers that have not been updated to
|
||||
allow for multiple opens. This implies that for such drivers &func-open; can
|
||||
return an &EBUSY; when the device is already in use.</para></footnote>
|
||||
When this is supported by the driver, users can for example start a
|
||||
"panel" application to change controls like brightness or audio
|
||||
volume, while another application captures video and audio. In other words, panel
|
||||
applications are comparable to an OSS or ALSA audio mixer application.
|
||||
When a device supports multiple functions like capturing and overlay
|
||||
<emphasis>simultaneously</emphasis>, multiple opens allow concurrent
|
||||
use of the device by forked processes or specialized applications.</para>
|
||||
applications are comparable to an ALSA audio mixer application.
|
||||
Just opening a V4L2 device should not change the state of the device.<footnote>
|
||||
<para>Unfortunately, opening a radio device often switches the state of the
|
||||
device to radio mode in many drivers. This behavior should be fixed eventually
|
||||
as it violates the V4L2 specification.</para></footnote></para>
|
||||
|
||||
<para>Multiple opens are optional, although drivers should
|
||||
permit at least concurrent accesses without data exchange, &ie; panel
|
||||
applications. This implies &func-open; can return an &EBUSY; when the
|
||||
device is already in use, as well as &func-ioctl; functions initiating
|
||||
data exchange (namely the &VIDIOC-S-FMT; ioctl), and the &func-read;
|
||||
and &func-write; functions.</para>
|
||||
<para>Once an application has allocated the memory buffers needed for
|
||||
streaming data (by calling the &VIDIOC-REQBUFS; or &VIDIOC-CREATE-BUFS; ioctls,
|
||||
or implicitly by calling the &func-read; or &func-write; functions) that
|
||||
application (filehandle) becomes the owner of the device. It is no longer
|
||||
allowed to make changes that would affect the buffer sizes (e.g. by calling
|
||||
the &VIDIOC-S-FMT; ioctl) and other applications are no longer allowed to allocate
|
||||
buffers or start or stop streaming. The &EBUSY; will be returned instead.</para>
|
||||
|
||||
<para>Mere opening a V4L2 device does not grant exclusive
|
||||
<para>Merely opening a V4L2 device does not grant exclusive
|
||||
access.<footnote>
|
||||
<para>Drivers could recognize the
|
||||
<constant>O_EXCL</constant> open flag. Presently this is not required,
|
||||
@ -206,12 +158,7 @@ additional access privileges using the priority mechanism described in
|
||||
<para>V4L2 drivers should not support multiple applications
|
||||
reading or writing the same data stream on a device by copying
|
||||
buffers, time multiplexing or similar means. This is better handled by
|
||||
a proxy application in user space. When the driver supports stream
|
||||
sharing anyway it must be implemented transparently. The V4L2 API does
|
||||
not specify how conflicts are solved. <!-- For example O_EXCL when the
|
||||
application does not want to be preempted, PROT_READ mmapped buffers
|
||||
which can be mapped twice, what happens when image formats do not
|
||||
match etc.--></para>
|
||||
a proxy application in user space.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@ -240,15 +187,15 @@ methods</link> supported by the device.</para>
|
||||
|
||||
<para>Starting with kernel version 3.1, VIDIOC-QUERYCAP will return the
|
||||
V4L2 API version used by the driver, with generally matches the Kernel version.
|
||||
There's no need of using &VIDIOC-QUERYCAP; to check if an specific ioctl is
|
||||
supported, the V4L2 core now returns ENOIOCTLCMD if a driver doesn't provide
|
||||
There's no need of using &VIDIOC-QUERYCAP; to check if a specific ioctl is
|
||||
supported, the V4L2 core now returns ENOTTY if a driver doesn't provide
|
||||
support for an ioctl.</para>
|
||||
|
||||
<para>Other features can be queried
|
||||
by calling the respective ioctl, for example &VIDIOC-ENUMINPUT;
|
||||
to learn about the number, types and names of video connectors on the
|
||||
device. Although abstraction is a major objective of this API, the
|
||||
ioctl also allows driver specific applications to reliable identify
|
||||
&VIDIOC-QUERYCAP; ioctl also allows driver specific applications to reliably identify
|
||||
the driver.</para>
|
||||
|
||||
<para>All V4L2 drivers must support
|
||||
@ -278,9 +225,7 @@ Applications requiring a different priority will usually call
|
||||
the &VIDIOC-QUERYCAP; ioctl.</para>
|
||||
|
||||
<para>Ioctls changing driver properties, such as &VIDIOC-S-INPUT;,
|
||||
return an &EBUSY; after another application obtained higher priority.
|
||||
An event mechanism to notify applications about asynchronous property
|
||||
changes has been proposed but not added yet.</para>
|
||||
return an &EBUSY; after another application obtained higher priority.</para>
|
||||
</section>
|
||||
|
||||
<section id="video">
|
||||
@ -288,9 +233,9 @@ changes has been proposed but not added yet.</para>
|
||||
|
||||
<para>Video inputs and outputs are physical connectors of a
|
||||
device. These can be for example RF connectors (antenna/cable), CVBS
|
||||
a.k.a. Composite Video, S-Video or RGB connectors. Only video and VBI
|
||||
capture devices have inputs, output devices have outputs, at least one
|
||||
each. Radio devices have no video inputs or outputs.</para>
|
||||
a.k.a. Composite Video, S-Video or RGB connectors. Video and VBI
|
||||
capture devices have inputs. Video and VBI output devices have outputs,
|
||||
at least one each. Radio devices have no video inputs or outputs.</para>
|
||||
|
||||
<para>To learn about the number and attributes of the
|
||||
available inputs and outputs applications can enumerate them with the
|
||||
@ -299,30 +244,13 @@ available inputs and outputs applications can enumerate them with the
|
||||
ioctl also contains signal status information applicable when the
|
||||
current video input is queried.</para>
|
||||
|
||||
<para>The &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; ioctl return the
|
||||
<para>The &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; ioctls return the
|
||||
index of the current video input or output. To select a different
|
||||
input or output applications call the &VIDIOC-S-INPUT; and
|
||||
&VIDIOC-S-OUTPUT; ioctl. Drivers must implement all the input ioctls
|
||||
&VIDIOC-S-OUTPUT; ioctls. Drivers must implement all the input ioctls
|
||||
when the device has one or more inputs, all the output ioctls when the
|
||||
device has one or more outputs.</para>
|
||||
|
||||
<!--
|
||||
<figure id=io-tree>
|
||||
<title>Input and output enumeration is the root of most device properties.</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="links.pdf" format="ps" />
|
||||
</imageobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="links.gif" format="gif" />
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>Links between various device property structures.</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
-->
|
||||
|
||||
<example>
|
||||
<title>Information about the current video input</title>
|
||||
|
||||
@ -330,20 +258,20 @@ device has one or more outputs.</para>
|
||||
&v4l2-input; input;
|
||||
int index;
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &index)) {
|
||||
perror ("VIDIOC_G_INPUT");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &index)) {
|
||||
perror("VIDIOC_G_INPUT");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset (&input, 0, sizeof (input));
|
||||
memset(&input, 0, sizeof(input));
|
||||
input.index = index;
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &input)) {
|
||||
perror ("VIDIOC_ENUMINPUT");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &input)) {
|
||||
perror("VIDIOC_ENUMINPUT");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf ("Current input: %s\n", input.name);
|
||||
printf("Current input: %s\n", input.name);
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
@ -355,9 +283,9 @@ int index;
|
||||
|
||||
index = 0;
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-S-INPUT;, &index)) {
|
||||
perror ("VIDIOC_S_INPUT");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-S-INPUT;, &index)) {
|
||||
perror("VIDIOC_S_INPUT");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
@ -397,7 +325,7 @@ available inputs and outputs applications can enumerate them with the
|
||||
also contains signal status information applicable when the current
|
||||
audio input is queried.</para>
|
||||
|
||||
<para>The &VIDIOC-G-AUDIO; and &VIDIOC-G-AUDOUT; ioctl report
|
||||
<para>The &VIDIOC-G-AUDIO; and &VIDIOC-G-AUDOUT; ioctls report
|
||||
the current audio input and output, respectively. Note that, unlike
|
||||
&VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; these ioctls return a structure
|
||||
as <constant>VIDIOC_ENUMAUDIO</constant> and
|
||||
@ -408,11 +336,11 @@ applications call the &VIDIOC-S-AUDIO; ioctl. To select an audio
|
||||
output (which presently has no changeable properties) applications
|
||||
call the &VIDIOC-S-AUDOUT; ioctl.</para>
|
||||
|
||||
<para>Drivers must implement all input ioctls when the device
|
||||
has one or more inputs, all output ioctls when the device has one
|
||||
or more outputs. When the device has any audio inputs or outputs the
|
||||
driver must set the <constant>V4L2_CAP_AUDIO</constant> flag in the
|
||||
&v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl.</para>
|
||||
<para>Drivers must implement all audio input ioctls when the device
|
||||
has multiple selectable audio inputs, all audio output ioctls when the
|
||||
device has multiple selectable audio outputs. When the device has any
|
||||
audio inputs or outputs the driver must set the <constant>V4L2_CAP_AUDIO</constant>
|
||||
flag in the &v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl.</para>
|
||||
|
||||
<example>
|
||||
<title>Information about the current audio input</title>
|
||||
@ -420,14 +348,14 @@ driver must set the <constant>V4L2_CAP_AUDIO</constant> flag in the
|
||||
<programlisting>
|
||||
&v4l2-audio; audio;
|
||||
|
||||
memset (&audio, 0, sizeof (audio));
|
||||
memset(&audio, 0, sizeof(audio));
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-G-AUDIO;, &audio)) {
|
||||
perror ("VIDIOC_G_AUDIO");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-G-AUDIO;, &audio)) {
|
||||
perror("VIDIOC_G_AUDIO");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf ("Current input: %s\n", audio.name);
|
||||
printf("Current input: %s\n", audio.name);
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
@ -437,13 +365,13 @@ printf ("Current input: %s\n", audio.name);
|
||||
<programlisting>
|
||||
&v4l2-audio; audio;
|
||||
|
||||
memset (&audio, 0, sizeof (audio)); /* clear audio.mode, audio.reserved */
|
||||
memset(&audio, 0, sizeof(audio)); /* clear audio.mode, audio.reserved */
|
||||
|
||||
audio.index = 0;
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-S-AUDIO;, &audio)) {
|
||||
perror ("VIDIOC_S_AUDIO");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-S-AUDIO;, &audio)) {
|
||||
perror("VIDIOC_S_AUDIO");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
@ -468,7 +396,7 @@ the tuner.</para>
|
||||
video inputs.</para>
|
||||
|
||||
<para>To query and change tuner properties applications use the
|
||||
&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctl, respectively. The
|
||||
&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctls, respectively. The
|
||||
&v4l2-tuner; returned by <constant>VIDIOC_G_TUNER</constant> also
|
||||
contains signal status information applicable when the tuner of the
|
||||
current video or radio input is queried. Note that
|
||||
@ -533,7 +461,7 @@ standards or variations of standards. Each video input and output may
|
||||
support another set of standards. This set is reported by the
|
||||
<structfield>std</structfield> field of &v4l2-input; and
|
||||
&v4l2-output; returned by the &VIDIOC-ENUMINPUT; and
|
||||
&VIDIOC-ENUMOUTPUT; ioctl, respectively.</para>
|
||||
&VIDIOC-ENUMOUTPUT; ioctls, respectively.</para>
|
||||
|
||||
<para>V4L2 defines one bit for each analog video standard
|
||||
currently in use worldwide, and sets aside bits for driver defined
|
||||
@ -564,28 +492,10 @@ automatically.</para>
|
||||
<para>To query and select the standard used by the current video
|
||||
input or output applications call the &VIDIOC-G-STD; and
|
||||
&VIDIOC-S-STD; ioctl, respectively. The <emphasis>received</emphasis>
|
||||
standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note that the parameter of all these ioctls is a pointer to a &v4l2-std-id; type (a standard set), <emphasis>not</emphasis> an index into the standard enumeration.<footnote>
|
||||
<para>An alternative to the current scheme is to use pointers
|
||||
to indices as arguments of <constant>VIDIOC_G_STD</constant> and
|
||||
<constant>VIDIOC_S_STD</constant>, the &v4l2-input; and
|
||||
&v4l2-output; <structfield>std</structfield> field would be a set of
|
||||
indices like <structfield>audioset</structfield>.</para>
|
||||
<para>Indices are consistent with the rest of the API
|
||||
and identify the standard unambiguously. In the present scheme of
|
||||
things an enumerated standard is looked up by &v4l2-std-id;. Now the
|
||||
standards supported by the inputs of a device can overlap. Just
|
||||
assume the tuner and composite input in the example above both
|
||||
exist on a device. An enumeration of "PAL-B/G", "PAL-H/I" suggests
|
||||
a choice which does not exist. We cannot merge or omit sets, because
|
||||
applications would be unable to find the standards reported by
|
||||
<constant>VIDIOC_G_STD</constant>. That leaves separate enumerations
|
||||
for each input. Also selecting a standard by &v4l2-std-id; can be
|
||||
ambiguous. Advantage of this method is that applications need not
|
||||
identify the standard indirectly, after enumerating.</para><para>So in
|
||||
summary, the lookup itself is unavoidable. The difference is only
|
||||
whether the lookup is necessary to find an enumerated standard or to
|
||||
switch to a standard by &v4l2-std-id;.</para>
|
||||
</footnote> Drivers must implement all video standard ioctls
|
||||
standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note that the
|
||||
parameter of all these ioctls is a pointer to a &v4l2-std-id; type
|
||||
(a standard set), <emphasis>not</emphasis> an index into the standard
|
||||
enumeration. Drivers must implement all video standard ioctls
|
||||
when the device has one or more video inputs or outputs.</para>
|
||||
|
||||
<para>Special rules apply to devices such as USB cameras where the notion of video
|
||||
@ -604,17 +514,10 @@ to zero and the <constant>VIDIOC_G_STD</constant>,
|
||||
<constant>VIDIOC_S_STD</constant>,
|
||||
<constant>VIDIOC_QUERYSTD</constant> and
|
||||
<constant>VIDIOC_ENUMSTD</constant> ioctls shall return the
|
||||
&ENOTTY;.<footnote>
|
||||
<para>See <xref linkend="buffer" /> for a rationale.</para>
|
||||
&ENOTTY; or the &EINVAL;.</para>
|
||||
<para>Applications can make use of the <xref linkend="input-capabilities" /> and
|
||||
<xref linkend="output-capabilities"/> flags to determine whether the video standard ioctls
|
||||
are available for the device.</para>
|
||||
|
||||
<para>See <xref linkend="buffer" /> for a rationale. Probably
|
||||
even USB cameras follow some well known video standard. It might have
|
||||
been better to explicitly indicate elsewhere if a device cannot live
|
||||
up to normal expectations, instead of this exception.</para>
|
||||
</footnote></para>
|
||||
can be used with the given input or output.</para>
|
||||
|
||||
<example>
|
||||
<title>Information about the current video standard</title>
|
||||
@ -623,22 +526,22 @@ up to normal expectations, instead of this exception.</para>
|
||||
&v4l2-std-id; std_id;
|
||||
&v4l2-standard; standard;
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-G-STD;, &std_id)) {
|
||||
if (-1 == ioctl(fd, &VIDIOC-G-STD;, &std_id)) {
|
||||
/* Note when VIDIOC_ENUMSTD always returns ENOTTY this
|
||||
is no video device or it falls under the USB exception,
|
||||
and VIDIOC_G_STD returning ENOTTY is no error. */
|
||||
|
||||
perror ("VIDIOC_G_STD");
|
||||
exit (EXIT_FAILURE);
|
||||
perror("VIDIOC_G_STD");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset (&standard, 0, sizeof (standard));
|
||||
memset(&standard, 0, sizeof(standard));
|
||||
standard.index = 0;
|
||||
|
||||
while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &standard)) {
|
||||
while (0 == ioctl(fd, &VIDIOC-ENUMSTD;, &standard)) {
|
||||
if (standard.id & std_id) {
|
||||
printf ("Current video standard: %s\n", standard.name);
|
||||
exit (EXIT_SUCCESS);
|
||||
printf("Current video standard: %s\n", standard.name);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
standard.index++;
|
||||
@ -648,8 +551,8 @@ while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &standard)) {
|
||||
empty unless this device falls under the USB exception. */
|
||||
|
||||
if (errno == EINVAL || standard.index == 0) {
|
||||
perror ("VIDIOC_ENUMSTD");
|
||||
exit (EXIT_FAILURE);
|
||||
perror("VIDIOC_ENUMSTD");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
@ -662,26 +565,26 @@ input</title>
|
||||
&v4l2-input; input;
|
||||
&v4l2-standard; standard;
|
||||
|
||||
memset (&input, 0, sizeof (input));
|
||||
memset(&input, 0, sizeof(input));
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &input.index)) {
|
||||
perror ("VIDIOC_G_INPUT");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &input.index)) {
|
||||
perror("VIDIOC_G_INPUT");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &input)) {
|
||||
perror ("VIDIOC_ENUM_INPUT");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &input)) {
|
||||
perror("VIDIOC_ENUM_INPUT");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf ("Current input %s supports:\n", input.name);
|
||||
printf("Current input %s supports:\n", input.name);
|
||||
|
||||
memset (&standard, 0, sizeof (standard));
|
||||
memset(&standard, 0, sizeof(standard));
|
||||
standard.index = 0;
|
||||
|
||||
while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &standard)) {
|
||||
while (0 == ioctl(fd, &VIDIOC-ENUMSTD;, &standard)) {
|
||||
if (standard.id & input.std)
|
||||
printf ("%s\n", standard.name);
|
||||
printf("%s\n", standard.name);
|
||||
|
||||
standard.index++;
|
||||
}
|
||||
@ -690,8 +593,8 @@ while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &standard)) {
|
||||
empty unless this device falls under the USB exception. */
|
||||
|
||||
if (errno != EINVAL || standard.index == 0) {
|
||||
perror ("VIDIOC_ENUMSTD");
|
||||
exit (EXIT_FAILURE);
|
||||
perror("VIDIOC_ENUMSTD");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
@ -703,21 +606,21 @@ if (errno != EINVAL || standard.index == 0) {
|
||||
&v4l2-input; input;
|
||||
&v4l2-std-id; std_id;
|
||||
|
||||
memset (&input, 0, sizeof (input));
|
||||
memset(&input, 0, sizeof(input));
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &input.index)) {
|
||||
perror ("VIDIOC_G_INPUT");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &input.index)) {
|
||||
perror("VIDIOC_G_INPUT");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &input)) {
|
||||
perror ("VIDIOC_ENUM_INPUT");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &input)) {
|
||||
perror("VIDIOC_ENUM_INPUT");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (0 == (input.std & V4L2_STD_PAL_BG)) {
|
||||
fprintf (stderr, "Oops. B/G PAL is not supported.\n");
|
||||
exit (EXIT_FAILURE);
|
||||
fprintf(stderr, "Oops. B/G PAL is not supported.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Note this is also supposed to work when only B
|
||||
@ -725,9 +628,9 @@ if (0 == (input.std & V4L2_STD_PAL_BG)) {
|
||||
|
||||
std_id = V4L2_STD_PAL_BG;
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-S-STD;, &std_id)) {
|
||||
perror ("VIDIOC_S_STD");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-S-STD;, &std_id)) {
|
||||
perror("VIDIOC_S_STD");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
@ -740,26 +643,25 @@ corresponding video timings. Today there are many more different hardware interf
|
||||
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 was added to set/get video timings at
|
||||
the input and output: </para><itemizedlist>
|
||||
<listitem>
|
||||
<para>DV Timings: This will allow applications to define detailed
|
||||
video timings for the interface. This includes parameters such as width, height,
|
||||
polarities, frontporch, backporch etc. The <filename>linux/v4l2-dv-timings.h</filename>
|
||||
the limited bits available, a new set of ioctls was added to set/get video timings at
|
||||
the input and output.</para>
|
||||
|
||||
<para>These ioctls deal with the detailed digital video timings that define
|
||||
each video format. This includes parameters such as the active video width and height,
|
||||
signal polarities, frontporches, backporches, sync widths etc. The <filename>linux/v4l2-dv-timings.h</filename>
|
||||
header can be used to get the timings of the formats in the <xref linkend="cea861" /> and
|
||||
<xref linkend="vesadmt" /> standards.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>To enumerate and query the attributes of the DV timings supported by a device,
|
||||
|
||||
<para>To enumerate and query the attributes of the DV timings supported by a device
|
||||
applications use the &VIDIOC-ENUM-DV-TIMINGS; and &VIDIOC-DV-TIMINGS-CAP; ioctls.
|
||||
To set DV timings for the device, applications use the
|
||||
To set DV timings for the device applications use the
|
||||
&VIDIOC-S-DV-TIMINGS; ioctl and to get current DV timings they use the
|
||||
&VIDIOC-G-DV-TIMINGS; ioctl. To detect the DV timings as seen by the video receiver applications
|
||||
use the &VIDIOC-QUERY-DV-TIMINGS; ioctl.</para>
|
||||
<para>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>
|
||||
<xref linkend="output-capabilities"/> flags to determine whether the digital video ioctls
|
||||
can be used with the given input or output.</para>
|
||||
</section>
|
||||
|
||||
&sub-controls;
|
||||
|
@ -2535,6 +2535,16 @@ fields changed from _s32 to _u32.
|
||||
</orderedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>V4L2 in Linux 3.15</title>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Added Software Defined Radio (SDR) Interface.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
|
||||
<section id="other">
|
||||
<title>Relation of V4L2 to other Linux multimedia APIs</title>
|
||||
|
||||
@ -2651,6 +2661,9 @@ ioctls.</para>
|
||||
<listitem>
|
||||
<para>Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Software Defined Radio (SDR) Interface, <xref linkend="sdr" />.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
@ -2256,6 +2256,26 @@ Applicable to the MPEG1, MPEG2, MPEG4 encoders.</entry>
|
||||
<entry>integer</entry>
|
||||
</row><row><entry spanname="descr">Sets the initial delay in milliseconds for
|
||||
VBV buffer control.</entry>
|
||||
</row>
|
||||
|
||||
<row><entry></entry></row>
|
||||
<row id="v4l2-mpeg-video-hor-search-range">
|
||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE</constant> </entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row><entry spanname="descr">Horizontal search range defines maximum horizontal search area in pixels
|
||||
to search and match for the present Macroblock (MB) in the reference picture. This V4L2 control macro is used to set
|
||||
horizontal search range for motion estimation module in video encoder.</entry>
|
||||
</row>
|
||||
|
||||
<row><entry></entry></row>
|
||||
<row id="v4l2-mpeg-video-vert-search-range">
|
||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE</constant> </entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row><entry spanname="descr">Vertical search range defines maximum vertical search area in pixels
|
||||
to search and match for the present Macroblock (MB) in the reference picture. This V4L2 control macro is used to set
|
||||
vertical search range for motion estimation module in video encoder.</entry>
|
||||
</row>
|
||||
|
||||
<row><entry></entry></row>
|
||||
@ -4370,6 +4390,24 @@ interface and may change in the future.</para>
|
||||
<entry>The flash controller has detected a short or open
|
||||
circuit condition on the indicator LED.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_FLASH_FAULT_UNDER_VOLTAGE</constant></entry>
|
||||
<entry>Flash controller voltage to the flash LED
|
||||
has been below the minimum limit specific to the flash
|
||||
controller.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_FLASH_FAULT_INPUT_VOLTAGE</constant></entry>
|
||||
<entry>The input voltage of the flash controller is below
|
||||
the limit under which strobing the flash at full current
|
||||
will not be possible.The condition persists until this flag
|
||||
is no longer set.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE</constant></entry>
|
||||
<entry>The temperature of the LED has exceeded its
|
||||
allowed upper limit.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</entrytbl>
|
||||
</row>
|
||||
@ -4971,4 +5009,142 @@ defines possible values for de-emphasis. Here they are:</entry>
|
||||
</table>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="rf-tuner-controls">
|
||||
<title>RF Tuner Control Reference</title>
|
||||
|
||||
<para>
|
||||
The RF Tuner (RF_TUNER) class includes controls for common features of devices
|
||||
having RF tuner.
|
||||
</para>
|
||||
<para>
|
||||
In this context, RF tuner is radio receiver circuit between antenna and
|
||||
demodulator. It receives radio frequency (RF) from the antenna and converts that
|
||||
received signal to lower intermediate frequency (IF) or baseband frequency (BB).
|
||||
Tuners that could do baseband output are often called Zero-IF tuners. Older
|
||||
tuners were typically simple PLL tuners inside a metal box, whilst newer ones
|
||||
are highly integrated chips without a metal box "silicon tuners". These controls
|
||||
are mostly applicable for new feature rich silicon tuners, just because older
|
||||
tuners does not have much adjustable features.
|
||||
</para>
|
||||
<para>
|
||||
For more information about RF tuners see
|
||||
<ulink url="http://en.wikipedia.org/wiki/Tuner_%28radio%29">Tuner (radio)</ulink>
|
||||
and
|
||||
<ulink url="http://en.wikipedia.org/wiki/RF_front_end">RF front end</ulink>
|
||||
from Wikipedia.
|
||||
</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="rf-tuner-control-id">
|
||||
<title>RF_TUNER Control IDs</title>
|
||||
|
||||
<tgroup cols="4">
|
||||
<colspec colname="c1" colwidth="1*" />
|
||||
<colspec colname="c2" colwidth="6*" />
|
||||
<colspec colname="c3" colwidth="2*" />
|
||||
<colspec colname="c4" colwidth="6*" />
|
||||
<spanspec namest="c1" nameend="c2" spanname="id" />
|
||||
<spanspec namest="c2" nameend="c4" spanname="descr" />
|
||||
<thead>
|
||||
<row>
|
||||
<entry spanname="id" align="left">ID</entry>
|
||||
<entry align="left">Type</entry>
|
||||
</row>
|
||||
<row rowsep="1">
|
||||
<entry spanname="descr" align="left">Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<row><entry></entry></row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_CLASS</constant> </entry>
|
||||
<entry>class</entry>
|
||||
</row><row><entry spanname="descr">The RF_TUNER class
|
||||
descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
|
||||
description of this control class.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_BANDWIDTH_AUTO</constant> </entry>
|
||||
<entry>boolean</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Enables/disables tuner radio channel
|
||||
bandwidth configuration. In automatic mode bandwidth configuration is performed
|
||||
by the driver.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_BANDWIDTH</constant> </entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Filter(s) on tuner signal path are used to
|
||||
filter signal according to receiving party needs. Driver configures filters to
|
||||
fulfill desired bandwidth requirement. Used when V4L2_CID_RF_TUNER_BANDWIDTH_AUTO is not
|
||||
set. Unit is in Hz. The range and step are driver-specific.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_LNA_GAIN_AUTO</constant> </entry>
|
||||
<entry>boolean</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Enables/disables LNA automatic gain control (AGC)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO</constant> </entry>
|
||||
<entry>boolean</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Enables/disables mixer automatic gain control (AGC)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_IF_GAIN_AUTO</constant> </entry>
|
||||
<entry>boolean</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Enables/disables IF automatic gain control (AGC)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_LNA_GAIN</constant> </entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">LNA (low noise amplifier) gain is first
|
||||
gain stage on the RF tuner signal path. It is located very close to tuner
|
||||
antenna input. Used when <constant>V4L2_CID_RF_TUNER_LNA_GAIN_AUTO</constant> is not set.
|
||||
The range and step are driver-specific.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_MIXER_GAIN</constant> </entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Mixer gain is second gain stage on the RF
|
||||
tuner signal path. It is located inside mixer block, where RF signal is
|
||||
down-converted by the mixer. Used when <constant>V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO</constant>
|
||||
is not set. The range and step are driver-specific.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_IF_GAIN</constant> </entry>
|
||||
<entry>integer</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">IF gain is last gain stage on the RF tuner
|
||||
signal path. It is located on output of RF tuner. It controls signal level of
|
||||
intermediate frequency output or baseband output. Used when
|
||||
<constant>V4L2_CID_RF_TUNER_IF_GAIN_AUTO</constant> is not set. The range and step are
|
||||
driver-specific.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="id"><constant>V4L2_CID_RF_TUNER_PLL_LOCK</constant> </entry>
|
||||
<entry>boolean</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="descr">Is synthesizer PLL locked? RF tuner is
|
||||
receiving given frequency when that control is set. This is a read-only control.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
</section>
|
||||
|
@ -56,18 +56,18 @@ framebuffer device.</para>
|
||||
unsigned int i;
|
||||
int fb_fd;
|
||||
|
||||
if (-1 == ioctl (fd, VIDIOC_G_FBUF, &fbuf)) {
|
||||
perror ("VIDIOC_G_FBUF");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, VIDIOC_G_FBUF, &fbuf)) {
|
||||
perror("VIDIOC_G_FBUF");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (i = 0; i > 30; ++i) {
|
||||
for (i = 0; i < 30; i++) {
|
||||
char dev_name[16];
|
||||
struct fb_fix_screeninfo si;
|
||||
|
||||
snprintf (dev_name, sizeof (dev_name), "/dev/fb%u", i);
|
||||
snprintf(dev_name, sizeof(dev_name), "/dev/fb%u", i);
|
||||
|
||||
fb_fd = open (dev_name, O_RDWR);
|
||||
fb_fd = open(dev_name, O_RDWR);
|
||||
if (-1 == fb_fd) {
|
||||
switch (errno) {
|
||||
case ENOENT: /* no such file */
|
||||
@ -75,19 +75,19 @@ for (i = 0; i > 30; ++i) {
|
||||
continue;
|
||||
|
||||
default:
|
||||
perror ("open");
|
||||
exit (EXIT_FAILURE);
|
||||
perror("open");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == ioctl (fb_fd, FBIOGET_FSCREENINFO, &si)) {
|
||||
if (si.smem_start == (unsigned long) fbuf.base)
|
||||
if (0 == ioctl(fb_fd, FBIOGET_FSCREENINFO, &si)) {
|
||||
if (si.smem_start == (unsigned long)fbuf.base)
|
||||
break;
|
||||
} else {
|
||||
/* Apparently not a framebuffer device. */
|
||||
}
|
||||
|
||||
close (fb_fd);
|
||||
close(fb_fd);
|
||||
fb_fd = -1;
|
||||
}
|
||||
|
||||
|
110
Documentation/DocBook/media/v4l/dev-sdr.xml
Normal file
110
Documentation/DocBook/media/v4l/dev-sdr.xml
Normal file
@ -0,0 +1,110 @@
|
||||
<title>Software Defined Radio Interface (SDR)</title>
|
||||
|
||||
<note>
|
||||
<title>Experimental</title>
|
||||
<para>This is an <link linkend="experimental"> experimental </link>
|
||||
interface and may change in the future.</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
SDR is an abbreviation of Software Defined Radio, the radio device
|
||||
which uses application software for modulation or demodulation. This interface
|
||||
is intended for controlling and data streaming of such devices.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
SDR devices are accessed through character device special files named
|
||||
<filename>/dev/swradio0</filename> to <filename>/dev/swradio255</filename>
|
||||
with major number 81 and dynamically allocated minor numbers 0 to 255.
|
||||
</para>
|
||||
|
||||
<section>
|
||||
<title>Querying Capabilities</title>
|
||||
|
||||
<para>
|
||||
Devices supporting the SDR receiver interface set the
|
||||
<constant>V4L2_CAP_SDR_CAPTURE</constant> and
|
||||
<constant>V4L2_CAP_TUNER</constant> flag in the
|
||||
<structfield>capabilities</structfield> field of &v4l2-capability;
|
||||
returned by the &VIDIOC-QUERYCAP; ioctl. That flag means the device has an
|
||||
Analog to Digital Converter (ADC), which is a mandatory element for the SDR receiver.
|
||||
At least one of the read/write, streaming or asynchronous I/O methods must
|
||||
be supported.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Supplemental Functions</title>
|
||||
|
||||
<para>
|
||||
SDR devices can support <link linkend="control">controls</link>, and must
|
||||
support the <link linkend="tuner">tuner</link> ioctls. Tuner ioctls are used
|
||||
for setting the ADC sampling rate (sampling frequency) and the possible RF tuner
|
||||
frequency.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <constant>V4L2_TUNER_ADC</constant> tuner type is used for ADC tuners, and
|
||||
the <constant>V4L2_TUNER_RF</constant> tuner type is used for RF tuners. The
|
||||
tuner index of the RF tuner (if any) must always follow the ADC tuner index.
|
||||
Normally the ADC tuner is #0 and the RF tuner is #1.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The &VIDIOC-S-HW-FREQ-SEEK; ioctl is not supported.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Data Format Negotiation</title>
|
||||
|
||||
<para>
|
||||
The SDR capture device uses the <link linkend="format">format</link> ioctls to
|
||||
select the capture format. Both the sampling resolution and the data streaming
|
||||
format are bound to that selectable format. In addition to the basic
|
||||
<link linkend="format">format</link> ioctls, the &VIDIOC-ENUM-FMT; ioctl
|
||||
must be supported as well.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To use the <link linkend="format">format</link> ioctls applications set the
|
||||
<structfield>type</structfield> field of a &v4l2-format; to
|
||||
<constant>V4L2_BUF_TYPE_SDR_CAPTURE</constant> and use the &v4l2-sdr-format;
|
||||
<structfield>sdr</structfield> member of the <structfield>fmt</structfield>
|
||||
union as needed per the desired operation.
|
||||
Currently only the <structfield>pixelformat</structfield> field of
|
||||
&v4l2-sdr-format; is used. The content of that field is the V4L2 fourcc code
|
||||
of the data format.
|
||||
</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-sdr-format">
|
||||
<title>struct <structname>v4l2_sdr_format</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>pixelformat</structfield></entry>
|
||||
<entry>
|
||||
The data format or type of compression, set by the application. This is a
|
||||
little endian <link linkend="v4l2-fourcc">four character code</link>.
|
||||
V4L2 defines SDR formats in <xref linkend="sdr-formats" />.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u8</entry>
|
||||
<entry><structfield>reserved[28]</structfield></entry>
|
||||
<entry>This array is reserved for future extensions.
|
||||
Drivers and applications must set it to zero.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
An SDR device may support <link linkend="rw">read/write</link>
|
||||
and/or streaming (<link linkend="mmap">memory mapping</link>
|
||||
or <link linkend="userp">user pointer</link>) I/O.
|
||||
</para>
|
||||
|
||||
</section>
|
@ -339,8 +339,8 @@ returns immediately with an &EAGAIN; when no buffer is available. The
|
||||
queues as a side effect. Since there is no notion of doing anything
|
||||
"now" on a multitasking system, if an application needs to synchronize
|
||||
with another event it should examine the &v4l2-buffer;
|
||||
<structfield>timestamp</structfield> of captured buffers, or set the
|
||||
field before enqueuing buffers for output.</para>
|
||||
<structfield>timestamp</structfield> of captured or outputted buffers.
|
||||
</para>
|
||||
|
||||
<para>Drivers implementing memory mapping I/O must
|
||||
support the <constant>VIDIOC_REQBUFS</constant>,
|
||||
@ -457,7 +457,7 @@ queues and unlocks all buffers as a side effect. Since there is no
|
||||
notion of doing anything "now" on a multitasking system, if an
|
||||
application needs to synchronize with another event it should examine
|
||||
the &v4l2-buffer; <structfield>timestamp</structfield> of captured
|
||||
buffers, or set the field before enqueuing buffers for output.</para>
|
||||
or outputted buffers.</para>
|
||||
|
||||
<para>Drivers implementing user pointer I/O must
|
||||
support the <constant>VIDIOC_REQBUFS</constant>,
|
||||
@ -620,8 +620,7 @@ returns immediately with an &EAGAIN; when no buffer is available. The
|
||||
unlocks all buffers as a side effect. Since there is no notion of doing
|
||||
anything "now" on a multitasking system, if an application needs to synchronize
|
||||
with another event it should examine the &v4l2-buffer;
|
||||
<structfield>timestamp</structfield> of captured buffers, or set the field
|
||||
before enqueuing buffers for output.</para>
|
||||
<structfield>timestamp</structfield> of captured or outputted buffers.</para>
|
||||
|
||||
<para>Drivers implementing DMABUF importing I/O must support the
|
||||
<constant>VIDIOC_REQBUFS</constant>, <constant>VIDIOC_QBUF</constant>,
|
||||
@ -654,38 +653,19 @@ plane, are stored in struct <structname>v4l2_plane</structname> instead.
|
||||
In that case, struct <structname>v4l2_buffer</structname> contains an array of
|
||||
plane structures.</para>
|
||||
|
||||
<para>Nominally timestamps refer to the first data byte transmitted.
|
||||
In practice however the wide range of hardware covered by the V4L2 API
|
||||
limits timestamp accuracy. Often an interrupt routine will
|
||||
sample the system clock shortly after the field or frame was stored
|
||||
completely in memory. So applications must expect a constant
|
||||
difference up to one field or frame period plus a small (few scan
|
||||
lines) random error. The delay and error can be much
|
||||
larger due to compression or transmission over an external bus when
|
||||
the frames are not properly stamped by the sender. This is frequently
|
||||
the case with USB cameras. Here timestamps refer to the instant the
|
||||
field or frame was received by the driver, not the capture time. These
|
||||
devices identify by not enumerating any video standards, see <xref
|
||||
linkend="standard" />.</para>
|
||||
|
||||
<para>Similar limitations apply to output timestamps. Typically
|
||||
the video hardware locks to a clock controlling the video timing, the
|
||||
horizontal and vertical synchronization pulses. At some point in the
|
||||
line sequence, possibly the vertical blanking, an interrupt routine
|
||||
samples the system clock, compares against the timestamp and programs
|
||||
the hardware to repeat the previous field or frame, or to display the
|
||||
buffer contents.</para>
|
||||
|
||||
<para>Apart of limitations of the video device and natural
|
||||
inaccuracies of all clocks, it should be noted system time itself is
|
||||
not perfectly stable. It can be affected by power saving cycles,
|
||||
warped to insert leap seconds, or even turned back or forth by the
|
||||
system administrator affecting long term measurements. <footnote>
|
||||
<para>Since no other Linux multimedia
|
||||
API supports unadjusted time it would be foolish to introduce here. We
|
||||
must use a universally supported clock to synchronize different media,
|
||||
hence time of day.</para>
|
||||
</footnote></para>
|
||||
<para>Dequeued video buffers come with timestamps. The driver
|
||||
decides at which part of the frame and with which clock the
|
||||
timestamp is taken. Please see flags in the masks
|
||||
<constant>V4L2_BUF_FLAG_TIMESTAMP_MASK</constant> and
|
||||
<constant>V4L2_BUF_FLAG_TSTAMP_SRC_MASK</constant> in <xref
|
||||
linkend="buffer-flags" />. These flags are always valid and constant
|
||||
across all buffers during the whole video stream. Changes in these
|
||||
flags may take place as a side effect of &VIDIOC-S-INPUT; or
|
||||
&VIDIOC-S-OUTPUT; however. The
|
||||
<constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant> timestamp type
|
||||
which is used by e.g. on mem-to-mem devices is an exception to the
|
||||
rule: the timestamp source flags are copied from the OUTPUT video
|
||||
buffer to the CAPTURE video buffer.</para>
|
||||
|
||||
<table frame="none" pgwide="1" id="v4l2-buffer">
|
||||
<title>struct <structname>v4l2_buffer</structname></title>
|
||||
@ -696,10 +676,11 @@ hence time of day.</para>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>index</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>Number of the buffer, set by the application. This
|
||||
field is only used for <link linkend="mmap">memory mapping</link> I/O
|
||||
and can range from zero to the number of buffers allocated
|
||||
with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.</entry>
|
||||
<entry>Number of the buffer, set by the application except
|
||||
when calling &VIDIOC-DQBUF;, then it is set by the driver.
|
||||
This field can range from zero to the number of buffers allocated
|
||||
with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>),
|
||||
plus any buffers allocated with &VIDIOC-CREATE-BUFS; minus one.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
@ -718,7 +699,7 @@ linkend="v4l2-buf-type" /></entry>
|
||||
buffer. It depends on the negotiated data format and may change with
|
||||
each buffer for compressed variable size data like JPEG images.
|
||||
Drivers must set this field when <structfield>type</structfield>
|
||||
refers to an input stream, applications when an output stream.</entry>
|
||||
refers to an input stream, applications when it refers to an output stream.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
@ -735,7 +716,7 @@ linkend="buffer-flags" />.</entry>
|
||||
buffer, see <xref linkend="v4l2-field" />. This field is not used when
|
||||
the buffer contains VBI data. Drivers must set it when
|
||||
<structfield>type</structfield> refers to an input stream,
|
||||
applications when an output stream.</entry>
|
||||
applications when it refers to an output stream.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>struct timeval</entry>
|
||||
@ -745,15 +726,13 @@ applications when an output stream.</entry>
|
||||
byte was captured, as returned by the
|
||||
<function>clock_gettime()</function> function for the relevant
|
||||
clock id; see <constant>V4L2_BUF_FLAG_TIMESTAMP_*</constant> in
|
||||
<xref linkend="buffer-flags" />. For output streams the data
|
||||
will not be displayed before this time, secondary to the nominal
|
||||
frame rate determined by the current video standard in enqueued
|
||||
order. Applications can for example zero this field to display
|
||||
frames as soon as possible. The driver stores the time at which
|
||||
the first data byte was actually sent out in the
|
||||
<structfield>timestamp</structfield> field. This permits
|
||||
<xref linkend="buffer-flags" />. For output streams the driver
|
||||
stores the time at which the last data byte was actually sent out
|
||||
in the <structfield>timestamp</structfield> field. This permits
|
||||
applications to monitor the drift between the video and system
|
||||
clock.</para></entry>
|
||||
clock. For output streams that use <constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant>
|
||||
the application has to fill in the timestamp which will be copied
|
||||
by the driver to the capture stream.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>&v4l2-timecode;</entry>
|
||||
@ -846,7 +825,8 @@ is the file descriptor associated with a DMABUF buffer.</entry>
|
||||
<entry><structfield>length</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>Size of the buffer (not the payload) in bytes for the
|
||||
single-planar API. For the multi-planar API the application sets
|
||||
single-planar API. This is set by the driver based on the calls to
|
||||
&VIDIOC-REQBUFS; and/or &VIDIOC-CREATE-BUFS;. For the multi-planar API the application sets
|
||||
this to the number of elements in the <structfield>planes</structfield>
|
||||
array. The driver will fill in the actual number of valid elements in
|
||||
that array.
|
||||
@ -880,13 +860,15 @@ should set this to 0.</entry>
|
||||
<entry><structfield>bytesused</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>The number of bytes occupied by data in the plane
|
||||
(its payload).</entry>
|
||||
(its payload). Drivers must set this field when <structfield>type</structfield>
|
||||
refers to an input stream, applications when it refers to an output stream.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>length</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>Size in bytes of the plane (not its payload).</entry>
|
||||
<entry>Size in bytes of the plane (not its payload). This is set by the driver
|
||||
based on the calls to &VIDIOC-REQBUFS; and/or &VIDIOC-CREATE-BUFS;.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>union</entry>
|
||||
@ -925,7 +907,9 @@ should set this to 0.</entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>data_offset</structfield></entry>
|
||||
<entry></entry>
|
||||
<entry>Offset in bytes to video data in the plane, if applicable.
|
||||
<entry>Offset in bytes to video data in the plane.
|
||||
Drivers must set this field when <structfield>type</structfield>
|
||||
refers to an input stream, applications when it refers to an output stream.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
@ -1005,6 +989,12 @@ should set this to 0.</entry>
|
||||
<entry>Buffer for video output overlay (OSD), see <xref
|
||||
linkend="osd" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_TYPE_SDR_CAPTURE</constant></entry>
|
||||
<entry>11</entry>
|
||||
<entry>Buffer for Software Defined Radio (SDR), see <xref
|
||||
linkend="sdr" />.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
@ -1016,7 +1006,7 @@ should set this to 0.</entry>
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_MAPPED</constant></entry>
|
||||
<entry>0x0001</entry>
|
||||
<entry>0x00000001</entry>
|
||||
<entry>The buffer resides in device memory and has been mapped
|
||||
into the application's address space, see <xref linkend="mmap" /> for details.
|
||||
Drivers set or clear this flag when the
|
||||
@ -1026,7 +1016,7 @@ Drivers set or clear this flag when the
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_QUEUED</constant></entry>
|
||||
<entry>0x0002</entry>
|
||||
<entry>0x00000002</entry>
|
||||
<entry>Internally drivers maintain two buffer queues, an
|
||||
incoming and outgoing queue. When this flag is set, the buffer is
|
||||
currently on the incoming queue. It automatically moves to the
|
||||
@ -1039,7 +1029,7 @@ cleared.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_DONE</constant></entry>
|
||||
<entry>0x0004</entry>
|
||||
<entry>0x00000004</entry>
|
||||
<entry>When this flag is set, the buffer is currently on
|
||||
the outgoing queue, ready to be dequeued from the driver. Drivers set
|
||||
or clear this flag when the <constant>VIDIOC_QUERYBUF</constant> ioctl
|
||||
@ -1049,11 +1039,11 @@ buffer cannot be on both queues at the same time, the
|
||||
<constant>V4L2_BUF_FLAG_QUEUED</constant> and
|
||||
<constant>V4L2_BUF_FLAG_DONE</constant> flag are mutually exclusive.
|
||||
They can be both cleared however, then the buffer is in "dequeued"
|
||||
state, in the application domain to say so.</entry>
|
||||
state, in the application domain so to say.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_ERROR</constant></entry>
|
||||
<entry>0x0040</entry>
|
||||
<entry>0x00000040</entry>
|
||||
<entry>When this flag is set, the buffer has been dequeued
|
||||
successfully, although the data might have been corrupted.
|
||||
This is recoverable, streaming may continue as normal and
|
||||
@ -1063,35 +1053,43 @@ state, in the application domain to say so.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry>
|
||||
<entry>0x0008</entry>
|
||||
<entry>0x00000008</entry>
|
||||
<entry>Drivers set or clear this flag when calling the
|
||||
<constant>VIDIOC_DQBUF</constant> ioctl. It may be set by video
|
||||
capture devices when the buffer contains a compressed image which is a
|
||||
key frame (or field), &ie; can be decompressed on its own.</entry>
|
||||
key frame (or field), &ie; can be decompressed on its own. Also know as
|
||||
an I-frame. Applications can set this bit when <structfield>type</structfield>
|
||||
refers to an output stream.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_PFRAME</constant></entry>
|
||||
<entry>0x0010</entry>
|
||||
<entry>0x00000010</entry>
|
||||
<entry>Similar to <constant>V4L2_BUF_FLAG_KEYFRAME</constant>
|
||||
this flags predicted frames or fields which contain only differences to a
|
||||
previous key frame.</entry>
|
||||
previous key frame. Applications can set this bit when <structfield>type</structfield>
|
||||
refers to an output stream.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_BFRAME</constant></entry>
|
||||
<entry>0x0020</entry>
|
||||
<entry>Similar to <constant>V4L2_BUF_FLAG_PFRAME</constant>
|
||||
this is a bidirectional predicted frame or field. [ooc tbd]</entry>
|
||||
<entry>0x00000020</entry>
|
||||
<entry>Similar to <constant>V4L2_BUF_FLAG_KEYFRAME</constant>
|
||||
this flags a bi-directional predicted frame or field which contains only
|
||||
the differences between the current frame and both the preceding and following
|
||||
key frames to specify its content. Applications can set this bit when
|
||||
<structfield>type</structfield> refers to an output stream.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_TIMECODE</constant></entry>
|
||||
<entry>0x0100</entry>
|
||||
<entry>0x00000100</entry>
|
||||
<entry>The <structfield>timecode</structfield> field is valid.
|
||||
Drivers set or clear this flag when the <constant>VIDIOC_DQBUF</constant>
|
||||
ioctl is called.</entry>
|
||||
ioctl is called. Applications can set this bit and the corresponding
|
||||
<structfield>timecode</structfield> structure when <structfield>type</structfield>
|
||||
refers to an output stream.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_PREPARED</constant></entry>
|
||||
<entry>0x0400</entry>
|
||||
<entry>0x00000400</entry>
|
||||
<entry>The buffer has been prepared for I/O and can be queued by the
|
||||
application. Drivers set or clear this flag when the
|
||||
<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
|
||||
@ -1101,7 +1099,7 @@ application. Drivers set or clear this flag when the
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
|
||||
<entry>0x0800</entry>
|
||||
<entry>0x00000800</entry>
|
||||
<entry>Caches do not have to be invalidated for this buffer.
|
||||
Typically applications shall use this flag if the data captured in the buffer
|
||||
is not going to be touched by the CPU, instead the buffer will, probably, be
|
||||
@ -1110,7 +1108,7 @@ passed on to a DMA-capable hardware unit for further processing or output.
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
|
||||
<entry>0x1000</entry>
|
||||
<entry>0x00001000</entry>
|
||||
<entry>Caches do not have to be cleaned for this buffer.
|
||||
Typically applications shall use this flag for output buffers if the data
|
||||
in this buffer has not been created by the CPU but by some DMA-capable unit,
|
||||
@ -1118,7 +1116,7 @@ in which case caches have not been used.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_TIMESTAMP_MASK</constant></entry>
|
||||
<entry>0xe000</entry>
|
||||
<entry>0x0000e000</entry>
|
||||
<entry>Mask for timestamp types below. To test the
|
||||
timestamp type, mask out bits not belonging to timestamp
|
||||
type by performing a logical and operation with buffer
|
||||
@ -1126,7 +1124,7 @@ in which case caches have not been used.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN</constant></entry>
|
||||
<entry>0x0000</entry>
|
||||
<entry>0x00000000</entry>
|
||||
<entry>Unknown timestamp type. This type is used by
|
||||
drivers before Linux 3.9 and may be either monotonic (see
|
||||
below) or realtime (wall clock). Monotonic clock has been
|
||||
@ -1139,7 +1137,7 @@ in which case caches have not been used.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC</constant></entry>
|
||||
<entry>0x2000</entry>
|
||||
<entry>0x00002000</entry>
|
||||
<entry>The buffer timestamp has been taken from the
|
||||
<constant>CLOCK_MONOTONIC</constant> clock. To access the
|
||||
same clock outside V4L2, use
|
||||
@ -1147,10 +1145,42 @@ in which case caches have not been used.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant></entry>
|
||||
<entry>0x4000</entry>
|
||||
<entry>0x00004000</entry>
|
||||
<entry>The CAPTURE buffer timestamp has been taken from the
|
||||
corresponding OUTPUT buffer. This flag applies only to mem2mem devices.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_TSTAMP_SRC_MASK</constant></entry>
|
||||
<entry>0x00070000</entry>
|
||||
<entry>Mask for timestamp sources below. The timestamp source
|
||||
defines the point of time the timestamp is taken in relation to
|
||||
the frame. Logical 'and' operation between the
|
||||
<structfield>flags</structfield> field and
|
||||
<constant>V4L2_BUF_FLAG_TSTAMP_SRC_MASK</constant> produces the
|
||||
value of the timestamp source. Applications must set the timestamp
|
||||
source when <structfield>type</structfield> refers to an output stream
|
||||
and <constant>V4L2_BUF_FLAG_TIMESTAMP_COPY</constant> is set.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_TSTAMP_SRC_EOF</constant></entry>
|
||||
<entry>0x00000000</entry>
|
||||
<entry>End Of Frame. The buffer timestamp has been taken
|
||||
when the last pixel of the frame has been received or the
|
||||
last pixel of the frame has been transmitted. In practice,
|
||||
software generated timestamps will typically be read from
|
||||
the clock a small amount of time after the last pixel has
|
||||
been received or transmitten, depending on the system and
|
||||
other activity in it.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_BUF_FLAG_TSTAMP_SRC_SOE</constant></entry>
|
||||
<entry>0x00010000</entry>
|
||||
<entry>Start Of Exposure. The buffer timestamp has been
|
||||
taken when the exposure of the frame has begun. This is
|
||||
only valid for the
|
||||
<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> buffer
|
||||
type.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
@ -1440,10 +1470,9 @@ or application, depending on data direction, must set &v4l2-buffer;
|
||||
<constant>V4L2_FIELD_BOTTOM</constant>. Any two successive fields pair
|
||||
to build a frame. If fields are successive, without any dropped fields
|
||||
between them (fields can drop individually), can be determined from
|
||||
the &v4l2-buffer; <structfield>sequence</structfield> field. Image
|
||||
sizes refer to the frame, not fields. This format cannot be selected
|
||||
when using the read/write I/O method.<!-- Where it's indistinguishable
|
||||
from V4L2_FIELD_SEQ_*. --></entry>
|
||||
the &v4l2-buffer; <structfield>sequence</structfield> field. This format
|
||||
cannot be selected when using the read/write I/O method since there
|
||||
is no way to communicate if a field was a top or bottom field.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_FIELD_INTERLACED_TB</constant></entry>
|
||||
|
@ -12,18 +12,17 @@
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>This is a multi-planar, two-plane version of the YUV 4:2:0 format.
|
||||
<para>This is a multi-planar, two-plane version of the YUV 4:2:2 format.
|
||||
The three components are separated into two sub-images or planes.
|
||||
<constant>V4L2_PIX_FMT_NV16M</constant> differs from <constant>V4L2_PIX_FMT_NV16
|
||||
</constant> in that the two planes are non-contiguous in memory, i.e. the chroma
|
||||
plane does not necessarily immediately follows the luma plane.
|
||||
plane does not necessarily immediately follow the luma plane.
|
||||
The luminance data occupies the first plane. The Y plane has one byte per pixel.
|
||||
In the second plane there is chrominance data with alternating chroma samples.
|
||||
The CbCr plane is the same width and height, in bytes, as the Y plane.
|
||||
Each CbCr pair belongs to four pixels. For example,
|
||||
Each CbCr pair belongs to two pixels. For example,
|
||||
Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
|
||||
Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
|
||||
Y'<subscript>10</subscript>, Y'<subscript>11</subscript>.
|
||||
Y'<subscript>00</subscript>, Y'<subscript>01</subscript>.
|
||||
<constant>V4L2_PIX_FMT_NV61M</constant> is the same as <constant>V4L2_PIX_FMT_NV16M</constant>
|
||||
except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para>
|
||||
|
||||
|
@ -121,14 +121,14 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
|
||||
<entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
|
||||
<entry>'RGB1'</entry>
|
||||
<entry></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row id="V4L2-PIX-FMT-RGB444">
|
||||
<entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
|
||||
@ -159,18 +159,18 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>a</entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>a</entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
</row>
|
||||
@ -181,17 +181,17 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
@ -201,32 +201,32 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
|
||||
<entry>'RGBQ'</entry>
|
||||
<entry></entry>
|
||||
<entry>a</entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row id="V4L2-PIX-FMT-RGB565X">
|
||||
<entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
|
||||
<entry>'RGBR'</entry>
|
||||
<entry></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row id="V4L2-PIX-FMT-RGB565X">
|
||||
<entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
|
||||
<entry>'RGBR'</entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
@ -234,11 +234,11 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row id="V4L2-PIX-FMT-BGR666">
|
||||
<entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
|
||||
@ -385,6 +385,15 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
|
||||
<entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
|
||||
<entry>'RGB4'</entry>
|
||||
<entry></entry>
|
||||
<entry>a<subscript>7</subscript></entry>
|
||||
<entry>a<subscript>6</subscript></entry>
|
||||
<entry>a<subscript>5</subscript></entry>
|
||||
<entry>a<subscript>4</subscript></entry>
|
||||
<entry>a<subscript>3</subscript></entry>
|
||||
<entry>a<subscript>2</subscript></entry>
|
||||
<entry>a<subscript>1</subscript></entry>
|
||||
<entry>a<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>7</subscript></entry>
|
||||
<entry>r<subscript>6</subscript></entry>
|
||||
<entry>r<subscript>5</subscript></entry>
|
||||
@ -411,25 +420,16 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>a<subscript>7</subscript></entry>
|
||||
<entry>a<subscript>6</subscript></entry>
|
||||
<entry>a<subscript>5</subscript></entry>
|
||||
<entry>a<subscript>4</subscript></entry>
|
||||
<entry>a<subscript>3</subscript></entry>
|
||||
<entry>a<subscript>2</subscript></entry>
|
||||
<entry>a<subscript>1</subscript></entry>
|
||||
<entry>a<subscript>0</subscript></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>Bit 7 is the most significant bit. The value of a = alpha
|
||||
<para>Bit 7 is the most significant bit. The value of the a = alpha
|
||||
bits is undefined when reading from the driver, ignored when writing
|
||||
to the driver, except when alpha blending has been negotiated for a
|
||||
<link linkend="overlay">Video Overlay</link> or <link linkend="osd">
|
||||
Video Output Overlay</link> or when alpha component has been configured
|
||||
Video Output Overlay</link> or when the alpha component has been configured
|
||||
for a <link linkend="capture">Video Capture</link> by means of <link
|
||||
linkend="v4l2-alpha-component"> <constant>V4L2_CID_ALPHA_COMPONENT
|
||||
</constant> </link> control.</para>
|
||||
@ -512,421 +512,6 @@ image</title>
|
||||
</formalpara>
|
||||
</example>
|
||||
|
||||
<important>
|
||||
<para>Drivers may interpret these formats differently.</para>
|
||||
</important>
|
||||
|
||||
<para>Some RGB formats above are uncommon and were probably
|
||||
defined in error. Drivers may interpret them as in <xref
|
||||
linkend="rgb-formats-corrected" />.</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="rgb-formats-corrected">
|
||||
<title>Packed RGB Image Formats (corrected)</title>
|
||||
<tgroup cols="37" align="center">
|
||||
<colspec colname="id" align="left" />
|
||||
<colspec colname="fourcc" />
|
||||
<colspec colname="bit" />
|
||||
|
||||
<colspec colnum="4" colname="b07" align="center" />
|
||||
<colspec colnum="5" colname="b06" align="center" />
|
||||
<colspec colnum="6" colname="b05" align="center" />
|
||||
<colspec colnum="7" colname="b04" align="center" />
|
||||
<colspec colnum="8" colname="b03" align="center" />
|
||||
<colspec colnum="9" colname="b02" align="center" />
|
||||
<colspec colnum="10" colname="b01" align="center" />
|
||||
<colspec colnum="11" colname="b00" align="center" />
|
||||
|
||||
<colspec colnum="13" colname="b17" align="center" />
|
||||
<colspec colnum="14" colname="b16" align="center" />
|
||||
<colspec colnum="15" colname="b15" align="center" />
|
||||
<colspec colnum="16" colname="b14" align="center" />
|
||||
<colspec colnum="17" colname="b13" align="center" />
|
||||
<colspec colnum="18" colname="b12" align="center" />
|
||||
<colspec colnum="19" colname="b11" align="center" />
|
||||
<colspec colnum="20" colname="b10" align="center" />
|
||||
|
||||
<colspec colnum="22" colname="b27" align="center" />
|
||||
<colspec colnum="23" colname="b26" align="center" />
|
||||
<colspec colnum="24" colname="b25" align="center" />
|
||||
<colspec colnum="25" colname="b24" align="center" />
|
||||
<colspec colnum="26" colname="b23" align="center" />
|
||||
<colspec colnum="27" colname="b22" align="center" />
|
||||
<colspec colnum="28" colname="b21" align="center" />
|
||||
<colspec colnum="29" colname="b20" align="center" />
|
||||
|
||||
<colspec colnum="31" colname="b37" align="center" />
|
||||
<colspec colnum="32" colname="b36" align="center" />
|
||||
<colspec colnum="33" colname="b35" align="center" />
|
||||
<colspec colnum="34" colname="b34" align="center" />
|
||||
<colspec colnum="35" colname="b33" align="center" />
|
||||
<colspec colnum="36" colname="b32" align="center" />
|
||||
<colspec colnum="37" colname="b31" align="center" />
|
||||
<colspec colnum="38" colname="b30" align="center" />
|
||||
|
||||
<spanspec namest="b07" nameend="b00" spanname="b0" />
|
||||
<spanspec namest="b17" nameend="b10" spanname="b1" />
|
||||
<spanspec namest="b27" nameend="b20" spanname="b2" />
|
||||
<spanspec namest="b37" nameend="b30" spanname="b3" />
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Identifier</entry>
|
||||
<entry>Code</entry>
|
||||
<entry> </entry>
|
||||
<entry spanname="b0">Byte 0 in memory</entry>
|
||||
<entry spanname="b1">Byte 1</entry>
|
||||
<entry spanname="b2">Byte 2</entry>
|
||||
<entry spanname="b3">Byte 3</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry> </entry>
|
||||
<entry> </entry>
|
||||
<entry>Bit</entry>
|
||||
<entry>7</entry>
|
||||
<entry>6</entry>
|
||||
<entry>5</entry>
|
||||
<entry>4</entry>
|
||||
<entry>3</entry>
|
||||
<entry>2</entry>
|
||||
<entry>1</entry>
|
||||
<entry>0</entry>
|
||||
<entry> </entry>
|
||||
<entry>7</entry>
|
||||
<entry>6</entry>
|
||||
<entry>5</entry>
|
||||
<entry>4</entry>
|
||||
<entry>3</entry>
|
||||
<entry>2</entry>
|
||||
<entry>1</entry>
|
||||
<entry>0</entry>
|
||||
<entry> </entry>
|
||||
<entry>7</entry>
|
||||
<entry>6</entry>
|
||||
<entry>5</entry>
|
||||
<entry>4</entry>
|
||||
<entry>3</entry>
|
||||
<entry>2</entry>
|
||||
<entry>1</entry>
|
||||
<entry>0</entry>
|
||||
<entry> </entry>
|
||||
<entry>7</entry>
|
||||
<entry>6</entry>
|
||||
<entry>5</entry>
|
||||
<entry>4</entry>
|
||||
<entry>3</entry>
|
||||
<entry>2</entry>
|
||||
<entry>1</entry>
|
||||
<entry>0</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<row><!-- id="V4L2-PIX-FMT-RGB332" -->
|
||||
<entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
|
||||
<entry>'RGB1'</entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-RGB444" -->
|
||||
<entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
|
||||
<entry>'R444'</entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>a<subscript>3</subscript></entry>
|
||||
<entry>a<subscript>2</subscript></entry>
|
||||
<entry>a<subscript>1</subscript></entry>
|
||||
<entry>a<subscript>0</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-RGB555" -->
|
||||
<entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
|
||||
<entry>'RGBO'</entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>a</entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-RGB565" -->
|
||||
<entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
|
||||
<entry>'RGBP'</entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-RGB555X" -->
|
||||
<entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
|
||||
<entry>'RGBQ'</entry>
|
||||
<entry></entry>
|
||||
<entry>a</entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-RGB565X" -->
|
||||
<entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
|
||||
<entry>'RGBR'</entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-BGR666" -->
|
||||
<entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
|
||||
<entry>'BGRH'</entry>
|
||||
<entry></entry>
|
||||
<entry>b<subscript>5</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry>r<subscript>5</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-BGR24" -->
|
||||
<entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
|
||||
<entry>'BGR3'</entry>
|
||||
<entry></entry>
|
||||
<entry>b<subscript>7</subscript></entry>
|
||||
<entry>b<subscript>6</subscript></entry>
|
||||
<entry>b<subscript>5</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>7</subscript></entry>
|
||||
<entry>g<subscript>6</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>7</subscript></entry>
|
||||
<entry>r<subscript>6</subscript></entry>
|
||||
<entry>r<subscript>5</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-RGB24" -->
|
||||
<entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
|
||||
<entry>'RGB3'</entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>7</subscript></entry>
|
||||
<entry>r<subscript>6</subscript></entry>
|
||||
<entry>r<subscript>5</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>7</subscript></entry>
|
||||
<entry>g<subscript>6</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>b<subscript>7</subscript></entry>
|
||||
<entry>b<subscript>6</subscript></entry>
|
||||
<entry>b<subscript>5</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-BGR32" -->
|
||||
<entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
|
||||
<entry>'BGR4'</entry>
|
||||
<entry></entry>
|
||||
<entry>b<subscript>7</subscript></entry>
|
||||
<entry>b<subscript>6</subscript></entry>
|
||||
<entry>b<subscript>5</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>7</subscript></entry>
|
||||
<entry>g<subscript>6</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>7</subscript></entry>
|
||||
<entry>r<subscript>6</subscript></entry>
|
||||
<entry>r<subscript>5</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>a<subscript>7</subscript></entry>
|
||||
<entry>a<subscript>6</subscript></entry>
|
||||
<entry>a<subscript>5</subscript></entry>
|
||||
<entry>a<subscript>4</subscript></entry>
|
||||
<entry>a<subscript>3</subscript></entry>
|
||||
<entry>a<subscript>2</subscript></entry>
|
||||
<entry>a<subscript>1</subscript></entry>
|
||||
<entry>a<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row><!-- id="V4L2-PIX-FMT-RGB32" -->
|
||||
<entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
|
||||
<entry>'RGB4'</entry>
|
||||
<entry></entry>
|
||||
<entry>a<subscript>7</subscript></entry>
|
||||
<entry>a<subscript>6</subscript></entry>
|
||||
<entry>a<subscript>5</subscript></entry>
|
||||
<entry>a<subscript>4</subscript></entry>
|
||||
<entry>a<subscript>3</subscript></entry>
|
||||
<entry>a<subscript>2</subscript></entry>
|
||||
<entry>a<subscript>1</subscript></entry>
|
||||
<entry>a<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>r<subscript>7</subscript></entry>
|
||||
<entry>r<subscript>6</subscript></entry>
|
||||
<entry>r<subscript>5</subscript></entry>
|
||||
<entry>r<subscript>4</subscript></entry>
|
||||
<entry>r<subscript>3</subscript></entry>
|
||||
<entry>r<subscript>2</subscript></entry>
|
||||
<entry>r<subscript>1</subscript></entry>
|
||||
<entry>r<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>g<subscript>7</subscript></entry>
|
||||
<entry>g<subscript>6</subscript></entry>
|
||||
<entry>g<subscript>5</subscript></entry>
|
||||
<entry>g<subscript>4</subscript></entry>
|
||||
<entry>g<subscript>3</subscript></entry>
|
||||
<entry>g<subscript>2</subscript></entry>
|
||||
<entry>g<subscript>1</subscript></entry>
|
||||
<entry>g<subscript>0</subscript></entry>
|
||||
<entry></entry>
|
||||
<entry>b<subscript>7</subscript></entry>
|
||||
<entry>b<subscript>6</subscript></entry>
|
||||
<entry>b<subscript>5</subscript></entry>
|
||||
<entry>b<subscript>4</subscript></entry>
|
||||
<entry>b<subscript>3</subscript></entry>
|
||||
<entry>b<subscript>2</subscript></entry>
|
||||
<entry>b<subscript>1</subscript></entry>
|
||||
<entry>b<subscript>0</subscript></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>A test utility to determine which RGB formats a driver
|
||||
actually supports is available from the LinuxTV v4l-dvb repository.
|
||||
See &v4l-dvb; for access instructions.</para>
|
||||
|
44
Documentation/DocBook/media/v4l/pixfmt-sdr-cu08.xml
Normal file
44
Documentation/DocBook/media/v4l/pixfmt-sdr-cu08.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<refentry id="V4L2-SDR-FMT-CU08">
|
||||
<refmeta>
|
||||
<refentrytitle>V4L2_SDR_FMT_CU8 ('CU08')</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname>
|
||||
<constant>V4L2_SDR_FMT_CU8</constant>
|
||||
</refname>
|
||||
<refpurpose>Complex unsigned 8-bit IQ sample</refpurpose>
|
||||
</refnamediv>
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
<para>
|
||||
This format contains sequence of complex number samples. Each complex number
|
||||
consist two parts, called In-phase and Quadrature (IQ). Both I and Q are
|
||||
represented as a 8 bit unsigned number. I value comes first and Q value after
|
||||
that.
|
||||
</para>
|
||||
<example>
|
||||
<title><constant>V4L2_SDR_FMT_CU8</constant> 1 sample</title>
|
||||
<formalpara>
|
||||
<title>Byte Order.</title>
|
||||
<para>Each cell is one byte.
|
||||
<informaltable frame="none">
|
||||
<tgroup cols="2" align="center">
|
||||
<colspec align="left" colwidth="2*" />
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>start + 0:</entry>
|
||||
<entry>I'<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>start + 1:</entry>
|
||||
<entry>Q'<subscript>0</subscript></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</para>
|
||||
</formalpara>
|
||||
</example>
|
||||
</refsect1>
|
||||
</refentry>
|
46
Documentation/DocBook/media/v4l/pixfmt-sdr-cu16le.xml
Normal file
46
Documentation/DocBook/media/v4l/pixfmt-sdr-cu16le.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<refentry id="V4L2-SDR-FMT-CU16LE">
|
||||
<refmeta>
|
||||
<refentrytitle>V4L2_SDR_FMT_CU16LE ('CU16')</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname>
|
||||
<constant>V4L2_SDR_FMT_CU16LE</constant>
|
||||
</refname>
|
||||
<refpurpose>Complex unsigned 16-bit little endian IQ sample</refpurpose>
|
||||
</refnamediv>
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
<para>
|
||||
This format contains sequence of complex number samples. Each complex number
|
||||
consist two parts, called In-phase and Quadrature (IQ). Both I and Q are
|
||||
represented as a 16 bit unsigned little endian number. I value comes first
|
||||
and Q value after that.
|
||||
</para>
|
||||
<example>
|
||||
<title><constant>V4L2_SDR_FMT_CU16LE</constant> 1 sample</title>
|
||||
<formalpara>
|
||||
<title>Byte Order.</title>
|
||||
<para>Each cell is one byte.
|
||||
<informaltable frame="none">
|
||||
<tgroup cols="3" align="center">
|
||||
<colspec align="left" colwidth="2*" />
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>start + 0:</entry>
|
||||
<entry>I'<subscript>0[7:0]</subscript></entry>
|
||||
<entry>I'<subscript>0[15:8]</subscript></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>start + 2:</entry>
|
||||
<entry>Q'<subscript>0[7:0]</subscript></entry>
|
||||
<entry>Q'<subscript>0[15:8]</subscript></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</para>
|
||||
</formalpara>
|
||||
</example>
|
||||
</refsect1>
|
||||
</refentry>
|
@ -25,7 +25,12 @@ capturing and output, for overlay frame buffer formats see also
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>height</structfield></entry>
|
||||
<entry>Image height in pixels.</entry>
|
||||
<entry>Image height in pixels. If <structfield>field</structfield> is
|
||||
one of <constant>V4L2_FIELD_TOP</constant>, <constant>V4L2_FIELD_BOTTOM</constant>
|
||||
or <constant>V4L2_FIELD_ALTERNATE</constant> then height refers to the
|
||||
number of lines in the field, otherwise it refers to the number of
|
||||
lines in the frame (which is twice the field height for interlaced
|
||||
formats).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry spanname="hspan">Applications set these fields to
|
||||
@ -54,7 +59,7 @@ linkend="reserved-formats" /></entry>
|
||||
can request to capture or output only the top or bottom field, or both
|
||||
fields interlaced or sequentially stored in one buffer or alternating
|
||||
in separate buffers. Drivers return the actual field order selected.
|
||||
For details see <xref linkend="field-order" />.</entry>
|
||||
For more details on fields see <xref linkend="field-order" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
@ -81,7 +86,10 @@ plane and is divided by the same factor as the
|
||||
example the Cb and Cr planes of a YUV 4:2:0 image have half as many
|
||||
padding bytes following each line as the Y plane. To avoid ambiguities
|
||||
drivers must return a <structfield>bytesperline</structfield> value
|
||||
rounded up to a multiple of the scale factor.</para></entry>
|
||||
rounded up to a multiple of the scale factor.</para>
|
||||
<para>For compressed formats the <structfield>bytesperline</structfield>
|
||||
value makes no sense. Applications and drivers must set this to 0 in
|
||||
that case.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
@ -97,7 +105,8 @@ hold an image.</entry>
|
||||
<entry>&v4l2-colorspace;</entry>
|
||||
<entry><structfield>colorspace</structfield></entry>
|
||||
<entry>This information supplements the
|
||||
<structfield>pixelformat</structfield> and must be set by the driver,
|
||||
<structfield>pixelformat</structfield> and must be set by the driver for
|
||||
capture streams and by the application for output streams,
|
||||
see <xref linkend="colorspaces" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
@ -135,7 +144,7 @@ set this field to zero.</entry>
|
||||
<entry>__u16</entry>
|
||||
<entry><structfield>bytesperline</structfield></entry>
|
||||
<entry>Distance in bytes between the leftmost pixels in two adjacent
|
||||
lines.</entry>
|
||||
lines. See &v4l2-pix-format;.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u16</entry>
|
||||
@ -154,12 +163,12 @@ set this field to zero.</entry>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>width</structfield></entry>
|
||||
<entry>Image width in pixels.</entry>
|
||||
<entry>Image width in pixels. See &v4l2-pix-format;.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>height</structfield></entry>
|
||||
<entry>Image height in pixels.</entry>
|
||||
<entry>Image height in pixels. See &v4l2-pix-format;.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
@ -811,6 +820,17 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section id="sdr-formats">
|
||||
<title>SDR Formats</title>
|
||||
|
||||
<para>These formats are used for <link linkend="sdr">SDR Capture</link>
|
||||
interface only.</para>
|
||||
|
||||
&sub-sdr-cu08;
|
||||
&sub-sdr-cu16le;
|
||||
|
||||
</section>
|
||||
|
||||
<section id="pixfmt-reserved">
|
||||
<title>Reserved Format Identifiers</title>
|
||||
|
||||
|
@ -1,10 +1,152 @@
|
||||
<partinfo>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Mauro</firstname>
|
||||
<surname>Chehab</surname>
|
||||
<othername role="mi">Carvalho</othername>
|
||||
<affiliation><address><email>m.chehab@samsung.com</email></address></affiliation>
|
||||
<contrib>Initial version.</contrib>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<copyright>
|
||||
<year>2009-2014</year>
|
||||
<holder>Mauro Carvalho Chehab</holder>
|
||||
</copyright>
|
||||
|
||||
<revhistory>
|
||||
<!-- Put document revisions here, newest first. -->
|
||||
<revision>
|
||||
<revnumber>3.15</revnumber>
|
||||
<date>2014-02-06</date>
|
||||
<authorinitials>mcc</authorinitials>
|
||||
<revremark>Added the interface description and the RC sysfs class description.</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>1.0</revnumber>
|
||||
<date>2009-09-06</date>
|
||||
<authorinitials>mcc</authorinitials>
|
||||
<revremark>Initial revision</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</partinfo>
|
||||
|
||||
<title>Remote Controller API</title>
|
||||
<chapter id="remote_controllers">
|
||||
|
||||
<title>Remote Controllers</title>
|
||||
|
||||
<section id="Remote_controllers_Intro">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>Currently, most analog and digital devices have a Infrared input for remote controllers. Each
|
||||
manufacturer has their own type of control. It is not rare for the same manufacturer to ship different
|
||||
types of controls, depending on the device.</para>
|
||||
<para>A Remote Controller interface is mapped as a normal evdev/input interface, just like a keyboard or a mouse.
|
||||
So, it uses all ioctls already defined for any other input devices.</para>
|
||||
<para>However, remove controllers are more flexible than a normal input device, as the IR
|
||||
receiver (and/or transmitter) can be used in conjunction with a wide variety of different IR remotes.</para>
|
||||
<para>In order to allow flexibility, the Remote Controller subsystem allows controlling the
|
||||
RC-specific attributes via <link linkend="remote_controllers_sysfs_nodes">the sysfs class nodes</link>.</para>
|
||||
</section>
|
||||
|
||||
<section id="remote_controllers_sysfs_nodes">
|
||||
<title>Remote Controller's sysfs nodes</title>
|
||||
<para>As defined at <constant>Documentation/ABI/testing/sysfs-class-rc</constant>, those are the sysfs nodes that control the Remote Controllers:</para>
|
||||
|
||||
<section id="sys_class_rc">
|
||||
<title>/sys/class/rc/</title>
|
||||
<para>The <constant>/sys/class/rc/</constant> class sub-directory belongs to the Remote Controller
|
||||
core and provides a sysfs interface for configuring infrared remote controller receivers.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
<section id="sys_class_rc_rcN">
|
||||
<title>/sys/class/rc/rcN/</title>
|
||||
<para>A <constant>/sys/class/rc/rcN</constant> directory is created for each remote
|
||||
control receiver device where N is the number of the receiver.</para>
|
||||
|
||||
</section>
|
||||
<section id="sys_class_rc_rcN_protocols">
|
||||
<title>/sys/class/rc/rcN/protocols</title>
|
||||
<para>Reading this file returns a list of available protocols, something like:</para>
|
||||
<para><constant>rc5 [rc6] nec jvc [sony]</constant></para>
|
||||
<para>Enabled protocols are shown in [] brackets.</para>
|
||||
<para>Writing "+proto" will add a protocol to the list of enabled protocols.</para>
|
||||
<para>Writing "-proto" will remove a protocol from the list of enabled protocols.</para>
|
||||
<para>Writing "proto" will enable only "proto".</para>
|
||||
<para>Writing "none" will disable all protocols.</para>
|
||||
<para>Write fails with EINVAL if an invalid protocol combination or unknown protocol name is used.</para>
|
||||
|
||||
</section>
|
||||
<section id="sys_class_rc_rcN_filter">
|
||||
<title>/sys/class/rc/rcN/filter</title>
|
||||
<para>Sets the scancode filter expected value.</para>
|
||||
<para>Use in combination with <constant>/sys/class/rc/rcN/filter_mask</constant> to set the
|
||||
expected value of the bits set in the filter mask.
|
||||
If the hardware supports it then scancodes which do not match
|
||||
the filter will be ignored. Otherwise the write will fail with
|
||||
an error.</para>
|
||||
<para>This value may be reset to 0 if the current protocol is altered.</para>
|
||||
|
||||
</section>
|
||||
<section id="sys_class_rc_rcN_filter_mask">
|
||||
<title>/sys/class/rc/rcN/filter_mask</title>
|
||||
<para>Sets the scancode filter mask of bits to compare.
|
||||
Use in combination with <constant>/sys/class/rc/rcN/filter</constant> to set the bits
|
||||
of the scancode which should be compared against the expected
|
||||
value. A value of 0 disables the filter to allow all valid
|
||||
scancodes to be processed.</para>
|
||||
<para>If the hardware supports it then scancodes which do not match
|
||||
the filter will be ignored. Otherwise the write will fail with
|
||||
an error.</para>
|
||||
<para>This value may be reset to 0 if the current protocol is altered.</para>
|
||||
|
||||
</section>
|
||||
<section id="sys_class_rc_rcN_wakeup_protocols">
|
||||
<title>/sys/class/rc/rcN/wakeup_protocols</title>
|
||||
<para>Reading this file returns a list of available protocols to use for the
|
||||
wakeup filter, something like:</para>
|
||||
<para><constant>rc5 rc6 nec jvc [sony]</constant></para>
|
||||
<para>The enabled wakeup protocol is shown in [] brackets.</para>
|
||||
<para>Writing "+proto" will add a protocol to the list of enabled wakeup
|
||||
protocols.</para>
|
||||
<para>Writing "-proto" will remove a protocol from the list of enabled wakeup
|
||||
protocols.</para>
|
||||
<para>Writing "proto" will use "proto" for wakeup events.</para>
|
||||
<para>Writing "none" will disable wakeup.</para>
|
||||
<para>Write fails with EINVAL if an invalid protocol combination or unknown
|
||||
protocol name is used, or if wakeup is not supported by the hardware.</para>
|
||||
|
||||
</section>
|
||||
<section id="sys_class_rc_rcN_wakeup_filter">
|
||||
<title>/sys/class/rc/rcN/wakeup_filter</title>
|
||||
<para>Sets the scancode wakeup filter expected value.
|
||||
Use in combination with <constant>/sys/class/rc/rcN/wakeup_filter_mask</constant> to
|
||||
set the expected value of the bits set in the wakeup filter mask
|
||||
to trigger a system wake event.</para>
|
||||
<para>If the hardware supports it and wakeup_filter_mask is not 0 then
|
||||
scancodes which match the filter will wake the system from e.g.
|
||||
suspend to RAM or power off.
|
||||
Otherwise the write will fail with an error.</para>
|
||||
<para>This value may be reset to 0 if the wakeup protocol is altered.</para>
|
||||
|
||||
</section>
|
||||
<section id="sys_class_rc_rcN_wakeup_filter_mask">
|
||||
<title>/sys/class/rc/rcN/wakeup_filter_mask</title>
|
||||
<para>Sets the scancode wakeup filter mask of bits to compare.
|
||||
Use in combination with <constant>/sys/class/rc/rcN/wakeup_filter</constant> to set
|
||||
the bits of the scancode which should be compared against the
|
||||
expected value to trigger a system wake event.</para>
|
||||
<para>If the hardware supports it and wakeup_filter_mask is not 0 then
|
||||
scancodes which match the filter will wake the system from e.g.
|
||||
suspend to RAM or power off.
|
||||
Otherwise the write will fail with an error.</para>
|
||||
<para>This value may be reset to 0 if the wakeup protocol is altered.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="Remote_controllers_tables">
|
||||
<title>Remote controller tables</title>
|
||||
<para>Unfortunately, for several years, there was no effort to create uniform IR keycodes for
|
||||
different devices. This caused the same IR keyname to be mapped completely differently on
|
||||
different IR devices. This resulted that the same IR keyname to be mapped completely different on
|
||||
@ -175,3 +317,4 @@ keymapping.</para>
|
||||
</section>
|
||||
|
||||
&sub-lirc_device_interface;
|
||||
</chapter>
|
||||
|
@ -70,7 +70,7 @@ MPEG stream embedded, sliced VBI data format in this specification.
|
||||
Remote Controller chapter.</contrib>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>mchehab@redhat.com</email>
|
||||
<email>m.chehab@samsung.com</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
@ -107,6 +107,16 @@ Remote Controller chapter.</contrib>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Antti</firstname>
|
||||
<surname>Palosaari</surname>
|
||||
<contrib>SDR API.</contrib>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>crope@iki.fi</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
@ -125,6 +135,7 @@ Remote Controller chapter.</contrib>
|
||||
<year>2011</year>
|
||||
<year>2012</year>
|
||||
<year>2013</year>
|
||||
<year>2014</year>
|
||||
<holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
|
||||
Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
|
||||
Pawel Osciak</holder>
|
||||
@ -140,6 +151,16 @@ structs, ioctls) must be noted in more detail in the history chapter
|
||||
(compat.xml), along with the possible impact on existing drivers and
|
||||
applications. -->
|
||||
|
||||
<revision>
|
||||
<revnumber>3.15</revnumber>
|
||||
<date>2014-02-03</date>
|
||||
<authorinitials>hv, ap</authorinitials>
|
||||
<revremark>Update several sections of "Common API Elements": "Opening and Closing Devices"
|
||||
"Querying Capabilities", "Application Priority", "Video Inputs and Outputs", "Audio Inputs and Outputs"
|
||||
"Tuners and Modulators", "Video Standards" and "Digital Video (DV) Timings". Added SDR API.
|
||||
</revremark>
|
||||
</revision>
|
||||
|
||||
<revision>
|
||||
<revnumber>3.14</revnumber>
|
||||
<date>2013-11-25</date>
|
||||
@ -537,6 +558,7 @@ and discussions on the V4L mailing list.</revremark>
|
||||
<section id="ttx"> &sub-dev-teletext; </section>
|
||||
<section id="radio"> &sub-dev-radio; </section>
|
||||
<section id="rds"> &sub-dev-rds; </section>
|
||||
<section id="sdr"> &sub-dev-sdr; </section>
|
||||
<section id="event"> &sub-dev-event; </section>
|
||||
<section id="subdev"> &sub-dev-subdev; </section>
|
||||
</chapter>
|
||||
@ -585,6 +607,7 @@ and discussions on the V4L mailing list.</revremark>
|
||||
&sub-g-crop;
|
||||
&sub-g-ctrl;
|
||||
&sub-g-dv-timings;
|
||||
&sub-g-edid;
|
||||
&sub-g-enc-index;
|
||||
&sub-g-ext-ctrls;
|
||||
&sub-g-fbuf;
|
||||
@ -616,7 +639,6 @@ and discussions on the V4L mailing list.</revremark>
|
||||
&sub-subdev-enum-frame-size;
|
||||
&sub-subdev-enum-mbus-code;
|
||||
&sub-subdev-g-crop;
|
||||
&sub-subdev-g-edid;
|
||||
&sub-subdev-g-fmt;
|
||||
&sub-subdev-g-frame-interval;
|
||||
&sub-subdev-g-selection;
|
||||
|
@ -100,7 +100,7 @@ See <xref linkend="v4l2-tuner-type" /></entry>
|
||||
<entry><structfield>capability</structfield></entry>
|
||||
<entry spanname="hspan">The tuner/modulator capability flags for
|
||||
this frequency band, see <xref linkend="tuner-capability" />. The <constant>V4L2_TUNER_CAP_LOW</constant>
|
||||
capability must be the same for all frequency bands of the selected tuner/modulator.
|
||||
or <constant>V4L2_TUNER_CAP_1HZ</constant> capability must be the same for all frequency bands of the selected tuner/modulator.
|
||||
So either all bands have that capability set, or none of them have that capability.</entry>
|
||||
</row>
|
||||
<row>
|
||||
@ -109,7 +109,8 @@ So either all bands have that capability set, or none of them have that capabili
|
||||
<entry spanname="hspan">The lowest tunable frequency in
|
||||
units of 62.5 kHz, or if the <structfield>capability</structfield>
|
||||
flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
|
||||
Hz, for this frequency band.</entry>
|
||||
Hz, for this frequency band. A 1 Hz unit is used when the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
@ -117,7 +118,8 @@ Hz, for this frequency band.</entry>
|
||||
<entry spanname="hspan">The highest tunable frequency in
|
||||
units of 62.5 kHz, or if the <structfield>capability</structfield>
|
||||
flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
|
||||
Hz, for this frequency band.</entry>
|
||||
Hz, for this frequency band. A 1 Hz unit is used when the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<refentry id="vidioc-subdev-g-edid">
|
||||
<refentry id="vidioc-g-edid">
|
||||
<refmeta>
|
||||
<refentrytitle>ioctl VIDIOC_SUBDEV_G_EDID, VIDIOC_SUBDEV_S_EDID</refentrytitle>
|
||||
<refentrytitle>ioctl VIDIOC_G_EDID, VIDIOC_S_EDID</refentrytitle>
|
||||
&manvol;
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>VIDIOC_SUBDEV_G_EDID</refname>
|
||||
<refname>VIDIOC_SUBDEV_S_EDID</refname>
|
||||
<refname>VIDIOC_G_EDID</refname>
|
||||
<refname>VIDIOC_S_EDID</refname>
|
||||
<refpurpose>Get or set the EDID of a video receiver/transmitter</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
<funcdef>int <function>ioctl</function></funcdef>
|
||||
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||
<paramdef>int <parameter>request</parameter></paramdef>
|
||||
<paramdef>struct v4l2_subdev_edid *<parameter>argp</parameter></paramdef>
|
||||
<paramdef>struct v4l2_edid *<parameter>argp</parameter></paramdef>
|
||||
</funcprototype>
|
||||
</funcsynopsis>
|
||||
<funcsynopsis>
|
||||
@ -24,7 +24,7 @@
|
||||
<funcdef>int <function>ioctl</function></funcdef>
|
||||
<paramdef>int <parameter>fd</parameter></paramdef>
|
||||
<paramdef>int <parameter>request</parameter></paramdef>
|
||||
<paramdef>const struct v4l2_subdev_edid *<parameter>argp</parameter></paramdef>
|
||||
<paramdef>const struct v4l2_edid *<parameter>argp</parameter></paramdef>
|
||||
</funcprototype>
|
||||
</funcsynopsis>
|
||||
</refsynopsisdiv>
|
||||
@ -42,7 +42,7 @@
|
||||
<varlistentry>
|
||||
<term><parameter>request</parameter></term>
|
||||
<listitem>
|
||||
<para>VIDIOC_SUBDEV_G_EDID, VIDIOC_SUBDEV_S_EDID</para>
|
||||
<para>VIDIOC_G_EDID, VIDIOC_S_EDID</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
@ -56,12 +56,20 @@
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
<para>These ioctls can be used to get or set an EDID associated with an input pad
|
||||
from a receiver or an output pad of a transmitter subdevice.</para>
|
||||
<para>These ioctls can be used to get or set an EDID associated with an input
|
||||
from a receiver or an output of a transmitter device. They can be
|
||||
used with subdevice nodes (/dev/v4l-subdevX) or with video nodes (/dev/videoX).</para>
|
||||
|
||||
<para>When used with video nodes the <structfield>pad</structfield> field represents the
|
||||
input (for video capture devices) or output (for video output devices) index as
|
||||
is returned by &VIDIOC-ENUMINPUT; and &VIDIOC-ENUMOUTPUT; respectively. When used
|
||||
with subdevice nodes the <structfield>pad</structfield> field represents the
|
||||
input or output pad of the subdevice. If there is no EDID support for the given
|
||||
<structfield>pad</structfield> value, then the &EINVAL; will be returned.</para>
|
||||
|
||||
<para>To get the EDID data the application has to fill in the <structfield>pad</structfield>,
|
||||
<structfield>start_block</structfield>, <structfield>blocks</structfield> and <structfield>edid</structfield>
|
||||
fields and call <constant>VIDIOC_SUBDEV_G_EDID</constant>. The current EDID from block
|
||||
fields and call <constant>VIDIOC_G_EDID</constant>. The current EDID from block
|
||||
<structfield>start_block</structfield> and of size <structfield>blocks</structfield>
|
||||
will be placed in the memory <structfield>edid</structfield> points to. The <structfield>edid</structfield>
|
||||
pointer must point to memory at least <structfield>blocks</structfield> * 128 bytes
|
||||
@ -91,15 +99,17 @@
|
||||
data in some way. In any case, the end result is the same: the EDID is no longer available.
|
||||
</para>
|
||||
|
||||
<table pgwide="1" frame="none" id="v4l2-subdev-edid">
|
||||
<title>struct <structname>v4l2_subdev_edid</structname></title>
|
||||
<table pgwide="1" frame="none" id="v4l2-edid">
|
||||
<title>struct <structname>v4l2_edid</structname></title>
|
||||
<tgroup cols="3">
|
||||
&cs-str;
|
||||
<tbody valign="top">
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>pad</structfield></entry>
|
||||
<entry>Pad for which to get/set the EDID blocks.</entry>
|
||||
<entry>Pad for which to get/set the EDID blocks. When used with a video device
|
||||
node the pad represents the input or output index as returned by
|
||||
&VIDIOC-ENUMINPUT; and &VIDIOC-ENUMOUTPUT; respectively.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
@ -327,7 +327,12 @@ These controls are described in <xref
|
||||
These controls are described in <xref
|
||||
linkend="fm-rx-controls" />.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><constant>V4L2_CTRL_CLASS_RF_TUNER</constant></entry>
|
||||
<entry>0xa20000</entry>
|
||||
<entry>The class containing RF tuner controls.
|
||||
These controls are described in <xref linkend="rf-tuner-controls" />.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
@ -169,6 +169,13 @@ capture and output devices.</entry>
|
||||
<entry>Sliced VBI capture or output parameters. See
|
||||
<xref linkend="sliced" /> for details. Used by sliced VBI
|
||||
capture and output devices.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>&v4l2-sdr-format;</entry>
|
||||
<entry><structfield>sdr</structfield></entry>
|
||||
<entry>Definition of a data format, see
|
||||
<xref linkend="pixfmt" />, used by SDR capture devices.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry></entry>
|
||||
|
@ -109,9 +109,10 @@ See <xref linkend="v4l2-tuner-type" /></entry>
|
||||
<entry>__u32</entry>
|
||||
<entry><structfield>frequency</structfield></entry>
|
||||
<entry>Tuning frequency in units of 62.5 kHz, or if the
|
||||
&v4l2-tuner; or &v4l2-modulator; <structfield>capabilities</structfield> flag
|
||||
&v4l2-tuner; or &v4l2-modulator; <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
|
||||
Hz.</entry>
|
||||
Hz. A 1 Hz unit is used when the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
@ -113,7 +113,8 @@ change for example with the current video standard.</entry>
|
||||
<entry>The lowest tunable frequency in units of 62.5
|
||||
KHz, or if the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
|
||||
Hz.</entry>
|
||||
Hz, or if the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
@ -121,7 +122,8 @@ Hz.</entry>
|
||||
<entry>The highest tunable frequency in units of 62.5
|
||||
KHz, or if the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
|
||||
Hz.</entry>
|
||||
Hz, or if the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>__u32</entry>
|
||||
|
@ -134,7 +134,9 @@ the structure refers to a radio tuner the
|
||||
<entry spanname="hspan">The lowest tunable frequency in
|
||||
units of 62.5 kHz, or if the <structfield>capability</structfield>
|
||||
flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
|
||||
Hz. If multiple frequency bands are supported, then
|
||||
Hz, or if the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.
|
||||
If multiple frequency bands are supported, then
|
||||
<structfield>rangelow</structfield> is the lowest frequency
|
||||
of all the frequency bands.</entry>
|
||||
</row>
|
||||
@ -144,7 +146,9 @@ of all the frequency bands.</entry>
|
||||
<entry spanname="hspan">The highest tunable frequency in
|
||||
units of 62.5 kHz, or if the <structfield>capability</structfield>
|
||||
flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
|
||||
Hz. If multiple frequency bands are supported, then
|
||||
Hz, or if the <structfield>capability</structfield> flag
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.
|
||||
If multiple frequency bands are supported, then
|
||||
<structfield>rangehigh</structfield> is the highest frequency
|
||||
of all the frequency bands.</entry>
|
||||
</row>
|
||||
@ -270,7 +274,7 @@ applications must set the array to zero.</entry>
|
||||
<entry><constant>V4L2_TUNER_CAP_LOW</constant></entry>
|
||||
<entry>0x0001</entry>
|
||||
<entry>When set, tuning frequencies are expressed in units of
|
||||
62.5 Hz, otherwise in units of 62.5 kHz.</entry>
|
||||
62.5 Hz instead of 62.5 kHz.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_TUNER_CAP_NORM</constant></entry>
|
||||
@ -360,6 +364,11 @@ radio tuners.</entry>
|
||||
<entry>The range to search when using the hardware seek functionality
|
||||
is programmable, see &VIDIOC-S-HW-FREQ-SEEK; for details.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_TUNER_CAP_1HZ</constant></entry>
|
||||
<entry>0x1000</entry>
|
||||
<entry>When set, tuning frequencies are expressed in units of 1 Hz instead of 62.5 kHz.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
@ -294,6 +294,12 @@ interface. For more information on audio inputs and outputs see <xref
|
||||
emit RF-modulated video/audio signals. For more information about
|
||||
modulator programming see
|
||||
<xref linkend="tuner" />.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CAP_SDR_CAPTURE</constant></entry>
|
||||
<entry>0x00100000</entry>
|
||||
<entry>The device supports the
|
||||
<link linkend="sdr">SDR Capture</link> interface.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><constant>V4L2_CAP_READWRITE</constant></entry>
|
||||
|
@ -121,7 +121,9 @@ field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
|
||||
<entry>If non-zero, the lowest tunable frequency of the band to
|
||||
search in units of 62.5 kHz, or if the &v4l2-tuner;
|
||||
<structfield>capability</structfield> field has the
|
||||
<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz.
|
||||
<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz or if the &v4l2-tuner;
|
||||
<structfield>capability</structfield> field has the
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> flag set, in units of 1 Hz.
|
||||
If <structfield>rangelow</structfield> is zero a reasonable default value
|
||||
is used.</entry>
|
||||
</row>
|
||||
@ -131,7 +133,9 @@ is used.</entry>
|
||||
<entry>If non-zero, the highest tunable frequency of the band to
|
||||
search in units of 62.5 kHz, or if the &v4l2-tuner;
|
||||
<structfield>capability</structfield> field has the
|
||||
<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz.
|
||||
<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz or if the &v4l2-tuner;
|
||||
<structfield>capability</structfield> field has the
|
||||
<constant>V4L2_TUNER_CAP_1HZ</constant> flag set, in units of 1 Hz.
|
||||
If <structfield>rangehigh</structfield> is zero a reasonable default value
|
||||
is used.</entry>
|
||||
</row>
|
||||
|
@ -52,16 +52,24 @@
|
||||
<para>The <constant>VIDIOC_STREAMON</constant> and
|
||||
<constant>VIDIOC_STREAMOFF</constant> ioctl start and stop the capture
|
||||
or output process during streaming (<link linkend="mmap">memory
|
||||
mapping</link> or <link linkend="userp">user pointer</link>) I/O.</para>
|
||||
mapping</link>, <link linkend="userp">user pointer</link> or
|
||||
<link linkend="dmabuf">DMABUF</link>) I/O.</para>
|
||||
|
||||
<para>Specifically the capture hardware is disabled and no input
|
||||
<para>Capture hardware is disabled and no input
|
||||
buffers are filled (if there are any empty buffers in the incoming
|
||||
queue) until <constant>VIDIOC_STREAMON</constant> has been called.
|
||||
Accordingly the output hardware is disabled, no video signal is
|
||||
Output hardware is disabled and no video signal is
|
||||
produced until <constant>VIDIOC_STREAMON</constant> has been called.
|
||||
The ioctl will succeed when at least one output buffer is in the
|
||||
incoming queue.</para>
|
||||
|
||||
<para>Memory-to-memory devices will not start until
|
||||
<constant>VIDIOC_STREAMON</constant> has been called for both the capture
|
||||
and output stream types.</para>
|
||||
|
||||
<para>If <constant>VIDIOC_STREAMON</constant> fails then any already
|
||||
queued buffers will remain queued.</para>
|
||||
|
||||
<para>The <constant>VIDIOC_STREAMOFF</constant> ioctl, apart of
|
||||
aborting or finishing any DMA in progress, unlocks any user pointer
|
||||
buffers locked in physical memory, and it removes all buffers from the
|
||||
@ -70,14 +78,22 @@ dequeued yet will be lost, likewise all images enqueued for output but
|
||||
not transmitted yet. I/O returns to the same state as after calling
|
||||
&VIDIOC-REQBUFS; and can be restarted accordingly.</para>
|
||||
|
||||
<para>If buffers have been queued with &VIDIOC-QBUF; and
|
||||
<constant>VIDIOC_STREAMOFF</constant> is called without ever having
|
||||
called <constant>VIDIOC_STREAMON</constant>, then those queued buffers
|
||||
will also be removed from the incoming queue and all are returned to the
|
||||
same state as after calling &VIDIOC-REQBUFS; and can be restarted
|
||||
accordingly.</para>
|
||||
|
||||
<para>Both ioctls take a pointer to an integer, the desired buffer or
|
||||
stream type. This is the same as &v4l2-requestbuffers;
|
||||
<structfield>type</structfield>.</para>
|
||||
|
||||
<para>If <constant>VIDIOC_STREAMON</constant> is called when streaming
|
||||
is already in progress, or if <constant>VIDIOC_STREAMOFF</constant> is called
|
||||
when streaming is already stopped, then the ioctl does nothing and 0 is
|
||||
returned.</para>
|
||||
when streaming is already stopped, then 0 is returned. Nothing happens in the
|
||||
case of <constant>VIDIOC_STREAMON</constant>, but <constant>VIDIOC_STREAMOFF</constant>
|
||||
will return queued buffers to their starting state as mentioned above.</para>
|
||||
|
||||
<para>Note that applications can be preempted for unknown periods right
|
||||
before or after the <constant>VIDIOC_STREAMON</constant> or
|
||||
@ -93,7 +109,7 @@ synchronize with other events.</para>
|
||||
<varlistentry>
|
||||
<term><errorcode>EINVAL</errorcode></term>
|
||||
<listitem>
|
||||
<para>The buffer<structfield>type</structfield> is not supported,
|
||||
<para>The buffer <structfield>type</structfield> is not supported,
|
||||
or no buffers have been allocated (memory mapping) or enqueued
|
||||
(output) yet.</para>
|
||||
</listitem>
|
||||
|
@ -34,22 +34,20 @@
|
||||
|
||||
<book id="media_api">
|
||||
<bookinfo>
|
||||
<title>LINUX MEDIA INFRASTRUCTURE API</title>
|
||||
<title>LINUX MEDIA INFRASTRUCTURE API</title>
|
||||
|
||||
<copyright>
|
||||
<year>2009-2012</year>
|
||||
<holder>LinuxTV Developers</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
|
||||
<para>Permission is granted to copy, distribute and/or modify
|
||||
this document under the terms of the GNU Free Documentation License,
|
||||
Version 1.1 or any later version published by the Free Software
|
||||
Foundation. A copy of the license is included in the chapter entitled
|
||||
"GNU Free Documentation License"</para>
|
||||
</legalnotice>
|
||||
<copyright>
|
||||
<year>2009-2014</year>
|
||||
<holder>LinuxTV Developers</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>Permission is granted to copy, distribute and/or modify
|
||||
this document under the terms of the GNU Free Documentation License,
|
||||
Version 1.1 or any later version published by the Free Software
|
||||
Foundation. A copy of the license is included in the chapter entitled
|
||||
"GNU Free Documentation License"</para>
|
||||
</legalnotice>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc> <!-- autogenerated -->
|
||||
@ -60,10 +58,11 @@ Foundation. A copy of the license is included in the chapter entitled
|
||||
<para>This document covers the Linux Kernel to Userspace API's used by
|
||||
video and radio streaming devices, including video cameras,
|
||||
analog and digital TV receiver cards, AM/FM receiver cards,
|
||||
streaming capture devices.</para>
|
||||
streaming capture and output devices, codec devices and remote
|
||||
controllers.</para>
|
||||
<para>It is divided into four parts.</para>
|
||||
<para>The first part covers radio, capture,
|
||||
cameras and analog TV devices.</para>
|
||||
<para>The first part covers radio, video capture and output,
|
||||
cameras, analog TV devices and codecs.</para>
|
||||
<para>The second part covers the
|
||||
API used for digital TV and Internet reception via one of the
|
||||
several digital tv standards. While it is called as DVB API,
|
||||
@ -75,55 +74,14 @@ Foundation. A copy of the license is included in the chapter entitled
|
||||
<para>For additional information and for the latest development code,
|
||||
see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
|
||||
<para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
|
||||
|
||||
</preface>
|
||||
|
||||
<part id="v4l2spec">
|
||||
&sub-v4l2;
|
||||
</part>
|
||||
<part id="dvbapi">
|
||||
&sub-dvbapi;
|
||||
</part>
|
||||
<part id="v4ldvb_common">
|
||||
<partinfo>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Mauro</firstname>
|
||||
<surname>Chehab</surname>
|
||||
<othername role="mi">Carvalho</othername>
|
||||
<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
|
||||
<contrib>Initial version.</contrib>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<copyright>
|
||||
<year>2009-2012</year>
|
||||
<holder>Mauro Carvalho Chehab</holder>
|
||||
</copyright>
|
||||
|
||||
<revhistory>
|
||||
<!-- Put document revisions here, newest first. -->
|
||||
<revision>
|
||||
<revnumber>1.0.0</revnumber>
|
||||
<date>2009-09-06</date>
|
||||
<authorinitials>mcc</authorinitials>
|
||||
<revremark>Initial revision</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
</partinfo>
|
||||
|
||||
<title>Remote Controller API</title>
|
||||
<chapter id="remote_controllers">
|
||||
&sub-remote_controllers;
|
||||
</chapter>
|
||||
</part>
|
||||
<part id="media_common">
|
||||
&sub-media-controller;
|
||||
</part>
|
||||
|
||||
<chapter id="gen_errors">
|
||||
&sub-gen-errors;
|
||||
</chapter>
|
||||
<part id="v4l2spec">&sub-v4l2;</part>
|
||||
<part id="dvbapi">&sub-dvbapi;</part>
|
||||
<part id="remotes">&sub-remote_controllers;</part>
|
||||
<part id="media_common">&sub-media-controller;</part>
|
||||
|
||||
<chapter id="gen_errors">&sub-gen-errors;</chapter>
|
||||
|
||||
&sub-fdl-appendix;
|
||||
|
||||
|
@ -1494,10 +1494,17 @@ Your cooperation is appreciated.
|
||||
64 = /dev/radio0 Radio device
|
||||
...
|
||||
127 = /dev/radio63 Radio device
|
||||
128 = /dev/swradio0 Software Defined Radio device
|
||||
...
|
||||
191 = /dev/swradio63 Software Defined Radio device
|
||||
224 = /dev/vbi0 Vertical blank interrupt
|
||||
...
|
||||
255 = /dev/vbi31 Vertical blank interrupt
|
||||
|
||||
Minor numbers are allocated dynamically unless
|
||||
CONFIG_VIDEO_FIXED_MINOR_RANGES (default n)
|
||||
configuration option is set.
|
||||
|
||||
81 block I2O hard disk
|
||||
0 = /dev/i2o/hdq 17th I2O hard disk, whole disk
|
||||
16 = /dev/i2o/hdr 18th I2O hard disk, whole disk
|
||||
|
34
Documentation/devicetree/bindings/media/img-ir-rev1.txt
Normal file
34
Documentation/devicetree/bindings/media/img-ir-rev1.txt
Normal file
@ -0,0 +1,34 @@
|
||||
* ImgTec Infrared (IR) decoder version 1
|
||||
|
||||
This binding is for Imagination Technologies' Infrared decoder block,
|
||||
specifically major revision 1.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "img,ir-rev1"
|
||||
- reg: Physical base address of the controller and length of
|
||||
memory mapped region.
|
||||
- interrupts: The interrupt specifier to the cpu.
|
||||
|
||||
Optional properties:
|
||||
- clocks: List of clock specifiers as described in standard
|
||||
clock bindings.
|
||||
Up to 3 clocks may be specified in the following order:
|
||||
1st: Core clock (defaults to 32.768KHz if omitted).
|
||||
2nd: System side (fast) clock.
|
||||
3rd: Power modulation clock.
|
||||
- clock-names: List of clock names corresponding to the clocks
|
||||
specified in the clocks property.
|
||||
Accepted clock names are:
|
||||
"core": Core clock.
|
||||
"sys": System clock.
|
||||
"mod": Power modulation clock.
|
||||
|
||||
Example:
|
||||
|
||||
ir@02006200 {
|
||||
compatible = "img,ir-rev1";
|
||||
reg = <0x02006200 0x100>;
|
||||
interrupts = <29 4>;
|
||||
clocks = <&clk_32khz>;
|
||||
clock-names = "core";
|
||||
};
|
@ -28,8 +28,8 @@ use IO::Handle;
|
||||
"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
|
||||
"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
|
||||
"lme2510c_s7395_old", "drxk", "drxk_terratec_h5",
|
||||
"drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137",
|
||||
"drxk_pctv", "drxk_terratec_htc_stick", "sms1xxx_hcw");
|
||||
"drxk_hauppauge_hvr930c", "tda10071", "it9135", "drxk_pctv",
|
||||
"drxk_terratec_htc_stick", "sms1xxx_hcw");
|
||||
|
||||
# Check args
|
||||
syntax() if (scalar(@ARGV) != 1);
|
||||
@ -727,24 +727,6 @@ sub it9135 {
|
||||
"$fwfile1 $fwfile2"
|
||||
}
|
||||
|
||||
sub it9137 {
|
||||
my $url = "http://kworld.server261.com/kworld/CD/ITE_TiVme/V1.00/";
|
||||
my $zipfile = "Driver_V10.323.1.0412.100412.zip";
|
||||
my $hash = "79b597dc648698ed6820845c0c9d0d37";
|
||||
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0);
|
||||
my $drvfile = "Driver_V10.323.1.0412.100412/Data/x86/IT9135BDA.sys";
|
||||
my $fwfile = "dvb-usb-it9137-01.fw";
|
||||
|
||||
checkstandard();
|
||||
|
||||
wgetfile($zipfile, $url . $zipfile);
|
||||
verify($zipfile, $hash);
|
||||
unzip($zipfile, $tmpdir);
|
||||
extract("$tmpdir/$drvfile", 69632, 5731, "$fwfile");
|
||||
|
||||
"$fwfile"
|
||||
}
|
||||
|
||||
sub tda10071 {
|
||||
my $sourcefile = "PCTV_460e_reference.zip";
|
||||
my $url = "ftp://ftp.pctvsystems.com/TV/driver/PCTV%2070e%2080e%20100e%20320e%20330e%20800e/";
|
||||
|
@ -1,9 +0,0 @@
|
||||
To extract firmware for Kworld UB499-2T (id 1b80:e409) you need to copy the
|
||||
following file(s) to this directory.
|
||||
|
||||
IT9135BDA.sys Dated Mon 22 Mar 2010 02:20:08 GMT
|
||||
|
||||
extract using dd
|
||||
dd if=IT9135BDA.sys ibs=1 skip=69632 count=5731 of=dvb-usb-it9137-01.fw
|
||||
|
||||
copy to default firmware location.
|
@ -6,7 +6,7 @@ Written by Doug Thompson <dougthompson@xmission.com>
|
||||
7 Dec 2005
|
||||
17 Jul 2007 Updated
|
||||
|
||||
(c) Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
(c) Mauro Carvalho Chehab
|
||||
05 Aug 2009 Nehalem interface
|
||||
|
||||
EDAC is maintained and written by:
|
||||
|
@ -163,3 +163,4 @@
|
||||
162 -> Adlink MPG24
|
||||
163 -> Bt848 Capture 14MHz
|
||||
164 -> CyberVision CV06 (SV)
|
||||
165 -> Kworld V-Stream Xpert TV PVR878
|
||||
|
@ -31,10 +31,13 @@
|
||||
30 -> NetUP Dual DVB-T/C-CI RF [1b55:e2e4]
|
||||
31 -> Leadtek Winfast PxDVR3200 H XC4000 [107d:6f39]
|
||||
32 -> MPX-885
|
||||
33 -> Mygica X8507 [14f1:8502]
|
||||
33 -> Mygica X8502/X8507 ISDB-T [14f1:8502]
|
||||
34 -> TerraTec Cinergy T PCIe Dual [153b:117e]
|
||||
35 -> TeVii S471 [d471:9022]
|
||||
36 -> Hauppauge WinTV-HVR1255 [0070:2259]
|
||||
37 -> Prof Revolution DVB-S2 8000 [8000:3034]
|
||||
38 -> Hauppauge WinTV-HVR4400 [0070:c108,0070:c138,0070:c12a,0070:c1f8]
|
||||
39 -> AVerTV Hybrid Express Slim HC81R [1461:d939]
|
||||
40 -> TurboSight TBS 6981 [6981:8888]
|
||||
41 -> TurboSight TBS 6980 [6980:8888]
|
||||
42 -> Leadtek Winfast PxPVR2200 [107d:6f21]
|
||||
|
@ -57,6 +57,7 @@
|
||||
56 -> Pinnacle Hybrid Pro (330e) (em2882) [2304:0226]
|
||||
57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316]
|
||||
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
|
||||
59 -> Pinnacle PCTV HD Mini (em2874) [2304:023f]
|
||||
60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f]
|
||||
61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840)
|
||||
62 -> Gadmei TVR200 (em2820/em2840)
|
||||
@ -86,3 +87,8 @@
|
||||
86 -> PCTV QuatroStick nano (520e) (em2884) [2013:0251]
|
||||
87 -> Terratec Cinergy HTC USB XS (em2884) [0ccd:008e,0ccd:00ac]
|
||||
88 -> C3 Tech Digital Duo HDTV/SDTV USB (em2884) [1b80:e755]
|
||||
89 -> Delock 61959 (em2874) [1b80:e1cc]
|
||||
90 -> KWorld USB ATSC TV Stick UB435-Q V2 (em2874) [1b80:e346]
|
||||
91 -> SpeedLink Vicious And Devine Laplace webcam (em2765) [1ae7:9003,1ae7:9004]
|
||||
92 -> PCTV DVB-S2 Stick (461e) (em28178)
|
||||
93 -> KWorld USB ATSC TV Stick UB435-Q V3 (em2874) [1b80:e34c]
|
||||
|
@ -55,6 +55,7 @@ zc3xx 0458:700f Genius VideoCam Web V2
|
||||
sonixj 0458:7025 Genius Eye 311Q
|
||||
sn9c20x 0458:7029 Genius Look 320s
|
||||
sonixj 0458:702e Genius Slim 310 NB
|
||||
sn9c20x 0458:7045 Genius Look 1320 V2
|
||||
sn9c20x 0458:704a Genius Slim 1320
|
||||
sn9c20x 0458:704c Genius i-Look 1321
|
||||
sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650)
|
||||
|
@ -34,6 +34,10 @@ So this framework sets up the basic building blocks that all drivers
|
||||
need and this same framework should make it much easier to refactor
|
||||
common code into utility functions shared by all drivers.
|
||||
|
||||
A good example to look at as a reference is the v4l2-pci-skeleton.c
|
||||
source that is available in this directory. It is a skeleton driver for
|
||||
a PCI capture card, and demonstrates how to use the V4L2 driver
|
||||
framework. It can be used as a template for real PCI video capture driver.
|
||||
|
||||
Structure of a driver
|
||||
---------------------
|
||||
@ -768,6 +772,7 @@ types exist:
|
||||
VFL_TYPE_GRABBER: videoX for video input/output devices
|
||||
VFL_TYPE_VBI: vbiX for vertical blank data (i.e. closed captions, teletext)
|
||||
VFL_TYPE_RADIO: radioX for radio tuners
|
||||
VFL_TYPE_SDR: swradioX for Software Defined Radio tuners
|
||||
|
||||
The last argument gives you a certain amount of control over the device
|
||||
device node number used (i.e. the X in videoX). Normally you will pass -1
|
||||
|
913
Documentation/video4linux/v4l2-pci-skeleton.c
Normal file
913
Documentation/video4linux/v4l2-pci-skeleton.c
Normal file
@ -0,0 +1,913 @@
|
||||
/*
|
||||
* This is a V4L2 PCI Skeleton Driver. It gives an initial skeleton source
|
||||
* for use with other PCI drivers.
|
||||
*
|
||||
* This skeleton PCI driver assumes that the card has an S-Video connector as
|
||||
* input 0 and an HDMI connector as input 1.
|
||||
*
|
||||
* Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* This program is free software; you may 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/v4l2-dv-timings.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-dev.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-dv-timings.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/videobuf2-dma-contig.h>
|
||||
|
||||
MODULE_DESCRIPTION("V4L2 PCI Skeleton Driver");
|
||||
MODULE_AUTHOR("Hans Verkuil");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DEVICE_TABLE(pci, skeleton_pci_tbl);
|
||||
|
||||
/**
|
||||
* struct skeleton - All internal data for one instance of device
|
||||
* @pdev: PCI device
|
||||
* @v4l2_dev: top-level v4l2 device struct
|
||||
* @vdev: video node structure
|
||||
* @ctrl_handler: control handler structure
|
||||
* @lock: ioctl serialization mutex
|
||||
* @std: current SDTV standard
|
||||
* @timings: current HDTV timings
|
||||
* @format: current pix format
|
||||
* @input: current video input (0 = SDTV, 1 = HDTV)
|
||||
* @queue: vb2 video capture queue
|
||||
* @alloc_ctx: vb2 contiguous DMA context
|
||||
* @qlock: spinlock controlling access to buf_list and sequence
|
||||
* @buf_list: list of buffers queued for DMA
|
||||
* @sequence: frame sequence counter
|
||||
*/
|
||||
struct skeleton {
|
||||
struct pci_dev *pdev;
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct video_device vdev;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
struct mutex lock;
|
||||
v4l2_std_id std;
|
||||
struct v4l2_dv_timings timings;
|
||||
struct v4l2_pix_format format;
|
||||
unsigned input;
|
||||
|
||||
struct vb2_queue queue;
|
||||
struct vb2_alloc_ctx *alloc_ctx;
|
||||
|
||||
spinlock_t qlock;
|
||||
struct list_head buf_list;
|
||||
unsigned int sequence;
|
||||
};
|
||||
|
||||
struct skel_buffer {
|
||||
struct vb2_buffer vb;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static inline struct skel_buffer *to_skel_buffer(struct vb2_buffer *vb2)
|
||||
{
|
||||
return container_of(vb2, struct skel_buffer, vb);
|
||||
}
|
||||
|
||||
static const struct pci_device_id skeleton_pci_tbl[] = {
|
||||
/* { PCI_DEVICE(PCI_VENDOR_ID_, PCI_DEVICE_ID_) }, */
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
/*
|
||||
* HDTV: this structure has the capabilities of the HDTV receiver.
|
||||
* It is used to constrain the huge list of possible formats based
|
||||
* upon the hardware capabilities.
|
||||
*/
|
||||
static const struct v4l2_dv_timings_cap skel_timings_cap = {
|
||||
.type = V4L2_DV_BT_656_1120,
|
||||
/* keep this initialization for compatibility with GCC < 4.4.6 */
|
||||
.reserved = { 0 },
|
||||
V4L2_INIT_BT_TIMINGS(
|
||||
720, 1920, /* min/max width */
|
||||
480, 1080, /* min/max height */
|
||||
27000000, 74250000, /* min/max pixelclock*/
|
||||
V4L2_DV_BT_STD_CEA861, /* Supported standards */
|
||||
/* capabilities */
|
||||
V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE
|
||||
)
|
||||
};
|
||||
|
||||
/*
|
||||
* Supported SDTV standards. This does the same job as skel_timings_cap, but
|
||||
* for standard TV formats.
|
||||
*/
|
||||
#define SKEL_TVNORMS V4L2_STD_ALL
|
||||
|
||||
/*
|
||||
* Interrupt handler: typically interrupts happen after a new frame has been
|
||||
* captured. It is the job of the handler to remove the new frame from the
|
||||
* internal list and give it back to the vb2 framework, updating the sequence
|
||||
* counter and timestamp at the same time.
|
||||
*/
|
||||
static irqreturn_t skeleton_irq(int irq, void *dev_id)
|
||||
{
|
||||
#ifdef TODO
|
||||
struct skeleton *skel = dev_id;
|
||||
|
||||
/* handle interrupt */
|
||||
|
||||
/* Once a new frame has been captured, mark it as done like this: */
|
||||
if (captured_new_frame) {
|
||||
...
|
||||
spin_lock(&skel->qlock);
|
||||
list_del(&new_buf->list);
|
||||
spin_unlock(&skel->qlock);
|
||||
new_buf->vb.v4l2_buf.sequence = skel->sequence++;
|
||||
v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp);
|
||||
vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE);
|
||||
}
|
||||
#endif
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the constraints of the queue: besides setting the number of planes
|
||||
* per buffer and the size and allocation context of each plane, it also
|
||||
* checks if sufficient buffers have been allocated. Usually 3 is a good
|
||||
* minimum number: many DMA engines need a minimum of 2 buffers in the
|
||||
* queue and you need to have another available for userspace processing.
|
||||
*/
|
||||
static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
{
|
||||
struct skeleton *skel = vb2_get_drv_priv(vq);
|
||||
|
||||
if (vq->num_buffers + *nbuffers < 3)
|
||||
*nbuffers = 3 - vq->num_buffers;
|
||||
|
||||
if (fmt && fmt->fmt.pix.sizeimage < skel->format.sizeimage)
|
||||
return -EINVAL;
|
||||
*nplanes = 1;
|
||||
sizes[0] = fmt ? fmt->fmt.pix.sizeimage : skel->format.sizeimage;
|
||||
alloc_ctxs[0] = skel->alloc_ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the buffer for queueing to the DMA engine: check and set the
|
||||
* payload size and fill in the field. Note: if the format's field is
|
||||
* V4L2_FIELD_ALTERNATE, then vb->v4l2_buf.field should be set in the
|
||||
* interrupt handler since that's usually where you know if the TOP or
|
||||
* BOTTOM field has been captured.
|
||||
*/
|
||||
static int buffer_prepare(struct vb2_buffer *vb)
|
||||
{
|
||||
struct skeleton *skel = vb2_get_drv_priv(vb->vb2_queue);
|
||||
unsigned long size = skel->format.sizeimage;
|
||||
|
||||
if (vb2_plane_size(vb, 0) < size) {
|
||||
dev_err(&skel->pdev->dev, "buffer too small (%lu < %lu)\n",
|
||||
vb2_plane_size(vb, 0), size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vb2_set_plane_payload(vb, 0, size);
|
||||
vb->v4l2_buf.field = skel->format.field;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue this buffer to the DMA engine.
|
||||
*/
|
||||
static void buffer_queue(struct vb2_buffer *vb)
|
||||
{
|
||||
struct skeleton *skel = vb2_get_drv_priv(vb->vb2_queue);
|
||||
struct skel_buffer *buf = to_skel_buffer(vb);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&skel->qlock, flags);
|
||||
list_add_tail(&buf->list, &skel->buf_list);
|
||||
|
||||
/* TODO: Update any DMA pointers if necessary */
|
||||
|
||||
spin_unlock_irqrestore(&skel->qlock, flags);
|
||||
}
|
||||
|
||||
static void return_all_buffers(struct skeleton *skel,
|
||||
enum vb2_buffer_state state)
|
||||
{
|
||||
struct skel_buffer *buf, *node;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&skel->qlock, flags);
|
||||
list_for_each_entry_safe(buf, node, &skel->buf_list, list) {
|
||||
vb2_buffer_done(&buf->vb, state);
|
||||
list_del(&buf->list);
|
||||
}
|
||||
spin_unlock_irqrestore(&skel->qlock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start streaming. First check if the minimum number of buffers have been
|
||||
* queued. If not, then return -ENOBUFS and the vb2 framework will call
|
||||
* this function again the next time a buffer has been queued until enough
|
||||
* buffers are available to actually start the DMA engine.
|
||||
*/
|
||||
static int start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||
{
|
||||
struct skeleton *skel = vb2_get_drv_priv(vq);
|
||||
int ret = 0;
|
||||
|
||||
skel->sequence = 0;
|
||||
|
||||
/* TODO: start DMA */
|
||||
|
||||
if (ret) {
|
||||
/*
|
||||
* In case of an error, return all active buffers to the
|
||||
* QUEUED state
|
||||
*/
|
||||
return_all_buffers(skel, VB2_BUF_STATE_QUEUED);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
|
||||
* and passed on to the vb2 framework marked as STATE_ERROR.
|
||||
*/
|
||||
static int stop_streaming(struct vb2_queue *vq)
|
||||
{
|
||||
struct skeleton *skel = vb2_get_drv_priv(vq);
|
||||
|
||||
/* TODO: stop DMA */
|
||||
|
||||
/* Release all active buffers */
|
||||
return_all_buffers(skel, VB2_BUF_STATE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The vb2 queue ops. Note that since q->lock is set we can use the standard
|
||||
* vb2_ops_wait_prepare/finish helper functions. If q->lock would be NULL,
|
||||
* then this driver would have to provide these ops.
|
||||
*/
|
||||
static struct vb2_ops skel_qops = {
|
||||
.queue_setup = queue_setup,
|
||||
.buf_prepare = buffer_prepare,
|
||||
.buf_queue = buffer_queue,
|
||||
.start_streaming = start_streaming,
|
||||
.stop_streaming = stop_streaming,
|
||||
.wait_prepare = vb2_ops_wait_prepare,
|
||||
.wait_finish = vb2_ops_wait_finish,
|
||||
};
|
||||
|
||||
/*
|
||||
* Required ioctl querycap. Note that the version field is prefilled with
|
||||
* the version of the kernel.
|
||||
*/
|
||||
static int skeleton_querycap(struct file *file, void *priv,
|
||||
struct v4l2_capability *cap)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
|
||||
strlcpy(cap->card, "V4L2 PCI Skeleton", sizeof(cap->card));
|
||||
snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
|
||||
pci_name(skel->pdev));
|
||||
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING;
|
||||
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to check and correct struct v4l2_pix_format. It's used
|
||||
* not only in VIDIOC_TRY/S_FMT, but also elsewhere if changes to the SDTV
|
||||
* standard, HDTV timings or the video input would require updating the
|
||||
* current format.
|
||||
*/
|
||||
static void skeleton_fill_pix_format(struct skeleton *skel,
|
||||
struct v4l2_pix_format *pix)
|
||||
{
|
||||
pix->pixelformat = V4L2_PIX_FMT_YUYV;
|
||||
if (skel->input == 0) {
|
||||
/* S-Video input */
|
||||
pix->width = 720;
|
||||
pix->height = (skel->std & V4L2_STD_525_60) ? 480 : 576;
|
||||
pix->field = V4L2_FIELD_INTERLACED;
|
||||
pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
} else {
|
||||
/* HDMI input */
|
||||
pix->width = skel->timings.bt.width;
|
||||
pix->height = skel->timings.bt.height;
|
||||
if (skel->timings.bt.interlaced)
|
||||
pix->field = V4L2_FIELD_INTERLACED;
|
||||
else
|
||||
pix->field = V4L2_FIELD_NONE;
|
||||
pix->colorspace = V4L2_COLORSPACE_REC709;
|
||||
}
|
||||
|
||||
/*
|
||||
* The YUYV format is four bytes for every two pixels, so bytesperline
|
||||
* is width * 2.
|
||||
*/
|
||||
pix->bytesperline = pix->width * 2;
|
||||
pix->sizeimage = pix->bytesperline * pix->height;
|
||||
pix->priv = 0;
|
||||
}
|
||||
|
||||
static int skeleton_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
struct v4l2_pix_format *pix = &f->fmt.pix;
|
||||
|
||||
/*
|
||||
* Due to historical reasons providing try_fmt with an unsupported
|
||||
* pixelformat will return -EINVAL for video receivers. Webcam drivers,
|
||||
* however, will silently correct the pixelformat. Some video capture
|
||||
* applications rely on this behavior...
|
||||
*/
|
||||
if (pix->pixelformat != V4L2_PIX_FMT_YUYV)
|
||||
return -EINVAL;
|
||||
skeleton_fill_pix_format(skel, pix);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_s_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
ret = skeleton_try_fmt_vid_cap(file, priv, f);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* It is not allowed to change the format while buffers for use with
|
||||
* streaming have already been allocated.
|
||||
*/
|
||||
if (vb2_is_busy(&skel->queue))
|
||||
return -EBUSY;
|
||||
|
||||
/* TODO: change format */
|
||||
skel->format = f->fmt.pix;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_g_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
f->fmt.pix = skel->format;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_enum_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_fmtdesc *f)
|
||||
{
|
||||
if (f->index != 0)
|
||||
return -EINVAL;
|
||||
|
||||
strlcpy(f->description, "4:2:2, packed, YUYV", sizeof(f->description));
|
||||
f->pixelformat = V4L2_PIX_FMT_YUYV;
|
||||
f->flags = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_s_std(struct file *file, void *priv, v4l2_std_id std)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
/* S_STD is not supported on the HDMI input */
|
||||
if (skel->input)
|
||||
return -ENODATA;
|
||||
|
||||
/*
|
||||
* No change, so just return. Some applications call S_STD again after
|
||||
* the buffers for streaming have been set up, so we have to allow for
|
||||
* this behavior.
|
||||
*/
|
||||
if (std == skel->std)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Changing the standard implies a format change, which is not allowed
|
||||
* while buffers for use with streaming have already been allocated.
|
||||
*/
|
||||
if (vb2_is_busy(&skel->queue))
|
||||
return -EBUSY;
|
||||
|
||||
/* TODO: handle changing std */
|
||||
|
||||
skel->std = std;
|
||||
|
||||
/* Update the internal format */
|
||||
skeleton_fill_pix_format(skel, &skel->format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_g_std(struct file *file, void *priv, v4l2_std_id *std)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
/* G_STD is not supported on the HDMI input */
|
||||
if (skel->input)
|
||||
return -ENODATA;
|
||||
|
||||
*std = skel->std;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the current standard as seen by the hardware. This function shall
|
||||
* never actually change the standard, it just detects and reports.
|
||||
* The framework will initially set *std to tvnorms (i.e. the set of
|
||||
* supported standards by this input), and this function should just AND
|
||||
* this value. If there is no signal, then *std should be set to 0.
|
||||
*/
|
||||
static int skeleton_querystd(struct file *file, void *priv, v4l2_std_id *std)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
/* QUERY_STD is not supported on the HDMI input */
|
||||
if (skel->input)
|
||||
return -ENODATA;
|
||||
|
||||
#ifdef TODO
|
||||
/*
|
||||
* Query currently seen standard. Initial value of *std is
|
||||
* V4L2_STD_ALL. This function should look something like this:
|
||||
*/
|
||||
get_signal_info();
|
||||
if (no_signal) {
|
||||
*std = 0;
|
||||
return 0;
|
||||
}
|
||||
/* Use signal information to reduce the number of possible standards */
|
||||
if (signal_has_525_lines)
|
||||
*std &= V4L2_STD_525_60;
|
||||
else
|
||||
*std &= V4L2_STD_625_50;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_s_dv_timings(struct file *file, void *_fh,
|
||||
struct v4l2_dv_timings *timings)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
/* S_DV_TIMINGS is not supported on the S-Video input */
|
||||
if (skel->input == 0)
|
||||
return -ENODATA;
|
||||
|
||||
/* Quick sanity check */
|
||||
if (!v4l2_valid_dv_timings(timings, &skel_timings_cap, NULL, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if the timings are part of the CEA-861 timings. */
|
||||
if (!v4l2_find_dv_timings_cap(timings, &skel_timings_cap,
|
||||
0, NULL, NULL))
|
||||
return -EINVAL;
|
||||
|
||||
/* Return 0 if the new timings are the same as the current timings. */
|
||||
if (v4l2_match_dv_timings(timings, &skel->timings, 0))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Changing the timings implies a format change, which is not allowed
|
||||
* while buffers for use with streaming have already been allocated.
|
||||
*/
|
||||
if (vb2_is_busy(&skel->queue))
|
||||
return -EBUSY;
|
||||
|
||||
/* TODO: Configure new timings */
|
||||
|
||||
/* Save timings */
|
||||
skel->timings = *timings;
|
||||
|
||||
/* Update the internal format */
|
||||
skeleton_fill_pix_format(skel, &skel->format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_g_dv_timings(struct file *file, void *_fh,
|
||||
struct v4l2_dv_timings *timings)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
/* G_DV_TIMINGS is not supported on the S-Video input */
|
||||
if (skel->input == 0)
|
||||
return -ENODATA;
|
||||
|
||||
*timings = skel->timings;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_enum_dv_timings(struct file *file, void *_fh,
|
||||
struct v4l2_enum_dv_timings *timings)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
/* ENUM_DV_TIMINGS is not supported on the S-Video input */
|
||||
if (skel->input == 0)
|
||||
return -ENODATA;
|
||||
|
||||
return v4l2_enum_dv_timings_cap(timings, &skel_timings_cap,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the current timings as seen by the hardware. This function shall
|
||||
* never actually change the timings, it just detects and reports.
|
||||
* If no signal is detected, then return -ENOLINK. If the hardware cannot
|
||||
* lock to the signal, then return -ENOLCK. If the signal is out of range
|
||||
* of the capabilities of the system (e.g., it is possible that the receiver
|
||||
* can lock but that the DMA engine it is connected to cannot handle
|
||||
* pixelclocks above a certain frequency), then -ERANGE is returned.
|
||||
*/
|
||||
static int skeleton_query_dv_timings(struct file *file, void *_fh,
|
||||
struct v4l2_dv_timings *timings)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
/* QUERY_DV_TIMINGS is not supported on the S-Video input */
|
||||
if (skel->input == 0)
|
||||
return -ENODATA;
|
||||
|
||||
#ifdef TODO
|
||||
/*
|
||||
* Query currently seen timings. This function should look
|
||||
* something like this:
|
||||
*/
|
||||
detect_timings();
|
||||
if (no_signal)
|
||||
return -ENOLINK;
|
||||
if (cannot_lock_to_signal)
|
||||
return -ENOLCK;
|
||||
if (signal_out_of_range_of_capabilities)
|
||||
return -ERANGE;
|
||||
|
||||
/* Useful for debugging */
|
||||
v4l2_print_dv_timings(skel->v4l2_dev.name, "query_dv_timings:",
|
||||
timings, true);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_dv_timings_cap(struct file *file, void *fh,
|
||||
struct v4l2_dv_timings_cap *cap)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
/* DV_TIMINGS_CAP is not supported on the S-Video input */
|
||||
if (skel->input == 0)
|
||||
return -ENODATA;
|
||||
*cap = skel_timings_cap;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_enum_input(struct file *file, void *priv,
|
||||
struct v4l2_input *i)
|
||||
{
|
||||
if (i->index > 1)
|
||||
return -EINVAL;
|
||||
|
||||
i->type = V4L2_INPUT_TYPE_CAMERA;
|
||||
if (i->index == 0) {
|
||||
i->std = SKEL_TVNORMS;
|
||||
strlcpy(i->name, "S-Video", sizeof(i->name));
|
||||
i->capabilities = V4L2_IN_CAP_STD;
|
||||
} else {
|
||||
i->std = 0;
|
||||
strlcpy(i->name, "HDMI", sizeof(i->name));
|
||||
i->capabilities = V4L2_IN_CAP_DV_TIMINGS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_s_input(struct file *file, void *priv, unsigned int i)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
if (i > 1)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Changing the input implies a format change, which is not allowed
|
||||
* while buffers for use with streaming have already been allocated.
|
||||
*/
|
||||
if (vb2_is_busy(&skel->queue))
|
||||
return -EBUSY;
|
||||
|
||||
skel->input = i;
|
||||
/*
|
||||
* Update tvnorms. The tvnorms value is used by the core to implement
|
||||
* VIDIOC_ENUMSTD so it has to be correct. If tvnorms == 0, then
|
||||
* ENUMSTD will return -ENODATA.
|
||||
*/
|
||||
skel->vdev.tvnorms = i ? 0 : SKEL_TVNORMS;
|
||||
|
||||
/* Update the internal format */
|
||||
skeleton_fill_pix_format(skel, &skel->format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skeleton_g_input(struct file *file, void *priv, unsigned int *i)
|
||||
{
|
||||
struct skeleton *skel = video_drvdata(file);
|
||||
|
||||
*i = skel->input;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The control handler. */
|
||||
static int skeleton_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
/*struct skeleton *skel =
|
||||
container_of(ctrl->handler, struct skeleton, ctrl_handler);*/
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
/* TODO: set brightness to ctrl->val */
|
||||
break;
|
||||
case V4L2_CID_CONTRAST:
|
||||
/* TODO: set contrast to ctrl->val */
|
||||
break;
|
||||
case V4L2_CID_SATURATION:
|
||||
/* TODO: set saturation to ctrl->val */
|
||||
break;
|
||||
case V4L2_CID_HUE:
|
||||
/* TODO: set hue to ctrl->val */
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
File operations for the device
|
||||
------------------------------------------------------------------*/
|
||||
|
||||
static const struct v4l2_ctrl_ops skel_ctrl_ops = {
|
||||
.s_ctrl = skeleton_s_ctrl,
|
||||
};
|
||||
|
||||
/*
|
||||
* The set of all supported ioctls. Note that all the streaming ioctls
|
||||
* use the vb2 helper functions that take care of all the locking and
|
||||
* that also do ownership tracking (i.e. only the filehandle that requested
|
||||
* the buffers can call the streaming ioctls, all other filehandles will
|
||||
* receive -EBUSY if they attempt to call the same streaming ioctls).
|
||||
*
|
||||
* The last three ioctls also use standard helper functions: these implement
|
||||
* standard behavior for drivers with controls.
|
||||
*/
|
||||
static const struct v4l2_ioctl_ops skel_ioctl_ops = {
|
||||
.vidioc_querycap = skeleton_querycap,
|
||||
.vidioc_try_fmt_vid_cap = skeleton_try_fmt_vid_cap,
|
||||
.vidioc_s_fmt_vid_cap = skeleton_s_fmt_vid_cap,
|
||||
.vidioc_g_fmt_vid_cap = skeleton_g_fmt_vid_cap,
|
||||
.vidioc_enum_fmt_vid_cap = skeleton_enum_fmt_vid_cap,
|
||||
|
||||
.vidioc_g_std = skeleton_g_std,
|
||||
.vidioc_s_std = skeleton_s_std,
|
||||
.vidioc_querystd = skeleton_querystd,
|
||||
|
||||
.vidioc_s_dv_timings = skeleton_s_dv_timings,
|
||||
.vidioc_g_dv_timings = skeleton_g_dv_timings,
|
||||
.vidioc_enum_dv_timings = skeleton_enum_dv_timings,
|
||||
.vidioc_query_dv_timings = skeleton_query_dv_timings,
|
||||
.vidioc_dv_timings_cap = skeleton_dv_timings_cap,
|
||||
|
||||
.vidioc_enum_input = skeleton_enum_input,
|
||||
.vidioc_g_input = skeleton_g_input,
|
||||
.vidioc_s_input = skeleton_s_input,
|
||||
|
||||
.vidioc_reqbufs = vb2_ioctl_reqbufs,
|
||||
.vidioc_create_bufs = vb2_ioctl_create_bufs,
|
||||
.vidioc_querybuf = vb2_ioctl_querybuf,
|
||||
.vidioc_qbuf = vb2_ioctl_qbuf,
|
||||
.vidioc_dqbuf = vb2_ioctl_dqbuf,
|
||||
.vidioc_expbuf = vb2_ioctl_expbuf,
|
||||
.vidioc_streamon = vb2_ioctl_streamon,
|
||||
.vidioc_streamoff = vb2_ioctl_streamoff,
|
||||
|
||||
.vidioc_log_status = v4l2_ctrl_log_status,
|
||||
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
|
||||
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
||||
};
|
||||
|
||||
/*
|
||||
* The set of file operations. Note that all these ops are standard core
|
||||
* helper functions.
|
||||
*/
|
||||
static const struct v4l2_file_operations skel_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = v4l2_fh_open,
|
||||
.release = vb2_fop_release,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
.read = vb2_fop_read,
|
||||
.mmap = vb2_fop_mmap,
|
||||
.poll = vb2_fop_poll,
|
||||
};
|
||||
|
||||
/*
|
||||
* The initial setup of this device instance. Note that the initial state of
|
||||
* the driver should be complete. So the initial format, standard, timings
|
||||
* and video input should all be initialized to some reasonable value.
|
||||
*/
|
||||
static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
/* The initial timings are chosen to be 720p60. */
|
||||
static const struct v4l2_dv_timings timings_def =
|
||||
V4L2_DV_BT_CEA_1280X720P60;
|
||||
struct skeleton *skel;
|
||||
struct video_device *vdev;
|
||||
struct v4l2_ctrl_handler *hdl;
|
||||
struct vb2_queue *q;
|
||||
int ret;
|
||||
|
||||
/* Enable PCI */
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "no suitable DMA available.\n");
|
||||
goto disable_pci;
|
||||
}
|
||||
|
||||
/* Allocate a new instance */
|
||||
skel = devm_kzalloc(&pdev->dev, sizeof(struct skeleton), GFP_KERNEL);
|
||||
if (!skel)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Allocate the interrupt */
|
||||
ret = devm_request_irq(&pdev->dev, pdev->irq,
|
||||
skeleton_irq, 0, KBUILD_MODNAME, skel);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "request_irq failed\n");
|
||||
goto disable_pci;
|
||||
}
|
||||
skel->pdev = pdev;
|
||||
|
||||
/* Fill in the initial format-related settings */
|
||||
skel->timings = timings_def;
|
||||
skel->std = V4L2_STD_625_50;
|
||||
skeleton_fill_pix_format(skel, &skel->format);
|
||||
|
||||
/* Initialize the top-level structure */
|
||||
ret = v4l2_device_register(&pdev->dev, &skel->v4l2_dev);
|
||||
if (ret)
|
||||
goto disable_pci;
|
||||
|
||||
mutex_init(&skel->lock);
|
||||
|
||||
/* Add the controls */
|
||||
hdl = &skel->ctrl_handler;
|
||||
v4l2_ctrl_handler_init(hdl, 4);
|
||||
v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
|
||||
V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
|
||||
v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
|
||||
V4L2_CID_CONTRAST, 0, 255, 1, 16);
|
||||
v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
|
||||
V4L2_CID_SATURATION, 0, 255, 1, 127);
|
||||
v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
|
||||
V4L2_CID_HUE, -128, 127, 1, 0);
|
||||
if (hdl->error) {
|
||||
ret = hdl->error;
|
||||
goto free_hdl;
|
||||
}
|
||||
skel->v4l2_dev.ctrl_handler = hdl;
|
||||
|
||||
/* Initialize the vb2 queue */
|
||||
q = &skel->queue;
|
||||
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
|
||||
q->drv_priv = skel;
|
||||
q->buf_struct_size = sizeof(struct skel_buffer);
|
||||
q->ops = &skel_qops;
|
||||
q->mem_ops = &vb2_dma_contig_memops;
|
||||
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||||
/*
|
||||
* Assume that this DMA engine needs to have at least two buffers
|
||||
* available before it can be started. The start_streaming() op
|
||||
* won't be called until at least this many buffers are queued up.
|
||||
*/
|
||||
q->min_buffers_needed = 2;
|
||||
/*
|
||||
* The serialization lock for the streaming ioctls. This is the same
|
||||
* as the main serialization lock, but if some of the non-streaming
|
||||
* ioctls could take a long time to execute, then you might want to
|
||||
* have a different lock here to prevent VIDIOC_DQBUF from being
|
||||
* blocked while waiting for another action to finish. This is
|
||||
* generally not needed for PCI devices, but USB devices usually do
|
||||
* want a separate lock here.
|
||||
*/
|
||||
q->lock = &skel->lock;
|
||||
/*
|
||||
* Since this driver can only do 32-bit DMA we must make sure that
|
||||
* the vb2 core will allocate the buffers in 32-bit DMA memory.
|
||||
*/
|
||||
q->gfp_flags = GFP_DMA32;
|
||||
ret = vb2_queue_init(q);
|
||||
if (ret)
|
||||
goto free_hdl;
|
||||
|
||||
skel->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
|
||||
if (IS_ERR(skel->alloc_ctx)) {
|
||||
dev_err(&pdev->dev, "Can't allocate buffer context");
|
||||
ret = PTR_ERR(skel->alloc_ctx);
|
||||
goto free_hdl;
|
||||
}
|
||||
INIT_LIST_HEAD(&skel->buf_list);
|
||||
spin_lock_init(&skel->qlock);
|
||||
|
||||
/* Initialize the video_device structure */
|
||||
vdev = &skel->vdev;
|
||||
strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
|
||||
/*
|
||||
* There is nothing to clean up, so release is set to an empty release
|
||||
* function. The release callback must be non-NULL.
|
||||
*/
|
||||
vdev->release = video_device_release_empty;
|
||||
vdev->fops = &skel_fops,
|
||||
vdev->ioctl_ops = &skel_ioctl_ops,
|
||||
/*
|
||||
* The main serialization lock. All ioctls are serialized by this
|
||||
* lock. Exception: if q->lock is set, then the streaming ioctls
|
||||
* are serialized by that separate lock.
|
||||
*/
|
||||
vdev->lock = &skel->lock;
|
||||
vdev->queue = q;
|
||||
vdev->v4l2_dev = &skel->v4l2_dev;
|
||||
/* Supported SDTV standards, if any */
|
||||
vdev->tvnorms = SKEL_TVNORMS;
|
||||
/* If this bit is set, then the v4l2 core will provide the support
|
||||
* for the VIDIOC_G/S_PRIORITY ioctls. This flag will eventually
|
||||
* go away once all drivers have been converted to use struct v4l2_fh.
|
||||
*/
|
||||
set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
|
||||
video_set_drvdata(vdev, skel);
|
||||
|
||||
ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
|
||||
if (ret)
|
||||
goto free_ctx;
|
||||
|
||||
dev_info(&pdev->dev, "V4L2 PCI Skeleton Driver loaded\n");
|
||||
return 0;
|
||||
|
||||
free_ctx:
|
||||
vb2_dma_contig_cleanup_ctx(skel->alloc_ctx);
|
||||
free_hdl:
|
||||
v4l2_ctrl_handler_free(&skel->ctrl_handler);
|
||||
v4l2_device_unregister(&skel->v4l2_dev);
|
||||
disable_pci:
|
||||
pci_disable_device(pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void skeleton_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
|
||||
struct skeleton *skel = container_of(v4l2_dev, struct skeleton, v4l2_dev);
|
||||
|
||||
video_unregister_device(&skel->vdev);
|
||||
v4l2_ctrl_handler_free(&skel->ctrl_handler);
|
||||
vb2_dma_contig_cleanup_ctx(skel->alloc_ctx);
|
||||
v4l2_device_unregister(&skel->v4l2_dev);
|
||||
pci_disable_device(skel->pdev);
|
||||
}
|
||||
|
||||
static struct pci_driver skeleton_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.probe = skeleton_probe,
|
||||
.remove = skeleton_remove,
|
||||
.id_table = skeleton_pci_tbl,
|
||||
};
|
||||
|
||||
module_pci_driver(skeleton_driver);
|
52
MAINTAINERS
52
MAINTAINERS
@ -4859,22 +4859,6 @@ S: Maintained
|
||||
F: Documentation/hwmon/it87
|
||||
F: drivers/hwmon/it87.c
|
||||
|
||||
IT913X MEDIA DRIVER
|
||||
M: Malcolm Priestley <tvboxspy@gmail.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
W: http://linuxtv.org/
|
||||
Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
S: Maintained
|
||||
F: drivers/media/usb/dvb-usb-v2/it913x*
|
||||
|
||||
IT913X FE MEDIA DRIVER
|
||||
M: Malcolm Priestley <tvboxspy@gmail.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
W: http://linuxtv.org/
|
||||
Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
S: Maintained
|
||||
F: drivers/media/dvb-frontends/it913x-fe*
|
||||
|
||||
IT913X MEDIA DRIVER
|
||||
M: Antti Palosaari <crope@iki.fi>
|
||||
L: linux-media@vger.kernel.org
|
||||
@ -5855,6 +5839,26 @@ L: platform-driver-x86@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/platform/x86/msi-wmi.c
|
||||
|
||||
MSI001 MEDIA DRIVER
|
||||
M: Antti Palosaari <crope@iki.fi>
|
||||
L: linux-media@vger.kernel.org
|
||||
W: http://linuxtv.org/
|
||||
W: http://palosaari.fi/linux/
|
||||
Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
T: git git://linuxtv.org/anttip/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/staging/media/msi3101/msi001*
|
||||
|
||||
MSI3101 MEDIA DRIVER
|
||||
M: Antti Palosaari <crope@iki.fi>
|
||||
L: linux-media@vger.kernel.org
|
||||
W: http://linuxtv.org/
|
||||
W: http://palosaari.fi/linux/
|
||||
Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
T: git git://linuxtv.org/anttip/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/staging/media/msi3101/sdr-msi3101*
|
||||
|
||||
MT9M032 APTINA SENSOR DRIVER
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
@ -7422,6 +7426,16 @@ T: git git://linuxtv.org/anttip/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/media/dvb-frontends/rtl2832*
|
||||
|
||||
RTL2832_SDR MEDIA DRIVER
|
||||
M: Antti Palosaari <crope@iki.fi>
|
||||
L: linux-media@vger.kernel.org
|
||||
W: http://linuxtv.org/
|
||||
W: http://palosaari.fi/linux/
|
||||
Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
T: git git://linuxtv.org/anttip/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/staging/media/rtl2832u_sdr/rtl2832_sdr*
|
||||
|
||||
RTL8180 WIRELESS DRIVER
|
||||
M: "John W. Linville" <linville@tuxdriver.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
@ -7954,15 +7968,13 @@ F: drivers/media/usb/siano/
|
||||
F: drivers/media/mmc/siano/
|
||||
|
||||
SH_VEU V4L2 MEM2MEM DRIVER
|
||||
M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/media/platform/sh_veu.c
|
||||
|
||||
SH_VOU V4L2 OUTPUT DRIVER
|
||||
M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
S: Orphan
|
||||
F: drivers/media/platform/sh_vou.c
|
||||
F: include/media/sh_vou.h
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -542,8 +544,22 @@ static struct isp_platform_data cm_t35_isp_pdata = {
|
||||
.subdevs = cm_t35_isp_subdevs,
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply cm_t35_camera_supplies[] = {
|
||||
REGULATOR_SUPPLY("vaa", "3-005d"),
|
||||
REGULATOR_SUPPLY("vdd", "3-005d"),
|
||||
};
|
||||
|
||||
static void __init cm_t35_init_camera(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "mt9t001-clkin", NULL, CLK_IS_ROOT,
|
||||
48000000);
|
||||
clk_register_clkdev(clk, NULL, "3-005d");
|
||||
|
||||
regulator_register_fixed(2, cm_t35_camera_supplies,
|
||||
ARRAY_SIZE(cm_t35_camera_supplies));
|
||||
|
||||
if (omap3_init_camera(&cm_t35_isp_pdata) < 0)
|
||||
pr_warn("CM-T3x: Failed registering camera device!\n");
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* Written Doug Thompson <norsk5@xmission.com> www.softwarebitmaker.com
|
||||
*
|
||||
* (c) 2012-2013 - Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* (c) 2012-2013 - Mauro Carvalho Chehab
|
||||
* The entire API were re-written, and ported to use struct device
|
||||
*
|
||||
*/
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This file may be distributed under the terms of the GNU General Public
|
||||
* License version 2.
|
||||
*
|
||||
* Copyright (c) 2013 by Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Copyright (c) 2013 by Mauro Carvalho Chehab
|
||||
*
|
||||
* Red Hat Inc. http://www.redhat.com
|
||||
*/
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Copyright (c) 2008 by:
|
||||
* Ben Woodard <woodard@redhat.com>
|
||||
* Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Mauro Carvalho Chehab
|
||||
*
|
||||
* Red Hat Inc. http://www.redhat.com
|
||||
*
|
||||
@ -1469,7 +1469,7 @@ module_exit(i5400_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Ben Woodard <woodard@redhat.com>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("MC Driver for Intel I5400 memory controllers - "
|
||||
I5400_REVISION);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* GNU General Public License version 2 only.
|
||||
*
|
||||
* Copyright (c) 2010 by:
|
||||
* Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Mauro Carvalho Chehab
|
||||
*
|
||||
* Red Hat Inc. http://www.redhat.com
|
||||
*
|
||||
@ -1209,7 +1209,7 @@ module_init(i7300_init);
|
||||
module_exit(i7300_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("MC Driver for Intel I7300 memory controllers - "
|
||||
I7300_REVISION);
|
||||
|
@ -9,7 +9,7 @@
|
||||
* GNU General Public License version 2 only.
|
||||
*
|
||||
* Copyright (c) 2009-2010 by:
|
||||
* Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Mauro Carvalho Chehab
|
||||
*
|
||||
* Red Hat Inc. http://www.redhat.com
|
||||
*
|
||||
@ -2457,7 +2457,7 @@ module_init(i7core_init);
|
||||
module_exit(i7core_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
|
||||
I7CORE_REVISION);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* GNU General Public License version 2 only.
|
||||
*
|
||||
* Copyright (c) 2011 by:
|
||||
* Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Mauro Carvalho Chehab
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -2183,7 +2183,7 @@ module_param(edac_op_state, int, 0444);
|
||||
MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
|
||||
MODULE_DESCRIPTION("MC Driver for Intel Sandy Bridge and Ivy Bridge memory controllers - "
|
||||
SBRIDGE_REVISION);
|
||||
|
@ -114,7 +114,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
|
||||
|
||||
rdev->priv = data;
|
||||
rdev->driver_type = RC_DRIVER_IR_RAW;
|
||||
rdev->allowed_protos = RC_BIT_ALL;
|
||||
rc_set_allowed_protocols(rdev, RC_BIT_ALL);
|
||||
rdev->open = picolcd_cir_open;
|
||||
rdev->close = picolcd_cir_close;
|
||||
rdev->input_name = data->hdev->name;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright(c) 2013 Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Copyright(c) 2013 Mauro Carvalho Chehab
|
||||
*
|
||||
* 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
|
||||
|
@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
|
||||
|
||||
dev->priv = coredev;
|
||||
dev->driver_type = RC_DRIVER_IR_RAW;
|
||||
dev->allowed_protos = RC_BIT_ALL;
|
||||
rc_set_allowed_protocols(dev, RC_BIT_ALL);
|
||||
dev->map_name = sms_get_board(board_id)->rc_codes;
|
||||
dev->driver_name = MODULE_NAME;
|
||||
|
||||
|
@ -257,6 +257,7 @@
|
||||
#define USB_PID_TERRATEC_T5 0x10a1
|
||||
#define USB_PID_NOXON_DAB_STICK 0x00b3
|
||||
#define USB_PID_NOXON_DAB_STICK_REV2 0x00e0
|
||||
#define USB_PID_NOXON_DAB_STICK_REV3 0x00b4
|
||||
#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
|
||||
#define USB_PID_PINNACLE_PCTV2000E 0x022c
|
||||
#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228
|
||||
|
@ -1279,7 +1279,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
|
||||
switch(tvp->cmd) {
|
||||
case DTV_ENUM_DELSYS:
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
|
||||
tvp->u.buffer.data[ncaps] = fe->ops.delsys[ncaps];
|
||||
ncaps++;
|
||||
}
|
||||
@ -1596,7 +1596,7 @@ static int dvbv5_set_delivery_system(struct dvb_frontend *fe,
|
||||
* supported
|
||||
*/
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
|
||||
if (fe->ops.delsys[ncaps] == desired_system) {
|
||||
c->delivery_system = desired_system;
|
||||
dev_dbg(fe->dvb->device,
|
||||
@ -1628,7 +1628,7 @@ static int dvbv5_set_delivery_system(struct dvb_frontend *fe,
|
||||
* of the desired system
|
||||
*/
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
|
||||
if (dvbv3_type(fe->ops.delsys[ncaps]) == type)
|
||||
delsys = fe->ops.delsys[ncaps];
|
||||
ncaps++;
|
||||
@ -1703,7 +1703,7 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)
|
||||
* DVBv3 standard
|
||||
*/
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
|
||||
if (dvbv3_type(fe->ops.delsys[ncaps]) != DVBV3_UNKNOWN) {
|
||||
delsys = fe->ops.delsys[ncaps];
|
||||
break;
|
||||
@ -1882,6 +1882,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
|
||||
c->lna = tvp->u.data;
|
||||
if (fe->ops.set_lna)
|
||||
r = fe->ops.set_lna(fe);
|
||||
if (r < 0)
|
||||
c->lna = LNA_AUTO;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -441,7 +441,7 @@ config DVB_RTL2830
|
||||
|
||||
config DVB_RTL2832
|
||||
tristate "Realtek RTL2832 DVB-T"
|
||||
depends on DVB_CORE && I2C
|
||||
depends on DVB_CORE && I2C && I2C_MUX
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
@ -650,6 +650,8 @@ config DVB_TUNER_DIB0090
|
||||
comment "SEC control devices for DVB-S"
|
||||
depends on DVB_CORE
|
||||
|
||||
source "drivers/media/dvb-frontends/drx39xyj/Kconfig"
|
||||
|
||||
config DVB_LNBP21
|
||||
tristate "LNBP21/LNBH24 SEC controllers"
|
||||
depends on DVB_CORE && I2C
|
||||
@ -733,14 +735,6 @@ config DVB_IX2505V
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_IT913X_FE
|
||||
tristate "it913x frontend and it9137 tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module.
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_M88RS2000
|
||||
tristate "M88RS2000 DVB-S demodulator and tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
|
@ -92,13 +92,13 @@ obj-$(CONFIG_DVB_HD29L2) += hd29l2.o
|
||||
obj-$(CONFIG_DVB_DS3000) += ds3000.o
|
||||
obj-$(CONFIG_DVB_TS2020) += ts2020.o
|
||||
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
|
||||
obj-$(CONFIG_DVB_DRX39XYJ) += drx39xyj/
|
||||
obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
|
||||
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
|
||||
obj-$(CONFIG_DVB_STV0367) += stv0367.o
|
||||
obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
|
||||
obj-$(CONFIG_DVB_DRXK) += drxk.o
|
||||
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
|
||||
obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o
|
||||
obj-$(CONFIG_DVB_A8293) += a8293.o
|
||||
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
|
||||
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
|
||||
|
@ -989,10 +989,62 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&state->i2c->dev, "%s: onoff=%d\n", __func__, onoff);
|
||||
|
||||
ret = af9033_wr_reg_mask(state, 0x80f993, onoff, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid, int onoff)
|
||||
{
|
||||
struct af9033_state *state = fe->demodulator_priv;
|
||||
int ret;
|
||||
u8 wbuf[2] = {(pid >> 0) & 0xff, (pid >> 8) & 0xff};
|
||||
|
||||
dev_dbg(&state->i2c->dev, "%s: index=%d pid=%04x onoff=%d\n",
|
||||
__func__, index, pid, onoff);
|
||||
|
||||
if (pid > 0x1fff)
|
||||
return 0;
|
||||
|
||||
ret = af9033_wr_regs(state, 0x80f996, wbuf, 2);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg(state, 0x80f994, onoff);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg(state, 0x80f995, index);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops af9033_ops;
|
||||
|
||||
struct dvb_frontend *af9033_attach(const struct af9033_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
struct i2c_adapter *i2c,
|
||||
struct af9033_ops *ops)
|
||||
{
|
||||
int ret;
|
||||
struct af9033_state *state;
|
||||
@ -1067,6 +1119,11 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
|
||||
memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
|
||||
state->fe.demodulator_priv = state;
|
||||
|
||||
if (ops) {
|
||||
ops->pid_filter = af9033_pid_filter;
|
||||
ops->pid_filter_ctrl = af9033_pid_filter_ctrl;
|
||||
}
|
||||
|
||||
return &state->fe;
|
||||
|
||||
err:
|
||||
|
@ -78,16 +78,42 @@ struct af9033_config {
|
||||
};
|
||||
|
||||
|
||||
struct af9033_ops {
|
||||
int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff);
|
||||
int (*pid_filter)(struct dvb_frontend *fe, int index, u16 pid,
|
||||
int onoff);
|
||||
};
|
||||
|
||||
|
||||
#if IS_ENABLED(CONFIG_DVB_AF9033)
|
||||
extern struct dvb_frontend *af9033_attach(const struct af9033_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
extern
|
||||
struct dvb_frontend *af9033_attach(const struct af9033_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
struct af9033_ops *ops);
|
||||
|
||||
#else
|
||||
static inline struct dvb_frontend *af9033_attach(
|
||||
const struct af9033_config *config, struct i2c_adapter *i2c)
|
||||
static inline
|
||||
struct dvb_frontend *af9033_attach(const struct af9033_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
struct af9033_ops *ops)
|
||||
{
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
|
||||
{
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
|
||||
int onoff)
|
||||
{
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* AF9033_H */
|
||||
|
7
drivers/media/dvb-frontends/drx39xyj/Kconfig
Normal file
7
drivers/media/dvb-frontends/drx39xyj/Kconfig
Normal file
@ -0,0 +1,7 @@
|
||||
config DVB_DRX39XYJ
|
||||
tristate "Micronas DRX-J demodulator"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
6
drivers/media/dvb-frontends/drx39xyj/Makefile
Normal file
6
drivers/media/dvb-frontends/drx39xyj/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
drx39xyj-objs := drxj.o
|
||||
|
||||
obj-$(CONFIG_DVB_DRX39XYJ) += drx39xyj.o
|
||||
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb-core/
|
||||
ccflags-y += -I$(srctree)/drivers/media/tuners/
|
139
drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h
Normal file
139
drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
I2C API, implementation depends on board specifics
|
||||
|
||||
Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of Trident Microsystems nor Hauppauge Computer Works
|
||||
nor the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
This module encapsulates I2C access.In some applications several devices
|
||||
share one I2C bus. If these devices have the same I2C address some kind
|
||||
off "switch" must be implemented to ensure error free communication with
|
||||
one device. In case such a "switch" is used, the device ID can be used
|
||||
to implement control over this "switch".
|
||||
*/
|
||||
|
||||
#ifndef __BSPI2C_H__
|
||||
#define __BSPI2C_H__
|
||||
|
||||
#include "bsp_types.h"
|
||||
|
||||
/*
|
||||
* This structure contains the I2C address, the device ID and a user_data pointer.
|
||||
* The user_data pointer can be used for application specific purposes.
|
||||
*/
|
||||
struct i2c_device_addr {
|
||||
u16 i2c_addr; /* The I2C address of the device. */
|
||||
u16 i2c_dev_id; /* The device identifier. */
|
||||
void *user_data; /* User data pointer */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \def IS_I2C_10BIT( addr )
|
||||
* \brief Determine if I2C address 'addr' is a 10 bits address or not.
|
||||
* \param addr The I2C address.
|
||||
* \return int.
|
||||
* \retval 0 if address is not a 10 bits I2C address.
|
||||
* \retval 1 if address is a 10 bits I2C address.
|
||||
*/
|
||||
#define IS_I2C_10BIT(addr) \
|
||||
(((addr) & 0xF8) == 0xF0)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Exported FUNCTIONS
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \fn drxbsp_i2c_init()
|
||||
* \brief Initialize I2C communication module.
|
||||
* \return drx_status_t Return status.
|
||||
* \retval 0 Initialization successful.
|
||||
* \retval -EIO Initialization failed.
|
||||
*/
|
||||
drx_status_t drxbsp_i2c_init(void);
|
||||
|
||||
/**
|
||||
* \fn drxbsp_i2c_term()
|
||||
* \brief Terminate I2C communication module.
|
||||
* \return drx_status_t Return status.
|
||||
* \retval 0 Termination successful.
|
||||
* \retval -EIO Termination failed.
|
||||
*/
|
||||
drx_status_t drxbsp_i2c_term(void);
|
||||
|
||||
/**
|
||||
* \fn drx_status_t drxbsp_i2c_write_read( struct i2c_device_addr *w_dev_addr,
|
||||
* u16 w_count,
|
||||
* u8 *wData,
|
||||
* struct i2c_device_addr *r_dev_addr,
|
||||
* u16 r_count,
|
||||
* u8 *r_data)
|
||||
* \brief Read and/or write count bytes from I2C bus, store them in data[].
|
||||
* \param w_dev_addr The device i2c address and the device ID to write to
|
||||
* \param w_count The number of bytes to write
|
||||
* \param wData The array to write the data to
|
||||
* \param r_dev_addr The device i2c address and the device ID to read from
|
||||
* \param r_count The number of bytes to read
|
||||
* \param r_data The array to read the data from
|
||||
* \return drx_status_t Return status.
|
||||
* \retval 0 Succes.
|
||||
* \retval -EIO Failure.
|
||||
* \retval -EINVAL Parameter 'wcount' is not zero but parameter
|
||||
* 'wdata' contains NULL.
|
||||
* Idem for 'rcount' and 'rdata'.
|
||||
* Both w_dev_addr and r_dev_addr are NULL.
|
||||
*
|
||||
* This function must implement an atomic write and/or read action on the I2C bus
|
||||
* No other process may use the I2C bus when this function is executing.
|
||||
* The critical section of this function runs from and including the I2C
|
||||
* write, up to and including the I2C read action.
|
||||
*
|
||||
* The device ID can be useful if several devices share an I2C address.
|
||||
* It can be used to control a "switch" on the I2C bus to the correct device.
|
||||
*/
|
||||
drx_status_t drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
|
||||
u16 w_count,
|
||||
u8 *w_data,
|
||||
struct i2c_device_addr *r_dev_addr,
|
||||
u16 r_count, u8 *r_data);
|
||||
|
||||
/**
|
||||
* \fn drxbsp_i2c_error_text()
|
||||
* \brief Returns a human readable error.
|
||||
* Counter part of numerical drx_i2c_error_g.
|
||||
*
|
||||
* \return char* Pointer to human readable error text.
|
||||
*/
|
||||
char *drxbsp_i2c_error_text(void);
|
||||
|
||||
/**
|
||||
* \var drx_i2c_error_g;
|
||||
* \brief I2C specific error codes, platform dependent.
|
||||
*/
|
||||
extern int drx_i2c_error_g;
|
||||
|
||||
#endif /* __BSPI2C_H__ */
|
45
drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
Normal file
45
drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Driver for Micronas DRX39xx family (drx3933j)
|
||||
*
|
||||
* Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
*
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
|
||||
*/
|
||||
|
||||
#ifndef DRX39XXJ_H
|
||||
#define DRX39XXJ_H
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
#include "drx_driver.h"
|
||||
|
||||
struct drx39xxj_state {
|
||||
struct i2c_adapter *i2c;
|
||||
struct drx_demod_instance *demod;
|
||||
struct dvb_frontend frontend;
|
||||
unsigned int i2c_gate_open:1;
|
||||
const struct firmware *fw;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DVB_DRX39XYJ)
|
||||
struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c);
|
||||
#else
|
||||
static inline struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) {
|
||||
return NULL;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* DVB_DUMMY_FE_H */
|
256
drivers/media/dvb-frontends/drx39xyj/drx_dap_fasi.h
Normal file
256
drivers/media/dvb-frontends/drx39xyj/drx_dap_fasi.h
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of Trident Microsystems nor Hauppauge Computer Works
|
||||
nor the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* FILENAME: $Id: drx_dap_fasi.h,v 1.5 2009/07/07 14:21:40 justin Exp $
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Part of DRX driver.
|
||||
* Data access protocol: Fast Access Sequential Interface (fasi)
|
||||
* Fast access, because of short addressing format (16 instead of 32 bits addr)
|
||||
* Sequential, because of I2C.
|
||||
*
|
||||
* USAGE:
|
||||
* Include.
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
/*-------- compilation control switches --------------------------------------*/
|
||||
|
||||
#ifndef __DRX_DAP_FASI_H__
|
||||
#define __DRX_DAP_FASI_H__
|
||||
|
||||
/*-------- Required includes -------------------------------------------------*/
|
||||
|
||||
#include "drx_driver.h"
|
||||
|
||||
/*-------- Defines, configuring the API --------------------------------------*/
|
||||
|
||||
/********************************************
|
||||
* Allowed address formats
|
||||
********************************************/
|
||||
|
||||
/*
|
||||
* Comments about short/long addressing format:
|
||||
*
|
||||
* The DAP FASI offers long address format (4 bytes) and short address format
|
||||
* (2 bytes). The DAP can operate in 3 modes:
|
||||
* (1) only short
|
||||
* (2) only long
|
||||
* (3) both long and short but short preferred and long only when necesarry
|
||||
*
|
||||
* These modes must be selected compile time via compile switches.
|
||||
* Compile switch settings for the diffrent modes:
|
||||
* (1) DRXDAPFASI_LONG_ADDR_ALLOWED=0, DRXDAPFASI_SHORT_ADDR_ALLOWED=1
|
||||
* (2) DRXDAPFASI_LONG_ADDR_ALLOWED=1, DRXDAPFASI_SHORT_ADDR_ALLOWED=0
|
||||
* (3) DRXDAPFASI_LONG_ADDR_ALLOWED=1, DRXDAPFASI_SHORT_ADDR_ALLOWED=1
|
||||
*
|
||||
* The default setting will be (3) both long and short.
|
||||
* The default setting will need no compile switches.
|
||||
* The default setting must be overridden if compile switches are already
|
||||
* defined.
|
||||
*
|
||||
*/
|
||||
|
||||
/* set default */
|
||||
#if !defined(DRXDAPFASI_LONG_ADDR_ALLOWED)
|
||||
#define DRXDAPFASI_LONG_ADDR_ALLOWED 1
|
||||
#endif
|
||||
|
||||
/* set default */
|
||||
#if !defined(DRXDAPFASI_SHORT_ADDR_ALLOWED)
|
||||
#define DRXDAPFASI_SHORT_ADDR_ALLOWED 1
|
||||
#endif
|
||||
|
||||
/* check */
|
||||
#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 0) && \
|
||||
(DRXDAPFASI_SHORT_ADDR_ALLOWED == 0))
|
||||
#error At least one of short- or long-addressing format must be allowed.
|
||||
*; /* illegal statement to force compiler error */
|
||||
#endif
|
||||
|
||||
/********************************************
|
||||
* Single/master multi master setting
|
||||
********************************************/
|
||||
/*
|
||||
* Comments about SINGLE MASTER/MULTI MASTER modes:
|
||||
*
|
||||
* Consider the two sides:1) the master and 2)the slave.
|
||||
*
|
||||
* Master:
|
||||
* Single/multimaster operation set via DRXDAP_SINGLE_MASTER compile switch
|
||||
* + single master mode means no use of repeated starts
|
||||
* + multi master mode means use of repeated starts
|
||||
* Default is single master.
|
||||
* Default can be overriden by setting the compile switch DRXDAP_SINGLE_MASTER.
|
||||
*
|
||||
* Slave:
|
||||
* Single/multi master selected via the flags in the FASI protocol.
|
||||
* + single master means remember memory address between i2c packets
|
||||
* + multimaster means flush memory address between i2c packets
|
||||
* Default is single master, DAP FASI changes multi-master setting silently
|
||||
* into single master setting. This cannot be overrriden.
|
||||
*
|
||||
*/
|
||||
/* set default */
|
||||
#ifndef DRXDAP_SINGLE_MASTER
|
||||
#define DRXDAP_SINGLE_MASTER 0
|
||||
#endif
|
||||
|
||||
/********************************************
|
||||
* Chunk/mode checking
|
||||
********************************************/
|
||||
/*
|
||||
* Comments about DRXDAP_MAX_WCHUNKSIZE in single or multi master mode and
|
||||
* in combination with short and long addressing format. All text below
|
||||
* assumes long addressing format. The table also includes information
|
||||
* for short ADDRessing format.
|
||||
*
|
||||
* In single master mode, data can be written by sending the register address
|
||||
* first, then two or four bytes of data in the next packet.
|
||||
* Because the device address plus a register address equals five bytes,
|
||||
* the mimimum chunk size must be five.
|
||||
* If ten-bit I2C device addresses are used, the minimum chunk size must be six,
|
||||
* because the I2C device address will then occupy two bytes when writing.
|
||||
*
|
||||
* Data in single master mode is transferred as follows:
|
||||
* <S> <devW> a0 a1 a2 a3 <P>
|
||||
* <S> <devW> d0 d1 [d2 d3] <P>
|
||||
* ..
|
||||
* or
|
||||
* ..
|
||||
* <S> <devW> a0 a1 a2 a3 <P>
|
||||
* <S> <devR> --- <P>
|
||||
*
|
||||
* In multi-master mode, the data must immediately follow the address (an I2C
|
||||
* stop resets the internal address), and hence the minimum chunk size is
|
||||
* 1 <I2C address> + 4 (register address) + 2 (data to send) = 7 bytes (8 if
|
||||
* 10-bit I2C device addresses are used).
|
||||
*
|
||||
* The 7-bit or 10-bit i2c address parameters is a runtime parameter.
|
||||
* The other parameters can be limited via compile time switches.
|
||||
*
|
||||
*-------------------------------------------------------------------------------
|
||||
*
|
||||
* Minimum chunk size table (in bytes):
|
||||
*
|
||||
* +----------------+----------------+
|
||||
* | 7b i2c addr | 10b i2c addr |
|
||||
* +----------------+----------------+
|
||||
* | single | multi | single | multi |
|
||||
* ------+--------+-------+--------+-------+
|
||||
* short | 3 | 5 | 4 | 6 |
|
||||
* long | 5 | 7 | 6 | 8 |
|
||||
* ------+--------+-------+--------+-------+
|
||||
*
|
||||
*/
|
||||
|
||||
/* set default */
|
||||
#if !defined(DRXDAP_MAX_WCHUNKSIZE)
|
||||
#define DRXDAP_MAX_WCHUNKSIZE 254
|
||||
#endif
|
||||
|
||||
/* check */
|
||||
#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 0) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
|
||||
#if DRXDAP_SINGLE_MASTER
|
||||
#define DRXDAP_MAX_WCHUNKSIZE_MIN 3
|
||||
#else
|
||||
#define DRXDAP_MAX_WCHUNKSIZE_MIN 5
|
||||
#endif
|
||||
#else
|
||||
#if DRXDAP_SINGLE_MASTER
|
||||
#define DRXDAP_MAX_WCHUNKSIZE_MIN 5
|
||||
#else
|
||||
#define DRXDAP_MAX_WCHUNKSIZE_MIN 7
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if DRXDAP_MAX_WCHUNKSIZE < DRXDAP_MAX_WCHUNKSIZE_MIN
|
||||
#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 0) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
|
||||
#if DRXDAP_SINGLE_MASTER
|
||||
#error DRXDAP_MAX_WCHUNKSIZE must be at least 3 in single master mode
|
||||
*; /* illegal statement to force compiler error */
|
||||
#else
|
||||
#error DRXDAP_MAX_WCHUNKSIZE must be at least 5 in multi master mode
|
||||
*; /* illegal statement to force compiler error */
|
||||
#endif
|
||||
#else
|
||||
#if DRXDAP_SINGLE_MASTER
|
||||
#error DRXDAP_MAX_WCHUNKSIZE must be at least 5 in single master mode
|
||||
*; /* illegal statement to force compiler error */
|
||||
#else
|
||||
#error DRXDAP_MAX_WCHUNKSIZE must be at least 7 in multi master mode
|
||||
*; /* illegal statement to force compiler error */
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* set default */
|
||||
#if !defined(DRXDAP_MAX_RCHUNKSIZE)
|
||||
#define DRXDAP_MAX_RCHUNKSIZE 254
|
||||
#endif
|
||||
|
||||
/* check */
|
||||
#if DRXDAP_MAX_RCHUNKSIZE < 2
|
||||
#error DRXDAP_MAX_RCHUNKSIZE must be at least 2
|
||||
*; /* illegal statement to force compiler error */
|
||||
#endif
|
||||
|
||||
/* check */
|
||||
#if DRXDAP_MAX_RCHUNKSIZE & 1
|
||||
#error DRXDAP_MAX_RCHUNKSIZE must be even
|
||||
*; /* illegal statement to force compiler error */
|
||||
#endif
|
||||
|
||||
/*-------- Public API functions ----------------------------------------------*/
|
||||
|
||||
extern struct drx_access_func drx_dap_fasi_funct_g;
|
||||
|
||||
#define DRXDAP_FASI_RMW 0x10000000
|
||||
#define DRXDAP_FASI_BROADCAST 0x20000000
|
||||
#define DRXDAP_FASI_CLEARCRC 0x80000000
|
||||
#define DRXDAP_FASI_SINGLE_MASTER 0xC0000000
|
||||
#define DRXDAP_FASI_MULTI_MASTER 0x40000000
|
||||
#define DRXDAP_FASI_SMM_SWITCH 0x40000000 /* single/multi master switch */
|
||||
#define DRXDAP_FASI_MODEFLAGS 0xC0000000
|
||||
#define DRXDAP_FASI_FLAGS 0xF0000000
|
||||
|
||||
#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr)>>22)&0x3F)
|
||||
#define DRXDAP_FASI_ADDR2BANK(addr) (((addr)>>16)&0x3F)
|
||||
#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr)&0x7FFF)
|
||||
|
||||
#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
|
||||
#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
|
||||
#define DRXDAP_FASI_OFFSET_TOO_LARGE(addr) (((addr) & 0x00008000) != 0)
|
||||
|
||||
#endif /* __DRX_DAP_FASI_H__ */
|
2343
drivers/media/dvb-frontends/drx39xyj/drx_driver.h
Normal file
2343
drivers/media/dvb-frontends/drx39xyj/drx_driver.h
Normal file
File diff suppressed because it is too large
Load Diff
72
drivers/media/dvb-frontends/drx39xyj/drx_driver_version.h
Normal file
72
drivers/media/dvb-frontends/drx39xyj/drx_driver_version.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* WARNING - THIS FILE HAS BEEN GENERATED - DO NOT CHANGE
|
||||
*
|
||||
* Filename: drx_driver_version.h
|
||||
* Generated on: Mon Jan 18 12:09:23 2010
|
||||
* Generated by: IDF:x 1.3.0
|
||||
* Generated from: ../../../device/drxj/version
|
||||
* Output start: [entry point]
|
||||
*
|
||||
* filename last modified re-use
|
||||
*
|
||||
Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of Trident Microsystems nor Hauppauge Computer Works
|
||||
nor the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* version.idf Mon Jan 18 11:56:10 2010 -
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DRX_DRIVER_VERSION__H__
|
||||
#define __DRX_DRIVER_VERSION__H__ INCLUDED
|
||||
|
||||
#ifdef _REGISTERTABLE_
|
||||
#include <registertable.h>
|
||||
extern register_table_t drx_driver_version[];
|
||||
extern register_table_info_t drx_driver_version_info[];
|
||||
#endif /* _REGISTERTABLE_ */
|
||||
|
||||
/*
|
||||
*==============================================================================
|
||||
* VERSION
|
||||
* version@/var/cvs/projects/drxj.cvsroot/hostcode/drxdriver/device/drxj
|
||||
*==============================================================================
|
||||
*/
|
||||
|
||||
#define VERSION__A 0x0
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_PATCH 56
|
||||
|
||||
#endif /* __DRX_DRIVER_VERSION__H__ */
|
||||
/*
|
||||
* End of file (drx_driver_version.h)
|
||||
*******************************************************************************
|
||||
*/
|
12400
drivers/media/dvb-frontends/drx39xyj/drxj.c
Normal file
12400
drivers/media/dvb-frontends/drx39xyj/drxj.c
Normal file
File diff suppressed because it is too large
Load Diff
650
drivers/media/dvb-frontends/drx39xyj/drxj.h
Normal file
650
drivers/media/dvb-frontends/drx39xyj/drxj.h
Normal file
@ -0,0 +1,650 @@
|
||||
|
||||
/*
|
||||
Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of Trident Microsystems nor Hauppauge Computer Works
|
||||
nor the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
DRXJ specific header file
|
||||
|
||||
Authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
|
||||
*/
|
||||
|
||||
#ifndef __DRXJ_H__
|
||||
#define __DRXJ_H__
|
||||
/*-------------------------------------------------------------------------
|
||||
INCLUDES
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#include "drx_driver.h"
|
||||
#include "drx_dap_fasi.h"
|
||||
|
||||
/* Check DRX-J specific dap condition */
|
||||
/* Multi master mode and short addr format only will not work.
|
||||
RMW, CRC reset, broadcast and switching back to single master mode
|
||||
cannot be done with short addr only in multi master mode. */
|
||||
#if ((DRXDAP_SINGLE_MASTER == 0) && (DRXDAPFASI_LONG_ADDR_ALLOWED == 0))
|
||||
#error "Multi master mode and short addressing only is an illegal combination"
|
||||
*; /* Generate a fatal compiler error to make sure it stops here,
|
||||
this is necesarry because not all compilers stop after a #error. */
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
TYPEDEFS
|
||||
-------------------------------------------------------------------------*/
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
/*== code support ============================================================*/
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
/*== SCU cmd if =============================================================*/
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
|
||||
struct drxjscu_cmd {
|
||||
u16 command;
|
||||
/**< Command number */
|
||||
u16 parameter_len;
|
||||
/**< Data length in byte */
|
||||
u16 result_len;
|
||||
/**< result length in byte */
|
||||
u16 *parameter;
|
||||
/**< General purpous param */
|
||||
u16 *result;
|
||||
/**< General purpous param */};
|
||||
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
/*== CTRL CFG related data structures ========================================*/
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
|
||||
/* extra intermediate lock state for VSB,QAM,NTSC */
|
||||
#define DRXJ_DEMOD_LOCK (DRX_LOCK_STATE_1)
|
||||
|
||||
/* OOB lock states */
|
||||
#define DRXJ_OOB_AGC_LOCK (DRX_LOCK_STATE_1) /* analog gain control lock */
|
||||
#define DRXJ_OOB_SYNC_LOCK (DRX_LOCK_STATE_2) /* digital gain control lock */
|
||||
|
||||
/* Intermediate powermodes for DRXJ */
|
||||
#define DRXJ_POWER_DOWN_MAIN_PATH DRX_POWER_MODE_8
|
||||
#define DRXJ_POWER_DOWN_CORE DRX_POWER_MODE_9
|
||||
#define DRXJ_POWER_DOWN_PLL DRX_POWER_MODE_10
|
||||
|
||||
/* supstition for GPIO FNC mux */
|
||||
#define APP_O (0x0000)
|
||||
|
||||
/*#define DRX_CTRL_BASE (0x0000)*/
|
||||
|
||||
#define DRXJ_CTRL_CFG_BASE (0x1000)
|
||||
enum drxj_cfg_type {
|
||||
DRXJ_CFG_AGC_RF = DRXJ_CTRL_CFG_BASE,
|
||||
DRXJ_CFG_AGC_IF,
|
||||
DRXJ_CFG_AGC_INTERNAL,
|
||||
DRXJ_CFG_PRE_SAW,
|
||||
DRXJ_CFG_AFE_GAIN,
|
||||
DRXJ_CFG_SYMBOL_CLK_OFFSET,
|
||||
DRXJ_CFG_ACCUM_CR_RS_CW_ERR,
|
||||
DRXJ_CFG_FEC_MERS_SEQ_COUNT,
|
||||
DRXJ_CFG_OOB_MISC,
|
||||
DRXJ_CFG_SMART_ANT,
|
||||
DRXJ_CFG_OOB_PRE_SAW,
|
||||
DRXJ_CFG_VSB_MISC,
|
||||
DRXJ_CFG_RESET_PACKET_ERR,
|
||||
|
||||
/* ATV (FM) */
|
||||
DRXJ_CFG_ATV_OUTPUT, /* also for FM (SIF control) but not likely */
|
||||
DRXJ_CFG_ATV_MISC,
|
||||
DRXJ_CFG_ATV_EQU_COEF,
|
||||
DRXJ_CFG_ATV_AGC_STATUS, /* also for FM ( IF,RF, audioAGC ) */
|
||||
|
||||
DRXJ_CFG_MPEG_OUTPUT_MISC,
|
||||
DRXJ_CFG_HW_CFG,
|
||||
DRXJ_CFG_OOB_LO_POW,
|
||||
|
||||
DRXJ_CFG_MAX /* dummy, never to be used */};
|
||||
|
||||
/**
|
||||
* /struct enum drxj_cfg_smart_ant_io * smart antenna i/o.
|
||||
*/
|
||||
enum drxj_cfg_smart_ant_io {
|
||||
DRXJ_SMT_ANT_OUTPUT = 0,
|
||||
DRXJ_SMT_ANT_INPUT
|
||||
};
|
||||
|
||||
/**
|
||||
* /struct struct drxj_cfg_smart_ant * Set smart antenna.
|
||||
*/
|
||||
struct drxj_cfg_smart_ant {
|
||||
enum drxj_cfg_smart_ant_io io;
|
||||
u16 ctrl_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* /struct DRXJAGCSTATUS_t
|
||||
* AGC status information from the DRXJ-IQM-AF.
|
||||
*/
|
||||
struct drxj_agc_status {
|
||||
u16 IFAGC;
|
||||
u16 RFAGC;
|
||||
u16 digital_agc;
|
||||
};
|
||||
|
||||
/* DRXJ_CFG_AGC_RF, DRXJ_CFG_AGC_IF */
|
||||
|
||||
/**
|
||||
* /struct enum drxj_agc_ctrl_mode * Available AGCs modes in the DRXJ.
|
||||
*/
|
||||
enum drxj_agc_ctrl_mode {
|
||||
DRX_AGC_CTRL_AUTO = 0,
|
||||
DRX_AGC_CTRL_USER,
|
||||
DRX_AGC_CTRL_OFF};
|
||||
|
||||
/**
|
||||
* /struct struct drxj_cfg_agc * Generic interface for all AGCs present on the DRXJ.
|
||||
*/
|
||||
struct drxj_cfg_agc {
|
||||
enum drx_standard standard; /* standard for which these settings apply */
|
||||
enum drxj_agc_ctrl_mode ctrl_mode; /* off, user, auto */
|
||||
u16 output_level; /* range dependent on AGC */
|
||||
u16 min_output_level; /* range dependent on AGC */
|
||||
u16 max_output_level; /* range dependent on AGC */
|
||||
u16 speed; /* range dependent on AGC */
|
||||
u16 top; /* rf-agc take over point */
|
||||
u16 cut_off_current; /* rf-agc is accelerated if output current
|
||||
is below cut-off current */};
|
||||
|
||||
/* DRXJ_CFG_PRE_SAW */
|
||||
|
||||
/**
|
||||
* /struct struct drxj_cfg_pre_saw * Interface to configure pre SAW sense.
|
||||
*/
|
||||
struct drxj_cfg_pre_saw {
|
||||
enum drx_standard standard; /* standard to which these settings apply */
|
||||
u16 reference; /* pre SAW reference value, range 0 .. 31 */
|
||||
bool use_pre_saw; /* true algorithms must use pre SAW sense */};
|
||||
|
||||
/* DRXJ_CFG_AFE_GAIN */
|
||||
|
||||
/**
|
||||
* /struct struct drxj_cfg_afe_gain * Interface to configure gain of AFE (LNA + PGA).
|
||||
*/
|
||||
struct drxj_cfg_afe_gain {
|
||||
enum drx_standard standard; /* standard to which these settings apply */
|
||||
u16 gain; /* gain in 0.1 dB steps, DRXJ range 140 .. 335 */};
|
||||
|
||||
/**
|
||||
* /struct drxjrs_errors
|
||||
* Available failure information in DRXJ_FEC_RS.
|
||||
*
|
||||
* Container for errors that are received in the most recently finished measurment period
|
||||
*
|
||||
*/
|
||||
struct drxjrs_errors {
|
||||
u16 nr_bit_errors;
|
||||
/**< no of pre RS bit errors */
|
||||
u16 nr_symbol_errors;
|
||||
/**< no of pre RS symbol errors */
|
||||
u16 nr_packet_errors;
|
||||
/**< no of pre RS packet errors */
|
||||
u16 nr_failures;
|
||||
/**< no of post RS failures to decode */
|
||||
u16 nr_snc_par_fail_count;
|
||||
/**< no of post RS bit erros */
|
||||
};
|
||||
|
||||
/**
|
||||
* /struct struct drxj_cfg_vsb_misc * symbol error rate
|
||||
*/
|
||||
struct drxj_cfg_vsb_misc {
|
||||
u32 symb_error;
|
||||
/**< symbol error rate sps */};
|
||||
|
||||
/**
|
||||
* /enum enum drxj_mpeg_output_clock_rate * Mpeg output clock rate.
|
||||
*
|
||||
*/
|
||||
enum drxj_mpeg_start_width {
|
||||
DRXJ_MPEG_START_WIDTH_1CLKCYC,
|
||||
DRXJ_MPEG_START_WIDTH_8CLKCYC};
|
||||
|
||||
/**
|
||||
* /enum enum drxj_mpeg_output_clock_rate * Mpeg output clock rate.
|
||||
*
|
||||
*/
|
||||
enum drxj_mpeg_output_clock_rate {
|
||||
DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO,
|
||||
DRXJ_MPEGOUTPUT_CLOCK_RATE_75973K,
|
||||
DRXJ_MPEGOUTPUT_CLOCK_RATE_50625K,
|
||||
DRXJ_MPEGOUTPUT_CLOCK_RATE_37968K,
|
||||
DRXJ_MPEGOUTPUT_CLOCK_RATE_30375K,
|
||||
DRXJ_MPEGOUTPUT_CLOCK_RATE_25313K,
|
||||
DRXJ_MPEGOUTPUT_CLOCK_RATE_21696K};
|
||||
|
||||
/**
|
||||
* /struct DRXJCfgMisc_t
|
||||
* Change TEI bit of MPEG output
|
||||
* reverse MPEG output bit order
|
||||
* set MPEG output clock rate
|
||||
*/
|
||||
struct drxj_cfg_mpeg_output_misc {
|
||||
bool disable_tei_handling; /**< if true pass (not change) TEI bit */
|
||||
bool bit_reverse_mpeg_outout; /**< if true, parallel: msb on MD0; serial: lsb out first */
|
||||
enum drxj_mpeg_output_clock_rate mpeg_output_clock_rate;
|
||||
/**< set MPEG output clock rate that overwirtes the derived one from symbol rate */
|
||||
enum drxj_mpeg_start_width mpeg_start_width; /**< set MPEG output start width */};
|
||||
|
||||
/**
|
||||
* /enum enum drxj_xtal_freq * Supported external crystal reference frequency.
|
||||
*/
|
||||
enum drxj_xtal_freq {
|
||||
DRXJ_XTAL_FREQ_RSVD,
|
||||
DRXJ_XTAL_FREQ_27MHZ,
|
||||
DRXJ_XTAL_FREQ_20P25MHZ,
|
||||
DRXJ_XTAL_FREQ_4MHZ};
|
||||
|
||||
/**
|
||||
* /enum enum drxj_xtal_freq * Supported external crystal reference frequency.
|
||||
*/
|
||||
enum drxji2c_speed {
|
||||
DRXJ_I2C_SPEED_400KBPS,
|
||||
DRXJ_I2C_SPEED_100KBPS};
|
||||
|
||||
/**
|
||||
* /struct struct drxj_cfg_hw_cfg * Get hw configuration, such as crystal reference frequency, I2C speed, etc...
|
||||
*/
|
||||
struct drxj_cfg_hw_cfg {
|
||||
enum drxj_xtal_freq xtal_freq;
|
||||
/**< crystal reference frequency */
|
||||
enum drxji2c_speed i2c_speed;
|
||||
/**< 100 or 400 kbps */};
|
||||
|
||||
/*
|
||||
* DRXJ_CFG_ATV_MISC
|
||||
*/
|
||||
struct drxj_cfg_atv_misc {
|
||||
s16 peak_filter; /* -8 .. 15 */
|
||||
u16 noise_filter; /* 0 .. 15 */};
|
||||
|
||||
/*
|
||||
* struct drxj_cfg_oob_misc */
|
||||
#define DRXJ_OOB_STATE_RESET 0x0
|
||||
#define DRXJ_OOB_STATE_AGN_HUNT 0x1
|
||||
#define DRXJ_OOB_STATE_DGN_HUNT 0x2
|
||||
#define DRXJ_OOB_STATE_AGC_HUNT 0x3
|
||||
#define DRXJ_OOB_STATE_FRQ_HUNT 0x4
|
||||
#define DRXJ_OOB_STATE_PHA_HUNT 0x8
|
||||
#define DRXJ_OOB_STATE_TIM_HUNT 0x10
|
||||
#define DRXJ_OOB_STATE_EQU_HUNT 0x20
|
||||
#define DRXJ_OOB_STATE_EQT_HUNT 0x30
|
||||
#define DRXJ_OOB_STATE_SYNC 0x40
|
||||
|
||||
struct drxj_cfg_oob_misc {
|
||||
struct drxj_agc_status agc;
|
||||
bool eq_lock;
|
||||
bool sym_timing_lock;
|
||||
bool phase_lock;
|
||||
bool freq_lock;
|
||||
bool dig_gain_lock;
|
||||
bool ana_gain_lock;
|
||||
u8 state;
|
||||
};
|
||||
|
||||
/*
|
||||
* Index of in array of coef
|
||||
*/
|
||||
enum drxj_cfg_oob_lo_power {
|
||||
DRXJ_OOB_LO_POW_MINUS0DB = 0,
|
||||
DRXJ_OOB_LO_POW_MINUS5DB,
|
||||
DRXJ_OOB_LO_POW_MINUS10DB,
|
||||
DRXJ_OOB_LO_POW_MINUS15DB,
|
||||
DRXJ_OOB_LO_POW_MAX};
|
||||
|
||||
/*
|
||||
* DRXJ_CFG_ATV_EQU_COEF
|
||||
*/
|
||||
struct drxj_cfg_atv_equ_coef {
|
||||
s16 coef0; /* -256 .. 255 */
|
||||
s16 coef1; /* -256 .. 255 */
|
||||
s16 coef2; /* -256 .. 255 */
|
||||
s16 coef3; /* -256 .. 255 */};
|
||||
|
||||
/*
|
||||
* Index of in array of coef
|
||||
*/
|
||||
enum drxj_coef_array_index {
|
||||
DRXJ_COEF_IDX_MN = 0,
|
||||
DRXJ_COEF_IDX_FM,
|
||||
DRXJ_COEF_IDX_L,
|
||||
DRXJ_COEF_IDX_LP,
|
||||
DRXJ_COEF_IDX_BG,
|
||||
DRXJ_COEF_IDX_DK,
|
||||
DRXJ_COEF_IDX_I,
|
||||
DRXJ_COEF_IDX_MAX};
|
||||
|
||||
/*
|
||||
* DRXJ_CFG_ATV_OUTPUT
|
||||
*/
|
||||
|
||||
/**
|
||||
* /enum DRXJAttenuation_t
|
||||
* Attenuation setting for SIF AGC.
|
||||
*
|
||||
*/
|
||||
enum drxjsif_attenuation {
|
||||
DRXJ_SIF_ATTENUATION_0DB,
|
||||
DRXJ_SIF_ATTENUATION_3DB,
|
||||
DRXJ_SIF_ATTENUATION_6DB,
|
||||
DRXJ_SIF_ATTENUATION_9DB};
|
||||
|
||||
/**
|
||||
* /struct struct drxj_cfg_atv_output * SIF attenuation setting.
|
||||
*
|
||||
*/
|
||||
struct drxj_cfg_atv_output {
|
||||
bool enable_cvbs_output; /* true= enabled */
|
||||
bool enable_sif_output; /* true= enabled */
|
||||
enum drxjsif_attenuation sif_attenuation;
|
||||
};
|
||||
|
||||
/*
|
||||
DRXJ_CFG_ATV_AGC_STATUS (get only)
|
||||
*/
|
||||
/* TODO : AFE interface not yet finished, subject to change */
|
||||
struct drxj_cfg_atv_agc_status {
|
||||
u16 rf_agc_gain; /* 0 .. 877 uA */
|
||||
u16 if_agc_gain; /* 0 .. 877 uA */
|
||||
s16 video_agc_gain; /* -75 .. 1972 in 0.1 dB steps */
|
||||
s16 audio_agc_gain; /* -4 .. 1020 in 0.1 dB steps */
|
||||
u16 rf_agc_loop_gain; /* 0 .. 7 */
|
||||
u16 if_agc_loop_gain; /* 0 .. 7 */
|
||||
u16 video_agc_loop_gain; /* 0 .. 7 */};
|
||||
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
/*== CTRL related data structures ============================================*/
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
|
||||
/* NONE */
|
||||
|
||||
/*============================================================================*/
|
||||
/*============================================================================*/
|
||||
|
||||
/*========================================*/
|
||||
/**
|
||||
* /struct struct drxj_data * DRXJ specific attributes.
|
||||
*
|
||||
* Global data container for DRXJ specific data.
|
||||
*
|
||||
*/
|
||||
struct drxj_data {
|
||||
/* device capabilties (determined during drx_open()) */
|
||||
bool has_lna; /**< true if LNA (aka PGA) present */
|
||||
bool has_oob; /**< true if OOB supported */
|
||||
bool has_ntsc; /**< true if NTSC supported */
|
||||
bool has_btsc; /**< true if BTSC supported */
|
||||
bool has_smatx; /**< true if mat_tx is available */
|
||||
bool has_smarx; /**< true if mat_rx is available */
|
||||
bool has_gpio; /**< true if GPIO is available */
|
||||
bool has_irqn; /**< true if IRQN is available */
|
||||
/* A1/A2/A... */
|
||||
u8 mfx; /**< metal fix */
|
||||
|
||||
/* tuner settings */
|
||||
bool mirror_freq_spect_oob;/**< tuner inversion (true = tuner mirrors the signal */
|
||||
|
||||
/* standard/channel settings */
|
||||
enum drx_standard standard; /**< current standard information */
|
||||
enum drx_modulation constellation;
|
||||
/**< current constellation */
|
||||
s32 frequency; /**< center signal frequency in KHz */
|
||||
enum drx_bandwidth curr_bandwidth;
|
||||
/**< current channel bandwidth */
|
||||
enum drx_mirror mirror; /**< current channel mirror */
|
||||
|
||||
/* signal quality information */
|
||||
u32 fec_bits_desired; /**< BER accounting period */
|
||||
u16 fec_vd_plen; /**< no of trellis symbols: VD SER measurement period */
|
||||
u16 qam_vd_prescale; /**< Viterbi Measurement Prescale */
|
||||
u16 qam_vd_period; /**< Viterbi Measurement period */
|
||||
u16 fec_rs_plen; /**< defines RS BER measurement period */
|
||||
u16 fec_rs_prescale; /**< ReedSolomon Measurement Prescale */
|
||||
u16 fec_rs_period; /**< ReedSolomon Measurement period */
|
||||
bool reset_pkt_err_acc; /**< Set a flag to reset accumulated packet error */
|
||||
u16 pkt_err_acc_start; /**< Set a flag to reset accumulated packet error */
|
||||
|
||||
/* HI configuration */
|
||||
u16 hi_cfg_timing_div; /**< HI Configure() parameter 2 */
|
||||
u16 hi_cfg_bridge_delay; /**< HI Configure() parameter 3 */
|
||||
u16 hi_cfg_wake_up_key; /**< HI Configure() parameter 4 */
|
||||
u16 hi_cfg_ctrl; /**< HI Configure() parameter 5 */
|
||||
u16 hi_cfg_transmit; /**< HI Configure() parameter 6 */
|
||||
|
||||
/* UIO configuartion */
|
||||
enum drxuio_mode uio_sma_rx_mode;/**< current mode of SmaRx pin */
|
||||
enum drxuio_mode uio_sma_tx_mode;/**< current mode of SmaTx pin */
|
||||
enum drxuio_mode uio_gpio_mode; /**< current mode of ASEL pin */
|
||||
enum drxuio_mode uio_irqn_mode; /**< current mode of IRQN pin */
|
||||
|
||||
/* IQM fs frequecy shift and inversion */
|
||||
u32 iqm_fs_rate_ofs; /**< frequency shifter setting after setchannel */
|
||||
bool pos_image; /**< Ture: positive image */
|
||||
/* IQM RC frequecy shift */
|
||||
u32 iqm_rc_rate_ofs; /**< frequency shifter setting after setchannel */
|
||||
|
||||
/* ATV configuartion */
|
||||
u32 atv_cfg_changed_flags; /**< flag: flags cfg changes */
|
||||
s16 atv_top_equ0[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU0__A */
|
||||
s16 atv_top_equ1[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU1__A */
|
||||
s16 atv_top_equ2[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU2__A */
|
||||
s16 atv_top_equ3[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU3__A */
|
||||
bool phase_correction_bypass;/**< flag: true=bypass */
|
||||
s16 atv_top_vid_peak; /**< shadow of ATV_TOP_VID_PEAK__A */
|
||||
u16 atv_top_noise_th; /**< shadow of ATV_TOP_NOISE_TH__A */
|
||||
bool enable_cvbs_output; /**< flag CVBS ouput enable */
|
||||
bool enable_sif_output; /**< flag SIF ouput enable */
|
||||
enum drxjsif_attenuation sif_attenuation;
|
||||
/**< current SIF att setting */
|
||||
/* Agc configuration for QAM and VSB */
|
||||
struct drxj_cfg_agc qam_rf_agc_cfg; /**< qam RF AGC config */
|
||||
struct drxj_cfg_agc qam_if_agc_cfg; /**< qam IF AGC config */
|
||||
struct drxj_cfg_agc vsb_rf_agc_cfg; /**< vsb RF AGC config */
|
||||
struct drxj_cfg_agc vsb_if_agc_cfg; /**< vsb IF AGC config */
|
||||
|
||||
/* PGA gain configuration for QAM and VSB */
|
||||
u16 qam_pga_cfg; /**< qam PGA config */
|
||||
u16 vsb_pga_cfg; /**< vsb PGA config */
|
||||
|
||||
/* Pre SAW configuration for QAM and VSB */
|
||||
struct drxj_cfg_pre_saw qam_pre_saw_cfg;
|
||||
/**< qam pre SAW config */
|
||||
struct drxj_cfg_pre_saw vsb_pre_saw_cfg;
|
||||
/**< qam pre SAW config */
|
||||
|
||||
/* Version information */
|
||||
char v_text[2][12]; /**< allocated text versions */
|
||||
struct drx_version v_version[2]; /**< allocated versions structs */
|
||||
struct drx_version_list v_list_elements[2];
|
||||
/**< allocated version list */
|
||||
|
||||
/* smart antenna configuration */
|
||||
bool smart_ant_inverted;
|
||||
|
||||
/* Tracking filter setting for OOB */
|
||||
u16 oob_trk_filter_cfg[8];
|
||||
bool oob_power_on;
|
||||
|
||||
/* MPEG static bitrate setting */
|
||||
u32 mpeg_ts_static_bitrate; /**< bitrate static MPEG output */
|
||||
bool disable_te_ihandling; /**< MPEG TS TEI handling */
|
||||
bool bit_reverse_mpeg_outout;/**< MPEG output bit order */
|
||||
enum drxj_mpeg_output_clock_rate mpeg_output_clock_rate;
|
||||
/**< MPEG output clock rate */
|
||||
enum drxj_mpeg_start_width mpeg_start_width;
|
||||
/**< MPEG Start width */
|
||||
|
||||
/* Pre SAW & Agc configuration for ATV */
|
||||
struct drxj_cfg_pre_saw atv_pre_saw_cfg;
|
||||
/**< atv pre SAW config */
|
||||
struct drxj_cfg_agc atv_rf_agc_cfg; /**< atv RF AGC config */
|
||||
struct drxj_cfg_agc atv_if_agc_cfg; /**< atv IF AGC config */
|
||||
u16 atv_pga_cfg; /**< atv pga config */
|
||||
|
||||
u32 curr_symbol_rate;
|
||||
|
||||
/* pin-safe mode */
|
||||
bool pdr_safe_mode; /**< PDR safe mode activated */
|
||||
u16 pdr_safe_restore_val_gpio;
|
||||
u16 pdr_safe_restore_val_v_sync;
|
||||
u16 pdr_safe_restore_val_sma_rx;
|
||||
u16 pdr_safe_restore_val_sma_tx;
|
||||
|
||||
/* OOB pre-saw value */
|
||||
u16 oob_pre_saw;
|
||||
enum drxj_cfg_oob_lo_power oob_lo_pow;
|
||||
|
||||
struct drx_aud_data aud_data;
|
||||
/**< audio storage */};
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Access MACROS
|
||||
-------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Compilable references to attributes
|
||||
* \param d pointer to demod instance
|
||||
*
|
||||
* Used as main reference to an attribute field.
|
||||
* Can be used by both macro implementation and function implementation.
|
||||
* These macros are defined to avoid duplication of code in macro and function
|
||||
* definitions that handle access of demod common or extended attributes.
|
||||
*
|
||||
*/
|
||||
|
||||
#define DRXJ_ATTR_BTSC_DETECT(d) \
|
||||
(((struct drxj_data *)(d)->my_ext_attr)->aud_data.btsc_detect)
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
DEFINES
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \def DRXJ_NTSC_CARRIER_FREQ_OFFSET
|
||||
* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
|
||||
*
|
||||
* For NTSC standard.
|
||||
* NTSC channels are listed by their picture carrier frequency (Fpc).
|
||||
* The function DRX_CTRL_SET_CHANNEL requires the centre frequency as input.
|
||||
* In case the tuner module is not used the DRX-J requires that the tuner is
|
||||
* tuned to the centre frequency of the channel:
|
||||
*
|
||||
* Fcentre = Fpc + DRXJ_NTSC_CARRIER_FREQ_OFFSET
|
||||
*
|
||||
*/
|
||||
#define DRXJ_NTSC_CARRIER_FREQ_OFFSET ((s32)(1750))
|
||||
|
||||
/**
|
||||
* \def DRXJ_PAL_SECAM_BG_CARRIER_FREQ_OFFSET
|
||||
* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
|
||||
*
|
||||
* For PAL/SECAM - BG standard. This define is needed in case the tuner module
|
||||
* is NOT used. PAL/SECAM channels are listed by their picture carrier frequency (Fpc).
|
||||
* The DRX-J requires that the tuner is tuned to:
|
||||
* Fpc + DRXJ_PAL_SECAM_BG_CARRIER_FREQ_OFFSET
|
||||
*
|
||||
* In case the tuner module is used the drxdriver takes care of this.
|
||||
* In case the tuner module is NOT used the application programmer must take
|
||||
* care of this.
|
||||
*
|
||||
*/
|
||||
#define DRXJ_PAL_SECAM_BG_CARRIER_FREQ_OFFSET ((s32)(2375))
|
||||
|
||||
/**
|
||||
* \def DRXJ_PAL_SECAM_DKIL_CARRIER_FREQ_OFFSET
|
||||
* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
|
||||
*
|
||||
* For PAL/SECAM - DK, I, L standards. This define is needed in case the tuner module
|
||||
* is NOT used. PAL/SECAM channels are listed by their picture carrier frequency (Fpc).
|
||||
* The DRX-J requires that the tuner is tuned to:
|
||||
* Fpc + DRXJ_PAL_SECAM_DKIL_CARRIER_FREQ_OFFSET
|
||||
*
|
||||
* In case the tuner module is used the drxdriver takes care of this.
|
||||
* In case the tuner module is NOT used the application programmer must take
|
||||
* care of this.
|
||||
*
|
||||
*/
|
||||
#define DRXJ_PAL_SECAM_DKIL_CARRIER_FREQ_OFFSET ((s32)(2775))
|
||||
|
||||
/**
|
||||
* \def DRXJ_PAL_SECAM_LP_CARRIER_FREQ_OFFSET
|
||||
* \brief Offset from picture carrier to centre frequency in kHz, in RF domain
|
||||
*
|
||||
* For PAL/SECAM - LP standard. This define is needed in case the tuner module
|
||||
* is NOT used. PAL/SECAM channels are listed by their picture carrier frequency (Fpc).
|
||||
* The DRX-J requires that the tuner is tuned to:
|
||||
* Fpc + DRXJ_PAL_SECAM_LP_CARRIER_FREQ_OFFSET
|
||||
*
|
||||
* In case the tuner module is used the drxdriver takes care of this.
|
||||
* In case the tuner module is NOT used the application programmer must take
|
||||
* care of this.
|
||||
*/
|
||||
#define DRXJ_PAL_SECAM_LP_CARRIER_FREQ_OFFSET ((s32)(-3255))
|
||||
|
||||
/**
|
||||
* \def DRXJ_FM_CARRIER_FREQ_OFFSET
|
||||
* \brief Offset from sound carrier to centre frequency in kHz, in RF domain
|
||||
*
|
||||
* For FM standard.
|
||||
* FM channels are listed by their sound carrier frequency (Fsc).
|
||||
* The function DRX_CTRL_SET_CHANNEL requires the Ffm frequency (see below) as
|
||||
* input.
|
||||
* In case the tuner module is not used the DRX-J requires that the tuner is
|
||||
* tuned to the Ffm frequency of the channel.
|
||||
*
|
||||
* Ffm = Fsc + DRXJ_FM_CARRIER_FREQ_OFFSET
|
||||
*
|
||||
*/
|
||||
#define DRXJ_FM_CARRIER_FREQ_OFFSET ((s32)(-3000))
|
||||
|
||||
/* Revision types -------------------------------------------------------*/
|
||||
|
||||
#define DRXJ_TYPE_ID (0x3946000DUL)
|
||||
|
||||
/* Macros ---------------------------------------------------------------*/
|
||||
|
||||
/* Convert OOB lock status to string */
|
||||
#define DRXJ_STR_OOB_LOCKSTATUS(x) ( \
|
||||
(x == DRX_NEVER_LOCK) ? "Never" : \
|
||||
(x == DRX_NOT_LOCKED) ? "No" : \
|
||||
(x == DRX_LOCKED) ? "Locked" : \
|
||||
(x == DRX_LOCK_STATE_1) ? "AGC lock" : \
|
||||
(x == DRX_LOCK_STATE_2) ? "sync lock" : \
|
||||
"(Invalid)")
|
||||
|
||||
#endif /* __DRXJ_H__ */
|
15055
drivers/media/dvb-frontends/drx39xyj/drxj_map.h
Normal file
15055
drivers/media/dvb-frontends/drx39xyj/drxj_map.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -2688,11 +2688,11 @@ static int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
|
||||
status = EnableAndResetMB(state);
|
||||
if (status < 0)
|
||||
break;
|
||||
if (state->type_A)
|
||||
if (state->type_A) {
|
||||
status = ResetCEFR(state);
|
||||
if (status < 0)
|
||||
break;
|
||||
|
||||
}
|
||||
if (fw) {
|
||||
status = DownloadMicrocode(state, fw, fw_size);
|
||||
if (status < 0)
|
||||
|
@ -616,7 +616,7 @@ static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
snr_reading = dvbs2_noise_reading / tmp;
|
||||
if (snr_reading > 80)
|
||||
snr_reading = 80;
|
||||
*snr = -(dvbs2_snr_tab[snr_reading] / 1000);
|
||||
*snr = -(dvbs2_snr_tab[snr_reading - 1] / 1000);
|
||||
}
|
||||
dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
|
||||
snr_reading, *snr);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,237 +0,0 @@
|
||||
/*
|
||||
* Driver for it913x Frontend
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
*
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
|
||||
*/
|
||||
|
||||
#ifndef IT913X_FE_H
|
||||
#define IT913X_FE_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
struct ite_config {
|
||||
u8 chip_ver;
|
||||
u16 chip_type;
|
||||
u32 firmware;
|
||||
u8 firmware_ver;
|
||||
u8 adc_x2;
|
||||
u8 tuner_id_0;
|
||||
u8 tuner_id_1;
|
||||
u8 dual_mode;
|
||||
u8 adf;
|
||||
/* option to read SIGNAL_LEVEL */
|
||||
u8 read_slevel;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DVB_IT913X_FE)
|
||||
extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
|
||||
u8 i2c_addr, struct ite_config *config);
|
||||
#else
|
||||
static inline struct dvb_frontend *it913x_fe_attach(
|
||||
struct i2c_adapter *i2c_adap,
|
||||
u8 i2c_addr, struct ite_config *config)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_IT913X_FE */
|
||||
#define I2C_BASE_ADDR 0x10
|
||||
#define DEV_0 0x0
|
||||
#define DEV_1 0x10
|
||||
#define PRO_LINK 0x0
|
||||
#define PRO_DMOD 0x1
|
||||
#define DEV_0_DMOD (PRO_DMOD << 0x7)
|
||||
#define DEV_1_DMOD (DEV_0_DMOD | DEV_1)
|
||||
#define CHIP2_I2C_ADDR 0x3a
|
||||
|
||||
#define AFE_MEM0 0xfb24
|
||||
|
||||
#define MP2_SW_RST 0xf99d
|
||||
#define MP2IF2_SW_RST 0xf9a4
|
||||
|
||||
#define PADODPU 0xd827
|
||||
#define THIRDODPU 0xd828
|
||||
#define AGC_O_D 0xd829
|
||||
|
||||
#define EP0_TX_EN 0xdd11
|
||||
#define EP0_TX_NAK 0xdd13
|
||||
#define EP4_TX_LEN_LSB 0xdd88
|
||||
#define EP4_TX_LEN_MSB 0xdd89
|
||||
#define EP4_MAX_PKT 0xdd0c
|
||||
#define EP5_TX_LEN_LSB 0xdd8a
|
||||
#define EP5_TX_LEN_MSB 0xdd8b
|
||||
#define EP5_MAX_PKT 0xdd0d
|
||||
|
||||
#define IO_MUX_POWER_CLK 0xd800
|
||||
#define CLK_O_EN 0xd81a
|
||||
#define I2C_CLK 0xf103
|
||||
#define I2C_CLK_100 0x7
|
||||
#define I2C_CLK_400 0x1a
|
||||
|
||||
#define D_TPSD_LOCK 0xf5a9
|
||||
#define MP2IF2_EN 0xf9a3
|
||||
#define MP2IF_SERIAL 0xf985
|
||||
#define TSIS_ENABLE 0xf9cd
|
||||
#define MP2IF2_HALF_PSB 0xf9a5
|
||||
#define MP2IF_STOP_EN 0xf9b5
|
||||
#define MPEG_FULL_SPEED 0xf990
|
||||
#define TOP_HOSTB_SER_MODE 0xd91c
|
||||
|
||||
#define PID_RST 0xf992
|
||||
#define PID_EN 0xf993
|
||||
#define PID_INX_EN 0xf994
|
||||
#define PID_INX 0xf995
|
||||
#define PID_LSB 0xf996
|
||||
#define PID_MSB 0xf997
|
||||
|
||||
#define MP2IF_MPEG_PAR_MODE 0xf986
|
||||
#define DCA_UPPER_CHIP 0xf731
|
||||
#define DCA_LOWER_CHIP 0xf732
|
||||
#define DCA_PLATCH 0xf730
|
||||
#define DCA_FPGA_LATCH 0xf778
|
||||
#define DCA_STAND_ALONE 0xf73c
|
||||
#define DCA_ENABLE 0xf776
|
||||
|
||||
#define DVBT_INTEN 0xf41f
|
||||
#define DVBT_ENABLE 0xf41a
|
||||
#define HOSTB_DCA_LOWER 0xd91f
|
||||
#define HOSTB_MPEG_PAR_MODE 0xd91b
|
||||
#define HOSTB_MPEG_SER_MODE 0xd91c
|
||||
#define HOSTB_MPEG_SER_DO7 0xd91d
|
||||
#define HOSTB_DCA_UPPER 0xd91e
|
||||
#define PADMISCDR2 0xd830
|
||||
#define PADMISCDR4 0xd831
|
||||
#define PADMISCDR8 0xd832
|
||||
#define PADMISCDRSR 0xd833
|
||||
#define LOCK3_OUT 0xd8fd
|
||||
|
||||
#define GPIOH1_O 0xd8af
|
||||
#define GPIOH1_EN 0xd8b0
|
||||
#define GPIOH1_ON 0xd8b1
|
||||
#define GPIOH3_O 0xd8b3
|
||||
#define GPIOH3_EN 0xd8b4
|
||||
#define GPIOH3_ON 0xd8b5
|
||||
#define GPIOH5_O 0xd8bb
|
||||
#define GPIOH5_EN 0xd8bc
|
||||
#define GPIOH5_ON 0xd8bd
|
||||
|
||||
#define AFE_MEM0 0xfb24
|
||||
|
||||
#define REG_TPSD_TX_MODE 0xf900
|
||||
#define REG_TPSD_GI 0xf901
|
||||
#define REG_TPSD_HIER 0xf902
|
||||
#define REG_TPSD_CONST 0xf903
|
||||
#define REG_BW 0xf904
|
||||
#define REG_PRIV 0xf905
|
||||
#define REG_TPSD_HP_CODE 0xf906
|
||||
#define REG_TPSD_LP_CODE 0xf907
|
||||
|
||||
#define MP2IF_SYNC_LK 0xf999
|
||||
#define ADC_FREQ 0xf1cd
|
||||
|
||||
#define TRIGGER_OFSM 0x0000
|
||||
/* COEFF Registers start at 0x0001 to 0x0020 */
|
||||
#define COEFF_1_2048 0x0001
|
||||
#define XTAL_CLK 0x0025
|
||||
#define BFS_FCW 0x0029
|
||||
|
||||
/* Error Regs */
|
||||
#define RSD_ABORT_PKT_LSB 0x0032
|
||||
#define RSD_ABORT_PKT_MSB 0x0033
|
||||
#define RSD_BIT_ERR_0_7 0x0034
|
||||
#define RSD_BIT_ERR_8_15 0x0035
|
||||
#define RSD_BIT_ERR_23_16 0x0036
|
||||
#define RSD_BIT_COUNT_LSB 0x0037
|
||||
#define RSD_BIT_COUNT_MSB 0x0038
|
||||
|
||||
#define TPSD_LOCK 0x003c
|
||||
#define TRAINING_MODE 0x0040
|
||||
#define ADC_X_2 0x0045
|
||||
#define TUNER_ID 0x0046
|
||||
#define EMPTY_CHANNEL_STATUS 0x0047
|
||||
#define SIGNAL_LEVEL 0x0048
|
||||
#define SIGNAL_QUALITY 0x0049
|
||||
#define EST_SIGNAL_LEVEL 0x004a
|
||||
#define FREE_BAND 0x004b
|
||||
#define SUSPEND_FLAG 0x004c
|
||||
#define VAR_P_INBAND 0x00f7
|
||||
|
||||
/* Build in tuner types */
|
||||
#define IT9137 0x38
|
||||
#define IT9135_38 0x38
|
||||
#define IT9135_51 0x51
|
||||
#define IT9135_52 0x52
|
||||
#define IT9135_60 0x60
|
||||
#define IT9135_61 0x61
|
||||
#define IT9135_62 0x62
|
||||
|
||||
enum {
|
||||
CMD_DEMOD_READ = 0,
|
||||
CMD_DEMOD_WRITE,
|
||||
CMD_TUNER_READ,
|
||||
CMD_TUNER_WRITE,
|
||||
CMD_REG_EEPROM_READ,
|
||||
CMD_REG_EEPROM_WRITE,
|
||||
CMD_DATA_READ,
|
||||
CMD_VAR_READ = 8,
|
||||
CMD_VAR_WRITE,
|
||||
CMD_PLATFORM_GET,
|
||||
CMD_PLATFORM_SET,
|
||||
CMD_IP_CACHE,
|
||||
CMD_IP_ADD,
|
||||
CMD_IP_REMOVE,
|
||||
CMD_PID_ADD,
|
||||
CMD_PID_REMOVE,
|
||||
CMD_SIPSI_GET,
|
||||
CMD_SIPSI_MPE_RESET,
|
||||
CMD_H_PID_ADD = 0x15,
|
||||
CMD_H_PID_REMOVE,
|
||||
CMD_ABORT,
|
||||
CMD_IR_GET,
|
||||
CMD_IR_SET,
|
||||
CMD_FW_DOWNLOAD = 0x21,
|
||||
CMD_QUERYINFO,
|
||||
CMD_BOOT,
|
||||
CMD_FW_DOWNLOAD_BEGIN,
|
||||
CMD_FW_DOWNLOAD_END,
|
||||
CMD_RUN_CODE,
|
||||
CMD_SCATTER_READ = 0x28,
|
||||
CMD_SCATTER_WRITE,
|
||||
CMD_GENERIC_READ,
|
||||
CMD_GENERIC_WRITE
|
||||
};
|
||||
|
||||
enum {
|
||||
READ_LONG,
|
||||
WRITE_LONG,
|
||||
READ_SHORT,
|
||||
WRITE_SHORT,
|
||||
READ_DATA,
|
||||
WRITE_DATA,
|
||||
WRITE_CMD,
|
||||
};
|
||||
|
||||
enum {
|
||||
IT9135_AUTO = 0,
|
||||
IT9137_FW,
|
||||
IT9135_V1_FW,
|
||||
IT9135_V2_FW,
|
||||
};
|
||||
|
||||
#endif /* IT913X_FE_H */
|
@ -271,6 +271,13 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
|
||||
ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_frequency);
|
||||
if (ret)
|
||||
goto err;
|
||||
} else {
|
||||
/*
|
||||
* Use nominal target frequency as tuner driver does not provide
|
||||
* actual frequency used. Carrier offset calculation is not
|
||||
* valid.
|
||||
*/
|
||||
tuner_frequency = c->frequency;
|
||||
}
|
||||
|
||||
/* reset */
|
||||
@ -428,18 +435,10 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
|
||||
goto err;
|
||||
|
||||
switch (target_mclk) {
|
||||
case 72000:
|
||||
u8tmp1 = 0x00; /* 0b00 */
|
||||
u8tmp2 = 0x03; /* 0b11 */
|
||||
break;
|
||||
case 96000:
|
||||
u8tmp1 = 0x02; /* 0b10 */
|
||||
u8tmp2 = 0x01; /* 0b01 */
|
||||
break;
|
||||
case 115200:
|
||||
u8tmp1 = 0x01; /* 0b01 */
|
||||
u8tmp2 = 0x01; /* 0b01 */
|
||||
break;
|
||||
case 144000:
|
||||
u8tmp1 = 0x00; /* 0b00 */
|
||||
u8tmp2 = 0x01; /* 0b01 */
|
||||
@ -448,10 +447,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
|
||||
u8tmp1 = 0x03; /* 0b11 */
|
||||
u8tmp2 = 0x00; /* 0b00 */
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid target_mclk\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = m88ds3103_wr_reg_mask(priv, 0x22, u8tmp1 << 6, 0xc0);
|
||||
@ -711,9 +706,6 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
|
||||
case 1:
|
||||
c->inversion = INVERSION_ON;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
switch ((buf[1] >> 5) & 0x07) {
|
||||
@ -793,9 +785,6 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
|
||||
case 1:
|
||||
c->pilot = PILOT_ON;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid pilot\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
switch ((buf[0] >> 6) & 0x07) {
|
||||
@ -823,9 +812,6 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
|
||||
case 1:
|
||||
c->inversion = INVERSION_ON;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
switch ((buf[2] >> 0) & 0x03) {
|
||||
@ -958,7 +944,7 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe,
|
||||
switch (fe_sec_tone_mode) {
|
||||
case SEC_TONE_ON:
|
||||
tone = 0;
|
||||
reg_a1_mask = 0x87;
|
||||
reg_a1_mask = 0x47;
|
||||
break;
|
||||
case SEC_TONE_OFF:
|
||||
tone = 1;
|
||||
|
@ -715,6 +715,22 @@ static int m88rs2000_get_frontend(struct dvb_frontend *fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m88rs2000_get_tune_settings(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_tune_settings *tune)
|
||||
{
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
|
||||
if (c->symbol_rate > 3000000)
|
||||
tune->min_delay_ms = 2000;
|
||||
else
|
||||
tune->min_delay_ms = 3000;
|
||||
|
||||
tune->step_size = c->symbol_rate / 16000;
|
||||
tune->max_drift = c->symbol_rate / 2000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
{
|
||||
struct m88rs2000_state *state = fe->demodulator_priv;
|
||||
@ -746,7 +762,7 @@ static struct dvb_frontend_ops m88rs2000_ops = {
|
||||
.symbol_rate_tolerance = 500, /* ppm */
|
||||
.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
|
||||
FE_CAN_QPSK |
|
||||
FE_CAN_QPSK | FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_AUTO
|
||||
},
|
||||
|
||||
@ -766,6 +782,7 @@ static struct dvb_frontend_ops m88rs2000_ops = {
|
||||
|
||||
.set_frontend = m88rs2000_set_frontend,
|
||||
.get_frontend = m88rs2000_get_frontend,
|
||||
.get_tune_settings = m88rs2000_get_tune_settings,
|
||||
};
|
||||
|
||||
struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
|
||||
*
|
||||
* Copyright (C) 2010-2013 Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Copyright (C) 2010-2013 Mauro Carvalho Chehab
|
||||
* Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@ -2156,5 +2156,5 @@ static struct dvb_frontend_ops mb86a20s_ops = {
|
||||
};
|
||||
|
||||
MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Fujitsu mb86a20s driver
|
||||
*
|
||||
* Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Copyright (C) 2010 Mauro Carvalho Chehab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
|
@ -24,11 +24,6 @@
|
||||
|
||||
/* Max transfer size done by I2C transfer functions */
|
||||
#define MAX_XFER_SIZE 64
|
||||
|
||||
int rtl2832_debug;
|
||||
module_param_named(debug, rtl2832_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
|
||||
|
||||
#define REG_MASK(b) (BIT(b + 1) - 1)
|
||||
|
||||
static const struct rtl2832_reg_entry registers[] = {
|
||||
@ -185,12 +180,13 @@ static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
|
||||
buf[0] = reg;
|
||||
memcpy(&buf[1], val, len);
|
||||
|
||||
ret = i2c_transfer(priv->i2c, msg, 1);
|
||||
ret = i2c_transfer(priv->i2c_adapter, msg, 1);
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
|
||||
"len=%d\n", KBUILD_MODNAME, ret, reg, len);
|
||||
dev_warn(&priv->i2c->dev,
|
||||
"%s: i2c wr failed=%d reg=%02x len=%d\n",
|
||||
KBUILD_MODNAME, ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
return ret;
|
||||
@ -214,12 +210,13 @@ static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(priv->i2c, msg, 2);
|
||||
ret = i2c_transfer(priv->i2c_adapter, msg, 2);
|
||||
if (ret == 2) {
|
||||
ret = 0;
|
||||
} else {
|
||||
dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
|
||||
"len=%d\n", KBUILD_MODNAME, ret, reg, len);
|
||||
dev_warn(&priv->i2c->dev,
|
||||
"%s: i2c rd failed=%d reg=%02x len=%d\n",
|
||||
KBUILD_MODNAME, ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
return ret;
|
||||
@ -417,7 +414,7 @@ static int rtl2832_set_if(struct dvb_frontend *fe, u32 if_freq)
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
|
||||
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl2832_init(struct dvb_frontend *fe)
|
||||
@ -514,15 +511,10 @@ static int rtl2832_init(struct dvb_frontend *fe)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!fe->ops.tuner_ops.get_if_frequency) {
|
||||
ret = rtl2832_set_if(fe, priv->cfg.if_dvbt);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* r820t NIM code does a software reset here at the demod -
|
||||
* may not be needed, as there's already a software reset at set_params()
|
||||
* may not be needed, as there's already a software reset at
|
||||
* set_params()
|
||||
*/
|
||||
#if 1
|
||||
/* soft reset */
|
||||
@ -599,9 +591,9 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
|
||||
};
|
||||
|
||||
|
||||
dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
|
||||
"inversion=%d\n", __func__, c->frequency,
|
||||
c->bandwidth_hz, c->inversion);
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
|
||||
__func__, c->frequency, c->bandwidth_hz, c->inversion);
|
||||
|
||||
/* program tuner */
|
||||
if (fe->ops.tuner_ops.set_params)
|
||||
@ -899,9 +891,149 @@ static void rtl2832_release(struct dvb_frontend *fe)
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
|
||||
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
|
||||
cancel_delayed_work_sync(&priv->i2c_gate_work);
|
||||
i2c_del_mux_adapter(priv->i2c_adapter_tuner);
|
||||
i2c_del_mux_adapter(priv->i2c_adapter);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delay mechanism to avoid unneeded I2C gate open / close. Gate close is
|
||||
* delayed here a little bit in order to see if there is sequence of I2C
|
||||
* messages sent to same I2C bus.
|
||||
* We must use unlocked version of __i2c_transfer() in order to avoid deadlock
|
||||
* as lock is already taken by calling muxed i2c_transfer().
|
||||
*/
|
||||
static void rtl2832_i2c_gate_work(struct work_struct *work)
|
||||
{
|
||||
struct rtl2832_priv *priv = container_of(work,
|
||||
struct rtl2832_priv, i2c_gate_work.work);
|
||||
struct i2c_adapter *adap = priv->i2c;
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
struct i2c_msg msg[1] = {
|
||||
{
|
||||
.addr = priv->cfg.i2c_addr,
|
||||
.flags = 0,
|
||||
.len = sizeof(buf),
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
/* select reg bank 1 */
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x01;
|
||||
ret = __i2c_transfer(adap, msg, 1);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
|
||||
priv->page = 1;
|
||||
|
||||
/* close I2C repeater gate */
|
||||
buf[0] = 0x01;
|
||||
buf[1] = 0x10;
|
||||
ret = __i2c_transfer(adap, msg, 1);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
|
||||
priv->i2c_gate_state = 0;
|
||||
|
||||
return;
|
||||
err:
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id)
|
||||
{
|
||||
struct rtl2832_priv *priv = mux_priv;
|
||||
int ret;
|
||||
u8 buf[2], val;
|
||||
struct i2c_msg msg[1] = {
|
||||
{
|
||||
.addr = priv->cfg.i2c_addr,
|
||||
.flags = 0,
|
||||
.len = sizeof(buf),
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
struct i2c_msg msg_rd[2] = {
|
||||
{
|
||||
.addr = priv->cfg.i2c_addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = "\x01",
|
||||
}, {
|
||||
.addr = priv->cfg.i2c_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = 1,
|
||||
.buf = &val,
|
||||
}
|
||||
};
|
||||
|
||||
/* terminate possible gate closing */
|
||||
cancel_delayed_work_sync(&priv->i2c_gate_work);
|
||||
|
||||
if (priv->i2c_gate_state == chan_id)
|
||||
return 0;
|
||||
|
||||
/* select reg bank 1 */
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x01;
|
||||
ret = __i2c_transfer(adap, msg, 1);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
|
||||
priv->page = 1;
|
||||
|
||||
/* we must read that register, otherwise there will be errors */
|
||||
ret = __i2c_transfer(adap, msg_rd, 2);
|
||||
if (ret != 2)
|
||||
goto err;
|
||||
|
||||
/* open or close I2C repeater gate */
|
||||
buf[0] = 0x01;
|
||||
if (chan_id == 1)
|
||||
buf[1] = 0x18; /* open */
|
||||
else
|
||||
buf[1] = 0x10; /* close */
|
||||
|
||||
ret = __i2c_transfer(adap, msg, 1);
|
||||
if (ret != 1)
|
||||
goto err;
|
||||
|
||||
priv->i2c_gate_state = chan_id;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv,
|
||||
u32 chan_id)
|
||||
{
|
||||
struct rtl2832_priv *priv = mux_priv;
|
||||
schedule_delayed_work(&priv->i2c_gate_work, usecs_to_jiffies(100));
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct i2c_adapter *rtl2832_get_i2c_adapter(struct dvb_frontend *fe)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
return priv->i2c_adapter_tuner;
|
||||
}
|
||||
EXPORT_SYMBOL(rtl2832_get_i2c_adapter);
|
||||
|
||||
struct i2c_adapter *rtl2832_get_private_i2c_adapter(struct dvb_frontend *fe)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
return priv->i2c_adapter;
|
||||
}
|
||||
EXPORT_SYMBOL(rtl2832_get_private_i2c_adapter);
|
||||
|
||||
struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
@ -920,12 +1052,25 @@ struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
|
||||
priv->i2c = i2c;
|
||||
priv->tuner = cfg->tuner;
|
||||
memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
|
||||
INIT_DELAYED_WORK(&priv->i2c_gate_work, rtl2832_i2c_gate_work);
|
||||
|
||||
/* create muxed i2c adapter for demod itself */
|
||||
priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0,
|
||||
rtl2832_select, NULL);
|
||||
if (priv->i2c_adapter == NULL)
|
||||
goto err;
|
||||
|
||||
/* check if the demod is there */
|
||||
ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* create muxed i2c adapter for demod tuner bus */
|
||||
priv->i2c_adapter_tuner = i2c_add_mux_adapter(i2c, &i2c->dev, priv,
|
||||
0, 1, 0, rtl2832_select, rtl2832_deselect);
|
||||
if (priv->i2c_adapter_tuner == NULL)
|
||||
goto err;
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
|
||||
priv->fe.demodulator_priv = priv;
|
||||
@ -936,6 +1081,8 @@ struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
|
||||
return &priv->fe;
|
||||
err:
|
||||
dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
if (priv && priv->i2c_adapter)
|
||||
i2c_del_mux_adapter(priv->i2c_adapter);
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -37,13 +37,6 @@ struct rtl2832_config {
|
||||
*/
|
||||
u32 xtal;
|
||||
|
||||
/*
|
||||
* IFs for all used modes.
|
||||
* Hz
|
||||
* 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
|
||||
*/
|
||||
u32 if_dvbt;
|
||||
|
||||
/*
|
||||
* tuner
|
||||
* XXX: This must be keep sync with dvb_usb_rtl28xxu demod driver.
|
||||
@ -58,11 +51,21 @@ struct rtl2832_config {
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DVB_RTL2832)
|
||||
extern struct dvb_frontend *rtl2832_attach(
|
||||
struct dvb_frontend *rtl2832_attach(
|
||||
const struct rtl2832_config *cfg,
|
||||
struct i2c_adapter *i2c
|
||||
);
|
||||
|
||||
extern struct i2c_adapter *rtl2832_get_i2c_adapter(
|
||||
struct dvb_frontend *fe
|
||||
);
|
||||
|
||||
extern struct i2c_adapter *rtl2832_get_private_i2c_adapter(
|
||||
struct dvb_frontend *fe
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *rtl2832_attach(
|
||||
const struct rtl2832_config *config,
|
||||
struct i2c_adapter *i2c
|
||||
@ -71,6 +74,21 @@ static inline struct dvb_frontend *rtl2832_attach(
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct i2c_adapter *rtl2832_get_i2c_adapter(
|
||||
struct dvb_frontend *fe
|
||||
)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct i2c_adapter *rtl2832_get_private_i2c_adapter(
|
||||
struct dvb_frontend *fe
|
||||
)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -23,9 +23,12 @@
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "rtl2832.h"
|
||||
#include <linux/i2c-mux.h>
|
||||
|
||||
struct rtl2832_priv {
|
||||
struct i2c_adapter *i2c;
|
||||
struct i2c_adapter *i2c_adapter;
|
||||
struct i2c_adapter *i2c_adapter_tuner;
|
||||
struct dvb_frontend fe;
|
||||
struct rtl2832_config cfg;
|
||||
|
||||
@ -34,6 +37,7 @@ struct rtl2832_priv {
|
||||
|
||||
u8 tuner;
|
||||
u8 page; /* active register page */
|
||||
struct delayed_work i2c_gate_work;
|
||||
};
|
||||
|
||||
struct rtl2832_reg_entry {
|
||||
@ -267,7 +271,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_tua9001[] = {
|
||||
{DVBT_OPT_ADC_IQ, 0x1},
|
||||
{DVBT_AD_AVI, 0x0},
|
||||
{DVBT_AD_AVQ, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
|
||||
@ -301,7 +305,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
|
||||
{DVBT_GI_PGA_STATE, 0x0},
|
||||
{DVBT_EN_AGC_PGA, 0x1},
|
||||
{DVBT_IF_AGC_MAN, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
|
||||
@ -339,32 +343,32 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
|
||||
{DVBT_REG_MONSEL, 0x1},
|
||||
{DVBT_REG_MON, 0x1},
|
||||
{DVBT_REG_4MSEL, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_r820t[] = {
|
||||
{DVBT_DAGC_TRG_VAL, 0x39},
|
||||
{DVBT_AGC_TARG_VAL_0, 0x0},
|
||||
{DVBT_AGC_TARG_VAL_8_1, 0x40},
|
||||
{DVBT_AAGC_LOOP_GAIN, 0x16},
|
||||
{DVBT_LOOP_GAIN2_3_0, 0x8},
|
||||
{DVBT_LOOP_GAIN2_4, 0x1},
|
||||
{DVBT_LOOP_GAIN3, 0x18},
|
||||
{DVBT_VTOP1, 0x35},
|
||||
{DVBT_VTOP2, 0x21},
|
||||
{DVBT_VTOP3, 0x21},
|
||||
{DVBT_KRF1, 0x0},
|
||||
{DVBT_KRF2, 0x40},
|
||||
{DVBT_KRF3, 0x10},
|
||||
{DVBT_KRF4, 0x10},
|
||||
{DVBT_IF_AGC_MIN, 0x80},
|
||||
{DVBT_IF_AGC_MAX, 0x7f},
|
||||
{DVBT_RF_AGC_MIN, 0x80},
|
||||
{DVBT_RF_AGC_MAX, 0x7f},
|
||||
{DVBT_POLAR_RF_AGC, 0x0},
|
||||
{DVBT_POLAR_IF_AGC, 0x0},
|
||||
{DVBT_AD7_SETTING, 0xe9f4},
|
||||
{DVBT_SPEC_INV, 0x1},
|
||||
{DVBT_DAGC_TRG_VAL, 0x39},
|
||||
{DVBT_AGC_TARG_VAL_0, 0x0},
|
||||
{DVBT_AGC_TARG_VAL_8_1, 0x40},
|
||||
{DVBT_AAGC_LOOP_GAIN, 0x16},
|
||||
{DVBT_LOOP_GAIN2_3_0, 0x8},
|
||||
{DVBT_LOOP_GAIN2_4, 0x1},
|
||||
{DVBT_LOOP_GAIN3, 0x18},
|
||||
{DVBT_VTOP1, 0x35},
|
||||
{DVBT_VTOP2, 0x21},
|
||||
{DVBT_VTOP3, 0x21},
|
||||
{DVBT_KRF1, 0x0},
|
||||
{DVBT_KRF2, 0x40},
|
||||
{DVBT_KRF3, 0x10},
|
||||
{DVBT_KRF4, 0x10},
|
||||
{DVBT_IF_AGC_MIN, 0x80},
|
||||
{DVBT_IF_AGC_MAX, 0x7f},
|
||||
{DVBT_RF_AGC_MIN, 0x80},
|
||||
{DVBT_RF_AGC_MAX, 0x7f},
|
||||
{DVBT_POLAR_RF_AGC, 0x0},
|
||||
{DVBT_POLAR_IF_AGC, 0x0},
|
||||
{DVBT_AD7_SETTING, 0xe9f4},
|
||||
{DVBT_SPEC_INV, 0x1},
|
||||
};
|
||||
|
||||
#endif /* RTL2832_PRIV_H */
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Sharp VA3A5JZ921 One Seg Broadcast Module driver
|
||||
* This device is labeled as just S. 921 at the top of the frontend can
|
||||
*
|
||||
* Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Copyright (C) 2009-2010 Mauro Carvalho Chehab
|
||||
* Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
|
||||
*
|
||||
* Developed for Leadership SBTVD 1seg device sold in Brazil
|
||||
@ -539,6 +539,6 @@ static struct dvb_frontend_ops s921_ops = {
|
||||
};
|
||||
|
||||
MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Sharp s921 driver
|
||||
*
|
||||
* Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
* Copyright (C) 2009 Mauro Carvalho Chehab
|
||||
* Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -193,7 +193,7 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st
|
||||
.len = len + 1
|
||||
};
|
||||
|
||||
if (1 + len > sizeof(buf)) {
|
||||
if (1 + len > sizeof(cmdbuf)) {
|
||||
printk(KERN_WARNING
|
||||
"%s: i2c wr: len=%d is too big!\n",
|
||||
KBUILD_MODNAME, len);
|
||||
|
@ -1081,7 +1081,7 @@ static int stv0900_wait_for_lock(struct stv0900_internal *intp,
|
||||
lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
|
||||
|
||||
if (lock)
|
||||
lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout);
|
||||
lock = stv0900_get_fec_lock(intp, demod, fec_timeout);
|
||||
|
||||
if (lock) {
|
||||
lock = 0;
|
||||
|
@ -42,8 +42,8 @@ static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
|
||||
|
||||
if (1 + len > sizeof(buf)) {
|
||||
dev_warn(&priv->i2c->dev,
|
||||
"%s: i2c wr reg=%04x: len=%d is too big!\n",
|
||||
KBUILD_MODNAME, reg, len);
|
||||
"%s: i2c wr reg=%04x: len=%d is too big!\n",
|
||||
KBUILD_MODNAME, reg, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -54,8 +54,9 @@ static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
|
||||
"len=%d\n", KBUILD_MODNAME, ret, reg, len);
|
||||
dev_warn(&priv->i2c->dev,
|
||||
"%s: i2c wr failed=%d reg=%02x len=%d\n",
|
||||
KBUILD_MODNAME, ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
return ret;
|
||||
@ -83,8 +84,8 @@ static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
|
||||
|
||||
if (len > sizeof(buf)) {
|
||||
dev_warn(&priv->i2c->dev,
|
||||
"%s: i2c wr reg=%04x: len=%d is too big!\n",
|
||||
KBUILD_MODNAME, reg, len);
|
||||
"%s: i2c wr reg=%04x: len=%d is too big!\n",
|
||||
KBUILD_MODNAME, reg, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -93,8 +94,9 @@ static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
|
||||
memcpy(val, buf, len);
|
||||
ret = 0;
|
||||
} else {
|
||||
dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
|
||||
"len=%d\n", KBUILD_MODNAME, ret, reg, len);
|
||||
dev_warn(&priv->i2c->dev,
|
||||
"%s: i2c rd failed=%d reg=%02x len=%d\n",
|
||||
KBUILD_MODNAME, ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
return ret;
|
||||
@ -491,10 +493,9 @@ static int tda10071_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (tmp & 0x01) /* tuner PLL */
|
||||
*status |= FE_HAS_SIGNAL;
|
||||
/* 0x39[0] tuner PLL */
|
||||
if (tmp & 0x02) /* demod PLL */
|
||||
*status |= FE_HAS_CARRIER;
|
||||
*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
|
||||
if (tmp & 0x04) /* viterbi or LDPC*/
|
||||
*status |= FE_HAS_VITERBI;
|
||||
if (tmp & 0x08) /* RS or BCH */
|
||||
@ -668,11 +669,11 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
|
||||
int ret, i;
|
||||
u8 mode, rolloff, pilot, inversion, div;
|
||||
|
||||
dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \
|
||||
"frequency=%d symbol_rate=%d inversion=%d pilot=%d " \
|
||||
"rolloff=%d\n", __func__, c->delivery_system, c->modulation,
|
||||
c->frequency, c->symbol_rate, c->inversion, c->pilot,
|
||||
c->rolloff);
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
|
||||
__func__, c->delivery_system, c->modulation,
|
||||
c->frequency, c->symbol_rate, c->inversion, c->pilot,
|
||||
c->rolloff);
|
||||
|
||||
priv->delivery_system = SYS_UNDEFINED;
|
||||
|
||||
@ -952,10 +953,8 @@ static int tda10071_init(struct dvb_frontend *fe)
|
||||
/* request the firmware, this will block and timeout */
|
||||
ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent);
|
||||
if (ret) {
|
||||
dev_err(&priv->i2c->dev, "%s: did not find the " \
|
||||
"firmware file. (%s) Please see " \
|
||||
"linux/Documentation/dvb/ for more " \
|
||||
"details on firmware-problems. (%d)\n",
|
||||
dev_err(&priv->i2c->dev,
|
||||
"%s: did not find the firmware file. (%s) Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)\n",
|
||||
KBUILD_MODNAME, fw_file, ret);
|
||||
goto error;
|
||||
}
|
||||
@ -985,11 +984,12 @@ static int tda10071_init(struct dvb_frontend *fe)
|
||||
if (ret)
|
||||
goto error_release_firmware;
|
||||
|
||||
dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state, " \
|
||||
"will try to load a firmware\n", KBUILD_MODNAME,
|
||||
tda10071_ops.info.name);
|
||||
dev_info(&priv->i2c->dev, "%s: downloading firmware from " \
|
||||
"file '%s'\n", KBUILD_MODNAME, fw_file);
|
||||
dev_info(&priv->i2c->dev,
|
||||
"%s: found a '%s' in cold state, will try to load a firmware\n",
|
||||
KBUILD_MODNAME, tda10071_ops.info.name);
|
||||
dev_info(&priv->i2c->dev,
|
||||
"%s: downloading firmware from file '%s'\n",
|
||||
KBUILD_MODNAME, fw_file);
|
||||
|
||||
/* do not download last byte */
|
||||
fw_size = fw->size - 1;
|
||||
@ -1003,11 +1003,10 @@ static int tda10071_init(struct dvb_frontend *fe)
|
||||
ret = tda10071_wr_regs(priv, 0xfa,
|
||||
(u8 *) &fw->data[fw_size - remaining], len);
|
||||
if (ret) {
|
||||
dev_err(&priv->i2c->dev, "%s: firmware " \
|
||||
"download failed=%d\n",
|
||||
dev_err(&priv->i2c->dev,
|
||||
"%s: firmware download failed=%d\n",
|
||||
KBUILD_MODNAME, ret);
|
||||
if (ret)
|
||||
goto error_release_firmware;
|
||||
goto error_release_firmware;
|
||||
}
|
||||
}
|
||||
release_firmware(fw);
|
||||
@ -1069,12 +1068,17 @@ static int tda10071_init(struct dvb_frontend *fe)
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (priv->cfg.tuner_i2c_addr)
|
||||
tmp = priv->cfg.tuner_i2c_addr;
|
||||
else
|
||||
tmp = 0x14;
|
||||
|
||||
cmd.args[0] = CMD_TUNER_INIT;
|
||||
cmd.args[1] = 0x00;
|
||||
cmd.args[2] = 0x00;
|
||||
cmd.args[3] = 0x00;
|
||||
cmd.args[4] = 0x00;
|
||||
cmd.args[5] = (priv->cfg.tuner_i2c_addr) ? priv->cfg.tuner_i2c_addr : 0x14;
|
||||
cmd.args[5] = tmp;
|
||||
cmd.args[6] = 0x00;
|
||||
cmd.args[7] = 0x03;
|
||||
cmd.args[8] = 0x02;
|
||||
@ -1214,14 +1218,14 @@ struct dvb_frontend *tda10071_attach(const struct tda10071_config *config,
|
||||
|
||||
/* make sure demod i2c address is specified */
|
||||
if (!config->demod_i2c_addr) {
|
||||
dev_dbg(&i2c->dev, "%s: invalid demod i2c address!\n", __func__);
|
||||
dev_dbg(&i2c->dev, "%s: invalid demod i2c address\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* make sure tuner i2c address is specified */
|
||||
if (!config->tuner_i2c_addr) {
|
||||
dev_dbg(&i2c->dev, "%s: invalid tuner i2c address!\n", __func__);
|
||||
dev_dbg(&i2c->dev, "%s: invalid tuner i2c address\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ extern struct dvb_frontend *tda10071_attach(
|
||||
static inline struct dvb_frontend *tda10071_attach(
|
||||
const struct tda10071_config *config, struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
@ -196,7 +196,7 @@ config VIDEO_ADV7183
|
||||
|
||||
config VIDEO_ADV7604
|
||||
tristate "Analog Devices ADV7604 decoder"
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
|
||||
---help---
|
||||
Support for the Analog Devices ADV7604 video decoder.
|
||||
|
||||
@ -208,7 +208,7 @@ config VIDEO_ADV7604
|
||||
|
||||
config VIDEO_ADV7842
|
||||
tristate "Analog Devices ADV7842 decoder"
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
|
||||
---help---
|
||||
Support for the Analog Devices ADV7842 video decoder.
|
||||
|
||||
@ -431,7 +431,7 @@ config VIDEO_ADV7393
|
||||
|
||||
config VIDEO_ADV7511
|
||||
tristate "Analog Devices ADV7511 encoder"
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
|
||||
---help---
|
||||
Support for the Analog Devices ADV7511 video encoder.
|
||||
|
||||
@ -629,6 +629,15 @@ config VIDEO_LM3560
|
||||
This is a driver for the lm3560 dual flash controllers. It controls
|
||||
flash, torch LEDs.
|
||||
|
||||
config VIDEO_LM3646
|
||||
tristate "LM3646 dual flash driver support"
|
||||
depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select REGMAP_I2C
|
||||
---help---
|
||||
This is a driver for the lm3646 dual flash controllers. It controls
|
||||
flash, torch LEDs.
|
||||
|
||||
comment "Video improvement chips"
|
||||
|
||||
config VIDEO_UPD64031A
|
||||
@ -659,6 +668,7 @@ comment "Audio/Video compression chips"
|
||||
config VIDEO_SAA6752HS
|
||||
tristate "Philips SAA6752HS MPEG-2 Audio/Video Encoder"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
select CRC32
|
||||
---help---
|
||||
Support for the Philips SAA6752HS MPEG-2 video and MPEG-audio/AC-3
|
||||
audio encoder with multiplexer.
|
||||
|
@ -72,6 +72,7 @@ obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/
|
||||
obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
|
||||
obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o
|
||||
obj-$(CONFIG_VIDEO_LM3560) += lm3560.o
|
||||
obj-$(CONFIG_VIDEO_LM3646) += lm3646.o
|
||||
obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
|
||||
obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
|
||||
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
|
||||
|
@ -573,7 +573,7 @@ static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
|
||||
|
||||
/* ------------------------------ PAD OPS ------------------------------ */
|
||||
|
||||
static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
|
||||
static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
||||
{
|
||||
struct ad9389b_state *state = get_ad9389b_state(sd);
|
||||
|
||||
|
@ -123,11 +123,11 @@
|
||||
struct adv7180_state {
|
||||
struct v4l2_ctrl_handler ctrl_hdl;
|
||||
struct v4l2_subdev sd;
|
||||
struct work_struct work;
|
||||
struct mutex mutex; /* mutual excl. when accessing chip */
|
||||
int irq;
|
||||
v4l2_std_id curr_norm;
|
||||
bool autodetect;
|
||||
bool powered;
|
||||
u8 input;
|
||||
};
|
||||
#define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
|
||||
@ -312,6 +312,37 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adv7180_set_power(struct adv7180_state *state,
|
||||
struct i2c_client *client, bool on)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
if (on)
|
||||
val = ADV7180_PWR_MAN_ON;
|
||||
else
|
||||
val = ADV7180_PWR_MAN_OFF;
|
||||
|
||||
return i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG, val);
|
||||
}
|
||||
|
||||
static int adv7180_s_power(struct v4l2_subdev *sd, int on)
|
||||
{
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
int ret;
|
||||
|
||||
ret = mutex_lock_interruptible(&state->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = adv7180_set_power(state, client, on);
|
||||
if (ret == 0)
|
||||
state->powered = on;
|
||||
|
||||
mutex_unlock(&state->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
|
||||
@ -442,6 +473,7 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = {
|
||||
|
||||
static const struct v4l2_subdev_core_ops adv7180_core_ops = {
|
||||
.s_std = adv7180_s_std,
|
||||
.s_power = adv7180_s_power,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops adv7180_ops = {
|
||||
@ -449,10 +481,9 @@ static const struct v4l2_subdev_ops adv7180_ops = {
|
||||
.video = &adv7180_video_ops,
|
||||
};
|
||||
|
||||
static void adv7180_work(struct work_struct *work)
|
||||
static irqreturn_t adv7180_irq(int irq, void *devid)
|
||||
{
|
||||
struct adv7180_state *state = container_of(work, struct adv7180_state,
|
||||
work);
|
||||
struct adv7180_state *state = devid;
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
|
||||
u8 isr3;
|
||||
|
||||
@ -468,17 +499,6 @@ static void adv7180_work(struct work_struct *work)
|
||||
__adv7180_status(client, NULL, &state->curr_norm);
|
||||
mutex_unlock(&state->mutex);
|
||||
|
||||
enable_irq(state->irq);
|
||||
}
|
||||
|
||||
static irqreturn_t adv7180_irq(int irq, void *devid)
|
||||
{
|
||||
struct adv7180_state *state = devid;
|
||||
|
||||
schedule_work(&state->work);
|
||||
|
||||
disable_irq_nosync(state->irq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -533,48 +553,52 @@ static int init_device(struct i2c_client *client, struct adv7180_state *state)
|
||||
|
||||
/* register for interrupts */
|
||||
if (state->irq > 0) {
|
||||
ret = request_irq(state->irq, adv7180_irq, 0, KBUILD_MODNAME,
|
||||
state);
|
||||
ret = request_threaded_irq(state->irq, NULL, adv7180_irq,
|
||||
IRQF_ONESHOT, KBUILD_MODNAME, state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
|
||||
ADV7180_ADI_CTRL_IRQ_SPACE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
/* config the Interrupt pin to be active low */
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_ICONF1_ADI,
|
||||
ADV7180_ICONF1_ACTIVE_LOW |
|
||||
ADV7180_ICONF1_PSYNC_ONLY);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_IMR1_ADI, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_IMR2_ADI, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
/* enable AD change interrupts interrupts */
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_IMR3_ADI,
|
||||
ADV7180_IRQ3_AD_CHANGE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_IMR4_ADI, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_ADI_CTRL_REG,
|
||||
0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
free_irq(state->irq, state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adv7180_probe(struct i2c_client *client,
|
||||
@ -598,9 +622,9 @@ static int adv7180_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
state->irq = client->irq;
|
||||
INIT_WORK(&state->work, adv7180_work);
|
||||
mutex_init(&state->mutex);
|
||||
state->autodetect = true;
|
||||
state->powered = true;
|
||||
state->input = 0;
|
||||
sd = &state->sd;
|
||||
v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
|
||||
@ -611,15 +635,21 @@ static int adv7180_probe(struct i2c_client *client,
|
||||
ret = init_device(client, state);
|
||||
if (ret)
|
||||
goto err_free_ctrl;
|
||||
|
||||
ret = v4l2_async_register_subdev(sd);
|
||||
if (ret)
|
||||
goto err_free_irq;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
if (state->irq > 0)
|
||||
free_irq(client->irq, state);
|
||||
err_free_ctrl:
|
||||
adv7180_exit_controls(state);
|
||||
err_unreg_subdev:
|
||||
mutex_destroy(&state->mutex);
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
err:
|
||||
printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -628,20 +658,14 @@ static int adv7180_remove(struct i2c_client *client)
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
|
||||
if (state->irq > 0) {
|
||||
free_irq(client->irq, state);
|
||||
if (cancel_work_sync(&state->work)) {
|
||||
/*
|
||||
* Work was pending, therefore we need to enable
|
||||
* IRQ here to balance the disable_irq() done in the
|
||||
* interrupt handler.
|
||||
*/
|
||||
enable_irq(state->irq);
|
||||
}
|
||||
}
|
||||
v4l2_async_unregister_subdev(sd);
|
||||
|
||||
if (state->irq > 0)
|
||||
free_irq(client->irq, state);
|
||||
|
||||
mutex_destroy(&state->mutex);
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
adv7180_exit_controls(state);
|
||||
mutex_destroy(&state->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -654,13 +678,10 @@ static const struct i2c_device_id adv7180_id[] = {
|
||||
static int adv7180_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int ret;
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
|
||||
ADV7180_PWR_MAN_OFF);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
return adv7180_set_power(state, client, false);
|
||||
}
|
||||
|
||||
static int adv7180_resume(struct device *dev)
|
||||
@ -670,10 +691,11 @@ static int adv7180_resume(struct device *dev)
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
int ret;
|
||||
|
||||
ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
|
||||
ADV7180_PWR_MAN_ON);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (state->powered) {
|
||||
ret = adv7180_set_power(state, client, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
ret = init_device(client, state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -597,7 +597,7 @@ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
|
||||
static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
||||
{
|
||||
struct adv7511_state *state = get_adv7511_state(sd);
|
||||
|
||||
|
@ -1658,7 +1658,7 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
|
||||
static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
||||
{
|
||||
struct adv7604_state *state = to_state(sd);
|
||||
u8 *data = NULL;
|
||||
@ -1728,7 +1728,7 @@ static int get_edid_spa_location(const u8 *edid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
|
||||
static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
||||
{
|
||||
struct adv7604_state *state = to_state(sd);
|
||||
int spa_loc;
|
||||
|
@ -546,6 +546,14 @@ static void main_reset(struct v4l2_subdev *sd)
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static inline bool is_analog_input(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct adv7842_state *state = to_state(sd);
|
||||
|
||||
return ((state->mode == ADV7842_MODE_RGB) ||
|
||||
(state->mode == ADV7842_MODE_COMP));
|
||||
}
|
||||
|
||||
static inline bool is_digital_input(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct adv7842_state *state = to_state(sd);
|
||||
@ -1027,12 +1035,72 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
|
||||
cp_write(sd, 0xac, (height & 0x0f) << 4);
|
||||
}
|
||||
|
||||
static void adv7842_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 offset_a, u16 offset_b, u16 offset_c)
|
||||
{
|
||||
struct adv7842_state *state = to_state(sd);
|
||||
u8 offset_buf[4];
|
||||
|
||||
if (auto_offset) {
|
||||
offset_a = 0x3ff;
|
||||
offset_b = 0x3ff;
|
||||
offset_c = 0x3ff;
|
||||
}
|
||||
|
||||
v4l2_dbg(2, debug, sd, "%s: %s offset: a = 0x%x, b = 0x%x, c = 0x%x\n",
|
||||
__func__, auto_offset ? "Auto" : "Manual",
|
||||
offset_a, offset_b, offset_c);
|
||||
|
||||
offset_buf[0]= (cp_read(sd, 0x77) & 0xc0) | ((offset_a & 0x3f0) >> 4);
|
||||
offset_buf[1] = ((offset_a & 0x00f) << 4) | ((offset_b & 0x3c0) >> 6);
|
||||
offset_buf[2] = ((offset_b & 0x03f) << 2) | ((offset_c & 0x300) >> 8);
|
||||
offset_buf[3] = offset_c & 0x0ff;
|
||||
|
||||
/* Registers must be written in this order with no i2c access in between */
|
||||
if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x77, 4, offset_buf))
|
||||
v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__);
|
||||
}
|
||||
|
||||
static void adv7842_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, u16 gain_b, u16 gain_c)
|
||||
{
|
||||
struct adv7842_state *state = to_state(sd);
|
||||
u8 gain_buf[4];
|
||||
u8 gain_man = 1;
|
||||
u8 agc_mode_man = 1;
|
||||
|
||||
if (auto_gain) {
|
||||
gain_man = 0;
|
||||
agc_mode_man = 0;
|
||||
gain_a = 0x100;
|
||||
gain_b = 0x100;
|
||||
gain_c = 0x100;
|
||||
}
|
||||
|
||||
v4l2_dbg(2, debug, sd, "%s: %s gain: a = 0x%x, b = 0x%x, c = 0x%x\n",
|
||||
__func__, auto_gain ? "Auto" : "Manual",
|
||||
gain_a, gain_b, gain_c);
|
||||
|
||||
gain_buf[0] = ((gain_man << 7) | (agc_mode_man << 6) | ((gain_a & 0x3f0) >> 4));
|
||||
gain_buf[1] = (((gain_a & 0x00f) << 4) | ((gain_b & 0x3c0) >> 6));
|
||||
gain_buf[2] = (((gain_b & 0x03f) << 2) | ((gain_c & 0x300) >> 8));
|
||||
gain_buf[3] = ((gain_c & 0x0ff));
|
||||
|
||||
/* Registers must be written in this order with no i2c access in between */
|
||||
if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x73, 4, gain_buf))
|
||||
v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__);
|
||||
}
|
||||
|
||||
static void set_rgb_quantization_range(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct adv7842_state *state = to_state(sd);
|
||||
bool rgb_output = io_read(sd, 0x02) & 0x02;
|
||||
bool hdmi_signal = hdmi_read(sd, 0x05) & 0x80;
|
||||
|
||||
v4l2_dbg(2, debug, sd, "%s: rgb_quantization_range = %d\n",
|
||||
__func__, state->rgb_quantization_range);
|
||||
v4l2_dbg(2, debug, sd, "%s: RGB quantization range: %d, RGB out: %d, HDMI: %d\n",
|
||||
__func__, state->rgb_quantization_range,
|
||||
rgb_output, hdmi_signal);
|
||||
|
||||
adv7842_set_gain(sd, true, 0x0, 0x0, 0x0);
|
||||
adv7842_set_offset(sd, true, 0x0, 0x0, 0x0);
|
||||
|
||||
switch (state->rgb_quantization_range) {
|
||||
case V4L2_DV_RGB_RANGE_AUTO:
|
||||
@ -1050,7 +1118,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (hdmi_read(sd, 0x05) & 0x80) {
|
||||
if (hdmi_signal) {
|
||||
/* Receiving HDMI signal
|
||||
* Set automode */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0xf0);
|
||||
@ -1066,24 +1134,45 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
|
||||
} else {
|
||||
/* RGB full range (0-255) */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0x10);
|
||||
|
||||
if (is_digital_input(sd) && rgb_output) {
|
||||
adv7842_set_offset(sd, false, 0x40, 0x40, 0x40);
|
||||
} else {
|
||||
adv7842_set_gain(sd, false, 0xe0, 0xe0, 0xe0);
|
||||
adv7842_set_offset(sd, false, 0x70, 0x70, 0x70);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case V4L2_DV_RGB_RANGE_LIMITED:
|
||||
if (state->mode == ADV7842_MODE_COMP) {
|
||||
/* YCrCb limited range (16-235) */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0x20);
|
||||
} else {
|
||||
/* RGB limited range (16-235) */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
/* RGB limited range (16-235) */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0x00);
|
||||
|
||||
break;
|
||||
case V4L2_DV_RGB_RANGE_FULL:
|
||||
if (state->mode == ADV7842_MODE_COMP) {
|
||||
/* YCrCb full range (0-255) */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0x60);
|
||||
break;
|
||||
}
|
||||
|
||||
/* RGB full range (0-255) */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0x10);
|
||||
|
||||
if (is_analog_input(sd) || hdmi_signal)
|
||||
break;
|
||||
|
||||
/* Adjust gain/offset for DVI-D signals only */
|
||||
if (rgb_output) {
|
||||
adv7842_set_offset(sd, false, 0x40, 0x40, 0x40);
|
||||
} else {
|
||||
/* RGB full range (0-255) */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0x10);
|
||||
adv7842_set_gain(sd, false, 0xe0, 0xe0, 0xe0);
|
||||
adv7842_set_offset(sd, false, 0x70, 0x70, 0x70);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1360,12 +1449,11 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
|
||||
|
||||
bt->width = (hdmi_read(sd, 0x07) & 0x0f) * 256 + hdmi_read(sd, 0x08);
|
||||
bt->height = (hdmi_read(sd, 0x09) & 0x0f) * 256 + hdmi_read(sd, 0x0a);
|
||||
freq = (hdmi_read(sd, 0x06) * 1000000) +
|
||||
((hdmi_read(sd, 0x3b) & 0x30) >> 4) * 250000;
|
||||
|
||||
freq = ((hdmi_read(sd, 0x51) << 1) + (hdmi_read(sd, 0x52) >> 7)) * 1000000;
|
||||
freq += ((hdmi_read(sd, 0x52) & 0x7f) * 7813);
|
||||
if (is_hdmi(sd)) {
|
||||
/* adjust for deep color mode */
|
||||
freq = freq * 8 / (((hdmi_read(sd, 0x0b) & 0xc0) >> 5) + 8);
|
||||
freq = freq * 8 / (((hdmi_read(sd, 0x0b) & 0xc0) >> 6) * 2 + 8);
|
||||
}
|
||||
bt->pixelclock = freq;
|
||||
bt->hfrontporch = (hdmi_read(sd, 0x20) & 0x03) * 256 +
|
||||
@ -1717,8 +1805,8 @@ static void select_input(struct v4l2_subdev *sd,
|
||||
* (rev. 2.5, June 2010)" p. 17. */
|
||||
afe_write(sd, 0x12, 0xfb); /* ADC noise shaping filter controls */
|
||||
afe_write(sd, 0x0c, 0x0d); /* CP core gain controls */
|
||||
cp_write(sd, 0x3e, 0x80); /* CP core pre-gain control,
|
||||
enable color control */
|
||||
cp_write(sd, 0x3e, 0x00); /* CP core pre-gain control */
|
||||
|
||||
/* CP coast control */
|
||||
cp_write(sd, 0xc3, 0x33); /* Component mode */
|
||||
|
||||
@ -1926,7 +2014,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
|
||||
static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
||||
{
|
||||
struct adv7842_state *state = to_state(sd);
|
||||
u8 *data = NULL;
|
||||
@ -1966,7 +2054,7 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edi
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e)
|
||||
static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e)
|
||||
{
|
||||
struct adv7842_state *state = to_state(sd);
|
||||
int err = 0;
|
||||
@ -2103,7 +2191,8 @@ static void print_avi_infoframe(struct v4l2_subdev *sd)
|
||||
{
|
||||
int i;
|
||||
uint8_t buf[14];
|
||||
uint8_t avi_inf_len;
|
||||
u8 avi_len;
|
||||
u8 avi_ver;
|
||||
struct avi_info_frame avi;
|
||||
|
||||
if (!(hdmi_read(sd, 0x05) & 0x80)) {
|
||||
@ -2116,18 +2205,20 @@ static void print_avi_infoframe(struct v4l2_subdev *sd)
|
||||
}
|
||||
|
||||
if (io_read(sd, 0x88) & 0x10) {
|
||||
/* Note: the ADV7842 calculated incorrect checksums for InfoFrames
|
||||
with a length of 14 or 15. See the ADV7842 Register Settings
|
||||
Recommendations document for more details. */
|
||||
v4l2_info(sd, "AVI infoframe checksum error\n");
|
||||
return;
|
||||
v4l2_info(sd, "AVI infoframe checksum error has occurred earlier\n");
|
||||
io_write(sd, 0x8a, 0x10); /* clear AVI_INF_CKS_ERR_RAW */
|
||||
if (io_read(sd, 0x88) & 0x10) {
|
||||
v4l2_info(sd, "AVI infoframe checksum error still present\n");
|
||||
io_write(sd, 0x8a, 0x10); /* clear AVI_INF_CKS_ERR_RAW */
|
||||
}
|
||||
}
|
||||
|
||||
avi_inf_len = infoframe_read(sd, 0xe2);
|
||||
avi_len = infoframe_read(sd, 0xe2);
|
||||
avi_ver = infoframe_read(sd, 0xe1);
|
||||
v4l2_info(sd, "AVI infoframe version %d (%d byte)\n",
|
||||
infoframe_read(sd, 0xe1), avi_inf_len);
|
||||
avi_ver, avi_len);
|
||||
|
||||
if (infoframe_read(sd, 0xe1) != 0x02)
|
||||
if (avi_ver != 0x02)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 14; i++)
|
||||
@ -2602,9 +2693,15 @@ static int adv7842_core_init(struct v4l2_subdev *sd)
|
||||
/* disable I2C access to internal EDID ram from HDMI DDC ports */
|
||||
rep_write_and_or(sd, 0x77, 0xf3, 0x00);
|
||||
|
||||
hdmi_write(sd, 0x69, 0xa3); /* HPA manual */
|
||||
/* HPA disable on port A and B */
|
||||
io_write_and_or(sd, 0x20, 0xcf, 0x00);
|
||||
if (pdata->hpa_auto) {
|
||||
/* HPA auto, HPA 0.5s after Edid set and Cable detect */
|
||||
hdmi_write(sd, 0x69, 0x5c);
|
||||
} else {
|
||||
/* HPA manual */
|
||||
hdmi_write(sd, 0x69, 0xa3);
|
||||
/* HPA disable on port A and B */
|
||||
io_write_and_or(sd, 0x20, 0xcf, 0x00);
|
||||
}
|
||||
|
||||
/* LLC */
|
||||
io_write(sd, 0x19, 0x80 | pdata->llc_dll_phase);
|
||||
|
@ -431,8 +431,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
* Initialize the other fields of rc_dev
|
||||
*/
|
||||
rc->map_name = ir->ir_codes;
|
||||
rc->allowed_protos = rc_type;
|
||||
rc->enabled_protocols = rc_type;
|
||||
rc_set_allowed_protocols(rc, rc_type);
|
||||
rc_set_enabled_protocols(rc, rc_type);
|
||||
if (!rc->driver_name)
|
||||
rc->driver_name = MODULE_NAME;
|
||||
|
||||
|
@ -15,12 +15,6 @@
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
@ -42,7 +36,7 @@
|
||||
#define REG_FLAG 0xd0
|
||||
#define REG_CONFIG1 0xe0
|
||||
|
||||
/* Fault Mask */
|
||||
/* fault mask */
|
||||
#define FAULT_TIMEOUT (1<<0)
|
||||
#define FAULT_OVERTEMP (1<<1)
|
||||
#define FAULT_SHORT_CIRCUIT (1<<2)
|
||||
@ -53,7 +47,8 @@ enum led_enable {
|
||||
MODE_FLASH = 0x3,
|
||||
};
|
||||
|
||||
/* struct lm3560_flash
|
||||
/**
|
||||
* struct lm3560_flash
|
||||
*
|
||||
* @pdata: platform data
|
||||
* @regmap: reg. map for i2c
|
||||
@ -98,7 +93,7 @@ static int lm3560_mode_ctrl(struct lm3560_flash *flash)
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* led1/2 enable/disable */
|
||||
/* led1/2 enable/disable */
|
||||
static int lm3560_enable_ctrl(struct lm3560_flash *flash,
|
||||
enum lm3560_led_id led_no, bool on)
|
||||
{
|
||||
@ -168,7 +163,7 @@ static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash,
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* V4L2 controls */
|
||||
/* v4l2 controls */
|
||||
static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum lm3560_led_id led_no)
|
||||
{
|
||||
struct lm3560_flash *flash = to_lm3560_flash(ctrl, led_no);
|
||||
@ -297,6 +292,7 @@ static int lm3560_init_controls(struct lm3560_flash *flash,
|
||||
const struct v4l2_ctrl_ops *ops = &lm3560_led_ctrl_ops[led_no];
|
||||
|
||||
v4l2_ctrl_handler_init(hdl, 8);
|
||||
|
||||
/* flash mode */
|
||||
v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE,
|
||||
V4L2_FLASH_LED_MODE_TORCH, ~0x7,
|
||||
@ -309,6 +305,7 @@ static int lm3560_init_controls(struct lm3560_flash *flash,
|
||||
|
||||
/* flash strobe */
|
||||
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
|
||||
|
||||
/* flash strobe stop */
|
||||
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
|
||||
|
||||
@ -395,7 +392,7 @@ static int lm3560_init_device(struct lm3560_flash *flash)
|
||||
rval = lm3560_mode_ctrl(flash);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
/* Reset faults */
|
||||
/* reset faults */
|
||||
rval = regmap_read(flash->regmap, REG_FLAG, ®_val);
|
||||
return rval;
|
||||
}
|
||||
@ -419,8 +416,7 @@ static int lm3560_probe(struct i2c_client *client,
|
||||
|
||||
/* if there is no platform data, use chip default value */
|
||||
if (pdata == NULL) {
|
||||
pdata =
|
||||
kzalloc(sizeof(struct lm3560_platform_data), GFP_KERNEL);
|
||||
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (pdata == NULL)
|
||||
return -ENODEV;
|
||||
pdata->peak = LM3560_PEAK_3600mA;
|
||||
|
414
drivers/media/i2c/lm3646.c
Normal file
414
drivers/media/i2c/lm3646.c
Normal file
@ -0,0 +1,414 @@
|
||||
/*
|
||||
* drivers/media/i2c/lm3646.c
|
||||
* General device driver for TI lm3646, Dual FLASH LED Driver
|
||||
*
|
||||
* Copyright (C) 2014 Texas Instruments
|
||||
*
|
||||
* Contact: Daniel Jeong <gshark.jeong@gmail.com>
|
||||
* Ldd-Mlp <ldd-mlp@list.ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/lm3646.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
|
||||
/* registers definitions */
|
||||
#define REG_ENABLE 0x01
|
||||
#define REG_TORCH_BR 0x05
|
||||
#define REG_FLASH_BR 0x05
|
||||
#define REG_FLASH_TOUT 0x04
|
||||
#define REG_FLAG 0x08
|
||||
#define REG_STROBE_SRC 0x06
|
||||
#define REG_LED1_FLASH_BR 0x06
|
||||
#define REG_LED1_TORCH_BR 0x07
|
||||
|
||||
#define MASK_ENABLE 0x03
|
||||
#define MASK_TORCH_BR 0x70
|
||||
#define MASK_FLASH_BR 0x0F
|
||||
#define MASK_FLASH_TOUT 0x07
|
||||
#define MASK_FLAG 0xFF
|
||||
#define MASK_STROBE_SRC 0x80
|
||||
|
||||
/* Fault Mask */
|
||||
#define FAULT_TIMEOUT (1<<0)
|
||||
#define FAULT_SHORT_CIRCUIT (1<<1)
|
||||
#define FAULT_UVLO (1<<2)
|
||||
#define FAULT_IVFM (1<<3)
|
||||
#define FAULT_OCP (1<<4)
|
||||
#define FAULT_OVERTEMP (1<<5)
|
||||
#define FAULT_NTC_TRIP (1<<6)
|
||||
#define FAULT_OVP (1<<7)
|
||||
|
||||
enum led_mode {
|
||||
MODE_SHDN = 0x0,
|
||||
MODE_TORCH = 0x2,
|
||||
MODE_FLASH = 0x3,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct lm3646_flash
|
||||
*
|
||||
* @pdata: platform data
|
||||
* @regmap: reg. map for i2c
|
||||
* @lock: muxtex for serial access.
|
||||
* @led_mode: V4L2 LED mode
|
||||
* @ctrls_led: V4L2 contols
|
||||
* @subdev_led: V4L2 subdev
|
||||
* @mode_reg : mode register value
|
||||
*/
|
||||
struct lm3646_flash {
|
||||
struct device *dev;
|
||||
struct lm3646_platform_data *pdata;
|
||||
struct regmap *regmap;
|
||||
|
||||
struct v4l2_ctrl_handler ctrls_led;
|
||||
struct v4l2_subdev subdev_led;
|
||||
|
||||
u8 mode_reg;
|
||||
};
|
||||
|
||||
#define to_lm3646_flash(_ctrl) \
|
||||
container_of(_ctrl->handler, struct lm3646_flash, ctrls_led)
|
||||
|
||||
/* enable mode control */
|
||||
static int lm3646_mode_ctrl(struct lm3646_flash *flash,
|
||||
enum v4l2_flash_led_mode led_mode)
|
||||
{
|
||||
switch (led_mode) {
|
||||
case V4L2_FLASH_LED_MODE_NONE:
|
||||
return regmap_write(flash->regmap,
|
||||
REG_ENABLE, flash->mode_reg | MODE_SHDN);
|
||||
case V4L2_FLASH_LED_MODE_TORCH:
|
||||
return regmap_write(flash->regmap,
|
||||
REG_ENABLE, flash->mode_reg | MODE_TORCH);
|
||||
case V4L2_FLASH_LED_MODE_FLASH:
|
||||
return regmap_write(flash->regmap,
|
||||
REG_ENABLE, flash->mode_reg | MODE_FLASH);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* V4L2 controls */
|
||||
static int lm3646_get_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct lm3646_flash *flash = to_lm3646_flash(ctrl);
|
||||
unsigned int reg_val;
|
||||
int rval;
|
||||
|
||||
if (ctrl->id != V4L2_CID_FLASH_FAULT)
|
||||
return -EINVAL;
|
||||
|
||||
rval = regmap_read(flash->regmap, REG_FLAG, ®_val);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
ctrl->val = 0;
|
||||
if (reg_val & FAULT_TIMEOUT)
|
||||
ctrl->val |= V4L2_FLASH_FAULT_TIMEOUT;
|
||||
if (reg_val & FAULT_SHORT_CIRCUIT)
|
||||
ctrl->val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
|
||||
if (reg_val & FAULT_UVLO)
|
||||
ctrl->val |= V4L2_FLASH_FAULT_UNDER_VOLTAGE;
|
||||
if (reg_val & FAULT_IVFM)
|
||||
ctrl->val |= V4L2_FLASH_FAULT_INPUT_VOLTAGE;
|
||||
if (reg_val & FAULT_OCP)
|
||||
ctrl->val |= V4L2_FLASH_FAULT_OVER_CURRENT;
|
||||
if (reg_val & FAULT_OVERTEMP)
|
||||
ctrl->val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
|
||||
if (reg_val & FAULT_NTC_TRIP)
|
||||
ctrl->val |= V4L2_FLASH_FAULT_LED_OVER_TEMPERATURE;
|
||||
if (reg_val & FAULT_OVP)
|
||||
ctrl->val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm3646_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct lm3646_flash *flash = to_lm3646_flash(ctrl);
|
||||
unsigned int reg_val;
|
||||
int rval = -EINVAL;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_FLASH_LED_MODE:
|
||||
|
||||
if (ctrl->val != V4L2_FLASH_LED_MODE_FLASH)
|
||||
return lm3646_mode_ctrl(flash, ctrl->val);
|
||||
/* switch to SHDN mode before flash strobe on */
|
||||
return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE);
|
||||
|
||||
case V4L2_CID_FLASH_STROBE_SOURCE:
|
||||
return regmap_update_bits(flash->regmap,
|
||||
REG_STROBE_SRC, MASK_STROBE_SRC,
|
||||
(ctrl->val) << 7);
|
||||
|
||||
case V4L2_CID_FLASH_STROBE:
|
||||
|
||||
/* read and check current mode of chip to start flash */
|
||||
rval = regmap_read(flash->regmap, REG_ENABLE, ®_val);
|
||||
if (rval < 0 || ((reg_val & MASK_ENABLE) != MODE_SHDN))
|
||||
return rval;
|
||||
/* flash on */
|
||||
return lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_FLASH);
|
||||
|
||||
case V4L2_CID_FLASH_STROBE_STOP:
|
||||
|
||||
/*
|
||||
* flash mode will be turned automatically
|
||||
* from FLASH mode to SHDN mode after flash duration timeout
|
||||
* read and check current mode of chip to stop flash
|
||||
*/
|
||||
rval = regmap_read(flash->regmap, REG_ENABLE, ®_val);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
if ((reg_val & MASK_ENABLE) == MODE_FLASH)
|
||||
return lm3646_mode_ctrl(flash,
|
||||
V4L2_FLASH_LED_MODE_NONE);
|
||||
return rval;
|
||||
|
||||
case V4L2_CID_FLASH_TIMEOUT:
|
||||
return regmap_update_bits(flash->regmap,
|
||||
REG_FLASH_TOUT, MASK_FLASH_TOUT,
|
||||
LM3646_FLASH_TOUT_ms_TO_REG
|
||||
(ctrl->val));
|
||||
|
||||
case V4L2_CID_FLASH_INTENSITY:
|
||||
return regmap_update_bits(flash->regmap,
|
||||
REG_FLASH_BR, MASK_FLASH_BR,
|
||||
LM3646_TOTAL_FLASH_BRT_uA_TO_REG
|
||||
(ctrl->val));
|
||||
|
||||
case V4L2_CID_FLASH_TORCH_INTENSITY:
|
||||
return regmap_update_bits(flash->regmap,
|
||||
REG_TORCH_BR, MASK_TORCH_BR,
|
||||
LM3646_TOTAL_TORCH_BRT_uA_TO_REG
|
||||
(ctrl->val) << 4);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct v4l2_ctrl_ops lm3646_led_ctrl_ops = {
|
||||
.g_volatile_ctrl = lm3646_get_ctrl,
|
||||
.s_ctrl = lm3646_set_ctrl,
|
||||
};
|
||||
|
||||
static int lm3646_init_controls(struct lm3646_flash *flash)
|
||||
{
|
||||
struct v4l2_ctrl *fault;
|
||||
struct v4l2_ctrl_handler *hdl = &flash->ctrls_led;
|
||||
const struct v4l2_ctrl_ops *ops = &lm3646_led_ctrl_ops;
|
||||
|
||||
v4l2_ctrl_handler_init(hdl, 8);
|
||||
/* flash mode */
|
||||
v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_LED_MODE,
|
||||
V4L2_FLASH_LED_MODE_TORCH, ~0x7,
|
||||
V4L2_FLASH_LED_MODE_NONE);
|
||||
|
||||
/* flash source */
|
||||
v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_FLASH_STROBE_SOURCE,
|
||||
0x1, ~0x3, V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
|
||||
|
||||
/* flash strobe */
|
||||
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
|
||||
/* flash strobe stop */
|
||||
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
|
||||
|
||||
/* flash strobe timeout */
|
||||
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT,
|
||||
LM3646_FLASH_TOUT_MIN,
|
||||
LM3646_FLASH_TOUT_MAX,
|
||||
LM3646_FLASH_TOUT_STEP, flash->pdata->flash_timeout);
|
||||
|
||||
/* max flash current */
|
||||
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY,
|
||||
LM3646_TOTAL_FLASH_BRT_MIN,
|
||||
LM3646_TOTAL_FLASH_BRT_MAX,
|
||||
LM3646_TOTAL_FLASH_BRT_STEP,
|
||||
LM3646_TOTAL_FLASH_BRT_MAX);
|
||||
|
||||
/* max torch current */
|
||||
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY,
|
||||
LM3646_TOTAL_TORCH_BRT_MIN,
|
||||
LM3646_TOTAL_TORCH_BRT_MAX,
|
||||
LM3646_TOTAL_TORCH_BRT_STEP,
|
||||
LM3646_TOTAL_TORCH_BRT_MAX);
|
||||
|
||||
/* fault */
|
||||
fault = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0,
|
||||
V4L2_FLASH_FAULT_OVER_VOLTAGE
|
||||
| V4L2_FLASH_FAULT_OVER_TEMPERATURE
|
||||
| V4L2_FLASH_FAULT_SHORT_CIRCUIT
|
||||
| V4L2_FLASH_FAULT_TIMEOUT, 0, 0);
|
||||
if (fault != NULL)
|
||||
fault->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
||||
|
||||
if (hdl->error)
|
||||
return hdl->error;
|
||||
|
||||
flash->subdev_led.ctrl_handler = hdl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialize device */
|
||||
static const struct v4l2_subdev_ops lm3646_ops = {
|
||||
.core = NULL,
|
||||
};
|
||||
|
||||
static const struct regmap_config lm3646_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0xFF,
|
||||
};
|
||||
|
||||
static int lm3646_subdev_init(struct lm3646_flash *flash)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(flash->dev);
|
||||
int rval;
|
||||
|
||||
v4l2_i2c_subdev_init(&flash->subdev_led, client, &lm3646_ops);
|
||||
flash->subdev_led.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
strcpy(flash->subdev_led.name, LM3646_NAME);
|
||||
rval = lm3646_init_controls(flash);
|
||||
if (rval)
|
||||
goto err_out;
|
||||
rval = media_entity_init(&flash->subdev_led.entity, 0, NULL, 0);
|
||||
if (rval < 0)
|
||||
goto err_out;
|
||||
flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
|
||||
return rval;
|
||||
|
||||
err_out:
|
||||
v4l2_ctrl_handler_free(&flash->ctrls_led);
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int lm3646_init_device(struct lm3646_flash *flash)
|
||||
{
|
||||
unsigned int reg_val;
|
||||
int rval;
|
||||
|
||||
/* read the value of mode register to reduce redundant i2c accesses */
|
||||
rval = regmap_read(flash->regmap, REG_ENABLE, ®_val);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
flash->mode_reg = reg_val & 0xfc;
|
||||
|
||||
/* output disable */
|
||||
rval = lm3646_mode_ctrl(flash, V4L2_FLASH_LED_MODE_NONE);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
/*
|
||||
* LED1 flash current setting
|
||||
* LED2 flash current = Total(Max) flash current - LED1 flash current
|
||||
*/
|
||||
rval = regmap_update_bits(flash->regmap,
|
||||
REG_LED1_FLASH_BR, 0x7F,
|
||||
LM3646_LED1_FLASH_BRT_uA_TO_REG
|
||||
(flash->pdata->led1_flash_brt));
|
||||
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
/*
|
||||
* LED1 torch current setting
|
||||
* LED2 torch current = Total(Max) torch current - LED1 torch current
|
||||
*/
|
||||
rval = regmap_update_bits(flash->regmap,
|
||||
REG_LED1_TORCH_BR, 0x7F,
|
||||
LM3646_LED1_TORCH_BRT_uA_TO_REG
|
||||
(flash->pdata->led1_torch_brt));
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
/* Reset flag register */
|
||||
return regmap_read(flash->regmap, REG_FLAG, ®_val);
|
||||
}
|
||||
|
||||
static int lm3646_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *devid)
|
||||
{
|
||||
struct lm3646_flash *flash;
|
||||
struct lm3646_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
int rval;
|
||||
|
||||
flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
|
||||
if (flash == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
flash->regmap = devm_regmap_init_i2c(client, &lm3646_regmap);
|
||||
if (IS_ERR(flash->regmap))
|
||||
return PTR_ERR(flash->regmap);
|
||||
|
||||
/* check device tree if there is no platform data */
|
||||
if (pdata == NULL) {
|
||||
pdata = devm_kzalloc(&client->dev,
|
||||
sizeof(struct lm3646_platform_data),
|
||||
GFP_KERNEL);
|
||||
if (pdata == NULL)
|
||||
return -ENOMEM;
|
||||
/* use default data in case of no platform data */
|
||||
pdata->flash_timeout = LM3646_FLASH_TOUT_MAX;
|
||||
pdata->led1_torch_brt = LM3646_LED1_TORCH_BRT_MAX;
|
||||
pdata->led1_flash_brt = LM3646_LED1_FLASH_BRT_MAX;
|
||||
}
|
||||
flash->pdata = pdata;
|
||||
flash->dev = &client->dev;
|
||||
|
||||
rval = lm3646_subdev_init(flash);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
rval = lm3646_init_device(flash);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
i2c_set_clientdata(client, flash);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm3646_remove(struct i2c_client *client)
|
||||
{
|
||||
struct lm3646_flash *flash = i2c_get_clientdata(client);
|
||||
|
||||
v4l2_device_unregister_subdev(&flash->subdev_led);
|
||||
v4l2_ctrl_handler_free(&flash->ctrls_led);
|
||||
media_entity_cleanup(&flash->subdev_led.entity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lm3646_id_table[] = {
|
||||
{LM3646_NAME, 0},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, lm3646_id_table);
|
||||
|
||||
static struct i2c_driver lm3646_i2c_driver = {
|
||||
.driver = {
|
||||
.name = LM3646_NAME,
|
||||
},
|
||||
.probe = lm3646_probe,
|
||||
.remove = lm3646_remove,
|
||||
.id_table = lm3646_id_table,
|
||||
};
|
||||
|
||||
module_i2c_driver(lm3646_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>");
|
||||
MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>");
|
||||
MODULE_DESCRIPTION("Texas Instruments LM3646 Dual Flash LED driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -78,6 +78,9 @@
|
||||
#define MT9P031_PLL_CONFIG_1 0x11
|
||||
#define MT9P031_PLL_CONFIG_2 0x12
|
||||
#define MT9P031_PIXEL_CLOCK_CONTROL 0x0a
|
||||
#define MT9P031_PIXEL_CLOCK_INVERT (1 << 15)
|
||||
#define MT9P031_PIXEL_CLOCK_SHIFT(n) ((n) << 8)
|
||||
#define MT9P031_PIXEL_CLOCK_DIVIDE(n) ((n) << 0)
|
||||
#define MT9P031_FRAME_RESTART 0x0b
|
||||
#define MT9P031_SHUTTER_DELAY 0x0c
|
||||
#define MT9P031_RST 0x0d
|
||||
@ -130,6 +133,8 @@ struct mt9p031 {
|
||||
|
||||
enum mt9p031_model model;
|
||||
struct aptina_pll pll;
|
||||
unsigned int clk_div;
|
||||
bool use_pll;
|
||||
int reset;
|
||||
|
||||
struct v4l2_ctrl_handler ctrls;
|
||||
@ -198,6 +203,11 @@ static int mt9p031_reset(struct mt9p031 *mt9p031)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mt9p031_write(client, MT9P031_PIXEL_CLOCK_CONTROL,
|
||||
MT9P031_PIXEL_CLOCK_DIVIDE(mt9p031->clk_div));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN,
|
||||
0);
|
||||
}
|
||||
@ -222,15 +232,34 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
|
||||
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
|
||||
struct mt9p031_platform_data *pdata = mt9p031->pdata;
|
||||
int ret;
|
||||
|
||||
mt9p031->clk = devm_clk_get(&client->dev, NULL);
|
||||
if (IS_ERR(mt9p031->clk))
|
||||
return PTR_ERR(mt9p031->clk);
|
||||
|
||||
clk_set_rate(mt9p031->clk, pdata->ext_freq);
|
||||
ret = clk_set_rate(mt9p031->clk, pdata->ext_freq);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* If the external clock frequency is out of bounds for the PLL use the
|
||||
* pixel clock divider only and disable the PLL.
|
||||
*/
|
||||
if (pdata->ext_freq > limits.ext_clock_max) {
|
||||
unsigned int div;
|
||||
|
||||
div = DIV_ROUND_UP(pdata->ext_freq, pdata->target_freq);
|
||||
div = roundup_pow_of_two(div) / 2;
|
||||
|
||||
mt9p031->clk_div = max_t(unsigned int, div, 64);
|
||||
mt9p031->use_pll = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
mt9p031->pll.ext_clock = pdata->ext_freq;
|
||||
mt9p031->pll.pix_clock = pdata->target_freq;
|
||||
mt9p031->use_pll = true;
|
||||
|
||||
return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
|
||||
}
|
||||
@ -240,6 +269,9 @@ static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
|
||||
int ret;
|
||||
|
||||
if (!mt9p031->use_pll)
|
||||
return 0;
|
||||
|
||||
ret = mt9p031_write(client, MT9P031_PLL_CONTROL,
|
||||
MT9P031_PLL_CONTROL_PWRON);
|
||||
if (ret < 0)
|
||||
@ -265,6 +297,9 @@ static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
|
||||
|
||||
if (!mt9p031->use_pll)
|
||||
return 0;
|
||||
|
||||
return mt9p031_write(client, MT9P031_PLL_CONTROL,
|
||||
MT9P031_PLL_CONTROL_PWROFF);
|
||||
}
|
||||
@ -285,9 +320,15 @@ static int mt9p031_power_on(struct mt9p031 *mt9p031)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Emable clock */
|
||||
if (mt9p031->clk)
|
||||
clk_prepare_enable(mt9p031->clk);
|
||||
/* Enable clock */
|
||||
if (mt9p031->clk) {
|
||||
ret = clk_prepare_enable(mt9p031->clk);
|
||||
if (ret) {
|
||||
regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
|
||||
mt9p031->regulators);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now RESET_BAR must be high */
|
||||
if (gpio_is_valid(mt9p031->reset)) {
|
||||
|
@ -12,9 +12,11 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/v4l2-mediabus.h>
|
||||
@ -55,6 +57,7 @@
|
||||
#define MT9T001_OUTPUT_CONTROL_SYNC (1 << 0)
|
||||
#define MT9T001_OUTPUT_CONTROL_CHIP_ENABLE (1 << 1)
|
||||
#define MT9T001_OUTPUT_CONTROL_TEST_DATA (1 << 6)
|
||||
#define MT9T001_OUTPUT_CONTROL_DEF 0x0002
|
||||
#define MT9T001_SHUTTER_WIDTH_HIGH 0x08
|
||||
#define MT9T001_SHUTTER_WIDTH_LOW 0x09
|
||||
#define MT9T001_SHUTTER_WIDTH_MIN 1
|
||||
@ -116,6 +119,12 @@ struct mt9t001 {
|
||||
struct v4l2_subdev subdev;
|
||||
struct media_pad pad;
|
||||
|
||||
struct clk *clk;
|
||||
struct regulator_bulk_data regulators[2];
|
||||
|
||||
struct mutex power_lock; /* lock to protect power_count */
|
||||
int power_count;
|
||||
|
||||
struct v4l2_mbus_framefmt format;
|
||||
struct v4l2_rect crop;
|
||||
|
||||
@ -159,6 +168,77 @@ static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt9t001_reset(struct mt9t001 *mt9t001)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
|
||||
int ret;
|
||||
|
||||
/* Reset the chip and stop data read out */
|
||||
ret = mt9t001_write(client, MT9T001_RESET, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mt9t001_write(client, MT9T001_RESET, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
|
||||
|
||||
return mt9t001_set_output_control(mt9t001,
|
||||
MT9T001_OUTPUT_CONTROL_CHIP_ENABLE,
|
||||
0);
|
||||
}
|
||||
|
||||
static int mt9t001_power_on(struct mt9t001 *mt9t001)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Bring up the supplies */
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators),
|
||||
mt9t001->regulators);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Enable clock */
|
||||
ret = clk_prepare_enable(mt9t001->clk);
|
||||
if (ret < 0)
|
||||
regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
|
||||
mt9t001->regulators);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mt9t001_power_off(struct mt9t001 *mt9t001)
|
||||
{
|
||||
regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
|
||||
mt9t001->regulators);
|
||||
|
||||
clk_disable_unprepare(mt9t001->clk);
|
||||
}
|
||||
|
||||
static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
|
||||
int ret;
|
||||
|
||||
if (!on) {
|
||||
mt9t001_power_off(mt9t001);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = mt9t001_power_on(mt9t001);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mt9t001_reset(mt9t001);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Failed to reset the camera\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return v4l2_ctrl_handler_setup(&mt9t001->ctrls);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* V4L2 subdev video operations
|
||||
*/
|
||||
@ -195,6 +275,7 @@ static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||
{
|
||||
const u16 mode = MT9T001_OUTPUT_CONTROL_CHIP_ENABLE;
|
||||
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
||||
struct mt9t001_platform_data *pdata = client->dev.platform_data;
|
||||
struct mt9t001 *mt9t001 = to_mt9t001(subdev);
|
||||
struct v4l2_mbus_framefmt *format = &mt9t001->format;
|
||||
struct v4l2_rect *crop = &mt9t001->crop;
|
||||
@ -205,6 +286,14 @@ static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||
if (!enable)
|
||||
return mt9t001_set_output_control(mt9t001, mode, 0);
|
||||
|
||||
/* Configure the pixel clock polarity */
|
||||
if (pdata->clk_pol) {
|
||||
ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
|
||||
MT9T001_PIXEL_CLOCK_INVERT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Configure the window size and row/column bin */
|
||||
hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
|
||||
vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
|
||||
@ -629,10 +718,68 @@ static const struct v4l2_ctrl_config mt9t001_gains[] = {
|
||||
},
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* V4L2 subdev core operations
|
||||
*/
|
||||
|
||||
static int mt9t001_set_power(struct v4l2_subdev *subdev, int on)
|
||||
{
|
||||
struct mt9t001 *mt9t001 = to_mt9t001(subdev);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&mt9t001->power_lock);
|
||||
|
||||
/* If the power count is modified from 0 to != 0 or from != 0 to 0,
|
||||
* update the power state.
|
||||
*/
|
||||
if (mt9t001->power_count == !on) {
|
||||
ret = __mt9t001_set_power(mt9t001, !!on);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Update the power count. */
|
||||
mt9t001->power_count += on ? 1 : -1;
|
||||
WARN_ON(mt9t001->power_count < 0);
|
||||
|
||||
out:
|
||||
mutex_unlock(&mt9t001->power_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* V4L2 subdev internal operations
|
||||
*/
|
||||
|
||||
static int mt9t001_registered(struct v4l2_subdev *subdev)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
||||
struct mt9t001 *mt9t001 = to_mt9t001(subdev);
|
||||
s32 data;
|
||||
int ret;
|
||||
|
||||
ret = mt9t001_power_on(mt9t001);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "MT9T001 power up failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read out the chip version register */
|
||||
data = mt9t001_read(client, MT9T001_CHIP_VERSION);
|
||||
mt9t001_power_off(mt9t001);
|
||||
|
||||
if (data != MT9T001_CHIP_ID) {
|
||||
dev_err(&client->dev,
|
||||
"MT9T001 not detected, wrong version 0x%04x\n", data);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
|
||||
client->addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct v4l2_mbus_framefmt *format;
|
||||
@ -651,9 +798,18 @@ static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
|
||||
format->field = V4L2_FIELD_NONE;
|
||||
format->colorspace = V4L2_COLORSPACE_SRGB;
|
||||
|
||||
return 0;
|
||||
return mt9t001_set_power(subdev, 1);
|
||||
}
|
||||
|
||||
static int mt9t001_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
return mt9t001_set_power(subdev, 0);
|
||||
}
|
||||
|
||||
static struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = {
|
||||
.s_power = mt9t001_set_power,
|
||||
};
|
||||
|
||||
static struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = {
|
||||
.s_stream = mt9t001_s_stream,
|
||||
};
|
||||
@ -668,58 +824,17 @@ static struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = {
|
||||
};
|
||||
|
||||
static struct v4l2_subdev_ops mt9t001_subdev_ops = {
|
||||
.core = &mt9t001_subdev_core_ops,
|
||||
.video = &mt9t001_subdev_video_ops,
|
||||
.pad = &mt9t001_subdev_pad_ops,
|
||||
};
|
||||
|
||||
static struct v4l2_subdev_internal_ops mt9t001_subdev_internal_ops = {
|
||||
.registered = mt9t001_registered,
|
||||
.open = mt9t001_open,
|
||||
.close = mt9t001_close,
|
||||
};
|
||||
|
||||
static int mt9t001_video_probe(struct i2c_client *client)
|
||||
{
|
||||
struct mt9t001_platform_data *pdata = client->dev.platform_data;
|
||||
s32 data;
|
||||
int ret;
|
||||
|
||||
dev_info(&client->dev, "Probing MT9T001 at address 0x%02x\n",
|
||||
client->addr);
|
||||
|
||||
/* Reset the chip and stop data read out */
|
||||
ret = mt9t001_write(client, MT9T001_RESET, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mt9t001_write(client, MT9T001_RESET, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Configure the pixel clock polarity */
|
||||
if (pdata->clk_pol) {
|
||||
ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
|
||||
MT9T001_PIXEL_CLOCK_INVERT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read and check the sensor version */
|
||||
data = mt9t001_read(client, MT9T001_CHIP_VERSION);
|
||||
if (data != MT9T001_CHIP_ID) {
|
||||
dev_err(&client->dev, "MT9T001 not detected, wrong version "
|
||||
"0x%04x\n", data);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
|
||||
client->addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mt9t001_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *did)
|
||||
{
|
||||
@ -740,14 +855,28 @@ static int mt9t001_probe(struct i2c_client *client,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = mt9t001_video_probe(client);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
|
||||
if (!mt9t001)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&mt9t001->power_lock);
|
||||
mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
|
||||
|
||||
mt9t001->regulators[0].supply = "vdd";
|
||||
mt9t001->regulators[1].supply = "vaa";
|
||||
|
||||
ret = devm_regulator_bulk_get(&client->dev, 2, mt9t001->regulators);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Unable to get regulators\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
mt9t001->clk = devm_clk_get(&client->dev, NULL);
|
||||
if (IS_ERR(mt9t001->clk)) {
|
||||
dev_err(&client->dev, "Unable to get clock\n");
|
||||
return PTR_ERR(mt9t001->clk);
|
||||
}
|
||||
|
||||
v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
|
||||
ARRAY_SIZE(mt9t001_gains) + 4);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
|
||||
*
|
||||
* Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
|
||||
* Copyright (c) 2009 Mauro Carvalho Chehab
|
||||
* This code is placed under the terms of the GNU General Public License v2
|
||||
*/
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
#include <media/mt9v011.h>
|
||||
|
||||
MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int debug;
|
||||
|
@ -317,8 +317,14 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
|
||||
int ret;
|
||||
|
||||
clk_set_rate(mt9v032->clk, mt9v032->sysclk);
|
||||
clk_prepare_enable(mt9v032->clk);
|
||||
ret = clk_set_rate(mt9v032->clk, mt9v032->sysclk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(mt9v032->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
udelay(1);
|
||||
|
||||
/* Reset the chip and stop data read out */
|
||||
|
@ -8,7 +8,7 @@
|
||||
* and HeungJun Kim <riverful.kim@samsung.com>.
|
||||
*
|
||||
* Based on mt9v011 Micron Digital Image Sensor driver
|
||||
* Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
|
||||
* Copyright (c) 2009 Mauro Carvalho Chehab
|
||||
*
|
||||
* 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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user