1
0
Fork 0

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 commit 4329b93b28 ("of: Reduce
  indentation in of_graph_get_next_endpoint").

  The of_graph_get_next_endpoint() function was moved and renamed by
  commit fd9fdb78a9 ("[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 commit b9db140c1e ("[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
  ...
wifi-calibration
Linus Torvalds 2014-04-04 09:50:07 -07:00
commit 3c83e61e67
384 changed files with 44036 additions and 7945 deletions

View File

@ -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

View 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.

View File

@ -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;

View File

@ -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>

View File

@ -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
&#x22C6;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 &#x22C6;strength);</para>
<link linkend="FE_READ_SIGNAL_STRENGTH">FE_READ_SIGNAL_STRENGTH</link>, uint16_t &#x22C6;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>

View File

@ -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>
&gt; insmod mydriver.o video_nr=0,1 radio_nr=0,1</screen>
&gt; 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.&nbsp;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;, &amp;index)) {
perror ("VIDIOC_G_INPUT");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &amp;index)) {
perror("VIDIOC_G_INPUT");
exit(EXIT_FAILURE);
}
memset (&amp;input, 0, sizeof (input));
memset(&amp;input, 0, sizeof(input));
input.index = index;
if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
perror ("VIDIOC_ENUMINPUT");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &amp;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;, &amp;index)) {
perror ("VIDIOC_S_INPUT");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-S-INPUT;, &amp;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 (&amp;audio, 0, sizeof (audio));
memset(&amp;audio, 0, sizeof(audio));
if (-1 == ioctl (fd, &VIDIOC-G-AUDIO;, &amp;audio)) {
perror ("VIDIOC_G_AUDIO");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-G-AUDIO;, &amp;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 (&amp;audio, 0, sizeof (audio)); /* clear audio.mode, audio.reserved */
memset(&amp;audio, 0, sizeof(audio)); /* clear audio.mode, audio.reserved */
audio.index = 0;
if (-1 == ioctl (fd, &VIDIOC-S-AUDIO;, &amp;audio)) {
perror ("VIDIOC_S_AUDIO");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-S-AUDIO;, &amp;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;, &amp;std_id)) {
if (-1 == ioctl(fd, &VIDIOC-G-STD;, &amp;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 (&amp;standard, 0, sizeof (standard));
memset(&amp;standard, 0, sizeof(standard));
standard.index = 0;
while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
while (0 == ioctl(fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
if (standard.id &amp; 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;, &amp;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 (&amp;input, 0, sizeof (input));
memset(&amp;input, 0, sizeof(input));
if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
perror ("VIDIOC_G_INPUT");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
perror("VIDIOC_G_INPUT");
exit(EXIT_FAILURE);
}
if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
perror ("VIDIOC_ENUM_INPUT");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &amp;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 (&amp;standard, 0, sizeof (standard));
memset(&amp;standard, 0, sizeof(standard));
standard.index = 0;
while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
while (0 == ioctl(fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
if (standard.id &amp; input.std)
printf ("%s\n", standard.name);
printf("%s\n", standard.name);
standard.index++;
}
@ -690,8 +593,8 @@ while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;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 (&amp;input, 0, sizeof (input));
memset(&amp;input, 0, sizeof(input));
if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
perror ("VIDIOC_G_INPUT");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
perror("VIDIOC_G_INPUT");
exit(EXIT_FAILURE);
}
if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
perror ("VIDIOC_ENUM_INPUT");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
perror("VIDIOC_ENUM_INPUT");
exit(EXIT_FAILURE);
}
if (0 == (input.std &amp; 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 &amp; V4L2_STD_PAL_BG)) {
std_id = V4L2_STD_PAL_BG;
if (-1 == ioctl (fd, &VIDIOC-S-STD;, &amp;std_id)) {
perror ("VIDIOC_S_STD");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-S-STD;, &amp;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;

View File

@ -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>

View File

@ -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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>

View File

@ -56,18 +56,18 @@ framebuffer device.</para>
unsigned int i;
int fb_fd;
if (-1 == ioctl (fd, VIDIOC_G_FBUF, &amp;fbuf)) {
perror ("VIDIOC_G_FBUF");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, VIDIOC_G_FBUF, &amp;fbuf)) {
perror("VIDIOC_G_FBUF");
exit(EXIT_FAILURE);
}
for (i = 0; i &gt; 30; ++i) {
for (i = 0; i &lt; 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 &gt; 30; ++i) {
continue;
default:
perror ("open");
exit (EXIT_FAILURE);
perror("open");
exit(EXIT_FAILURE);
}
}
if (0 == ioctl (fb_fd, FBIOGET_FSCREENINFO, &amp;si)) {
if (si.smem_start == (unsigned long) fbuf.base)
if (0 == ioctl(fb_fd, FBIOGET_FSCREENINFO, &amp;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;
}

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>&nbsp;</entry>
<entry spanname="b0">Byte&nbsp;0 in memory</entry>
<entry spanname="b1">Byte&nbsp;1</entry>
<entry spanname="b2">Byte&nbsp;2</entry>
<entry spanname="b3">Byte&nbsp;3</entry>
</row>
<row>
<entry>&nbsp;</entry>
<entry>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>

View 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&nbsp;+&nbsp;0:</entry>
<entry>I'<subscript>0</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;1:</entry>
<entry>Q'<subscript>0</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>

View 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&nbsp;+&nbsp;0:</entry>
<entry>I'<subscript>0[7:0]</subscript></entry>
<entry>I'<subscript>0[15:8]</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;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>

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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>

View File

@ -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>&nbsp;*&nbsp;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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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&nbsp;Hz, otherwise in units of 62.5&nbsp;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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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

View 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";
};

View File

@ -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/";

View File

@ -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.

View File

@ -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:

View File

@ -163,3 +163,4 @@
162 -> Adlink MPG24
163 -> Bt848 Capture 14MHz
164 -> CyberVision CV06 (SV)
165 -> Kworld V-Stream Xpert TV PVR878

View File

@ -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]

View File

@ -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]

View File

@ -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)

View File

@ -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

View 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);

View File

@ -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

View File

@ -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");
}

View File

@ -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
*
*/

View File

@ -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
*/

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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 */

View 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.

View 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/

View 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__ */

View 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 */

View 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__ */

File diff suppressed because it is too large Load Diff

View 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)
*******************************************************************************
*/

File diff suppressed because it is too large Load Diff

View 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__ */

File diff suppressed because it is too large Load Diff

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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,

View File

@ -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");

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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");

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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, &reg_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;

View 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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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");

View File

@ -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)) {

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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