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:
 - removal of sn9c102.  This device driver was replaced a long time ago
   by gspca
 - solo6x10 and go7007 webcam drivers moved from staging into
   mainstream.  They were waiting for an API to allow setting the image
   detection matrix
 - SDR drivers moved from staging into mainstream: sdr-msi3101 (renamed
   as msi2500) and rtl2832
 - added SDR driver for airspy
 - added demux driver: si2165
 - rework at several RC subsystem, making the code for RC-5 SZ variant
   to be added at the standard RC5 decoder
 - added decoder for the XMP IR protocol
 - tuner driver moved from staging into mainstream: msi3101 (renamed as
   msi001)
 - added documentation for some additional SDR pixfmt
 - some device tree bindings documented
 - added support for exynos3250 at s5p-jpeg
 - remove the obsolete, unmaintained and broken mx1_camera driver
 - added support for remote controllers at au0828 driver
 - added a RC driver: sunxi-cir
 - several driver fixes, enhancements and cleanups.

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (455 commits)
  [media] cx23885: fix UNSET/TUNER_ABSENT confusion
  [media] coda: fix build error by making reset control optional
  [media] radio-miropcm20: fix sparse NULL pointer warning
  [media] MAINTAINERS: Update go7007 pattern
  [media] MAINTAINERS: Update solo6x10 patterns
  [media] media: atmel-isi: add primary DT support
  [media] media: atmel-isi: convert the pdata from pointer to structure
  [media] media: atmel-isi: add v4l2 async probe support
  [media] rcar_vin: add devicetree support
  [media] media: pxa_camera device-tree support
  [media] media: mt9m111: add device-tree suppport
  [media] soc_camera: add support for dt binding soc_camera drivers
  [media] media: soc_camera: pxa_camera documentation device-tree support
  [media] media: mt9m111: add device-tree documentation
  [media] s5p-mfc: remove unnecessary calling to function video_devdata()
  [media] s5p-jpeg: add chroma subsampling adjustment for Exynos3250
  [media] s5p-jpeg: Prevent erroneous downscaling for Exynos3250 SoC
  [media] s5p-jpeg: Assure proper crop rectangle initialization
  [media] s5p-jpeg: fix g_selection op
  [media] s5p-jpeg: Adjust jpeg_bound_align_image to Exynos3250 needs
  ...
This commit is contained in:
Linus Torvalds 2014-08-05 16:36:30 -07:00
commit f4d33337ea
442 changed files with 16255 additions and 17154 deletions

View File

@ -174,7 +174,7 @@ FILENAME = \
DOCUMENTED = \
-e "s/\(enum *\)v4l2_mpeg_cx2341x_video_\([a-z]*_spatial_filter_type\)/\1<link linkend=\"\2\">v4l2_mpeg_cx2341x_video_\2<\/link>/g" \
-e "s/\(\(enum\|struct\) *\)\(v4l2_[a-zA-Z0-9_]*\)/\1<link linkend=\"\3\">\3<\/link>/g" \
-e "s/\(V4L2_PIX_FMT_[A-Z0-9_]\+\) /<link linkend=\"\1\">\1<\/link> /g" \
-e "s/\(V4L2_PIX_FMT_[A-Z0-9_]\+\)\(\s\+v4l2_fourcc\)/<link linkend=\"\1\">\1<\/link>\2/g" \
-e ":a;s/\(linkend=\".*\)_\(.*\">\)/\1-\2/;ta" \
-e "s/v4l2\-mpeg\-vbi\-ITV0/v4l2-mpeg-vbi-itv0-1/g"

View File

@ -555,10 +555,46 @@ typedef enum fe_delivery_system {
</section>
<section id="DTV-ISDBT-LAYER-TIME-INTERLEAVING">
<title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
<para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
<para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
here are referring to what can be found in the TMCC-structure -
independent of the mode.</para>
<para>Valid values: 0, 1, 2, 4, -1 (AUTO)</para>
<para>when DTV_ISDBT_SOUND_BROADCASTING is active, value 8 is also valid.</para>
<para>Note: The real time interleaving length depends on the mode (fft-size). The values
here are referring to what can be found in the TMCC-structure, as shown in the table below.</para>
<informaltable id="isdbt-layer-interleaving-table">
<tgroup cols="4" align="center">
<tbody>
<row>
<entry>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</entry>
<entry>Mode 1 (2K FFT)</entry>
<entry>Mode 2 (4K FFT)</entry>
<entry>Mode 3 (8K FFT)</entry>
</row>
<row>
<entry>0</entry>
<entry>0</entry>
<entry>0</entry>
<entry>0</entry>
</row>
<row>
<entry>1</entry>
<entry>4</entry>
<entry>2</entry>
<entry>1</entry>
</row>
<row>
<entry>2</entry>
<entry>8</entry>
<entry>4</entry>
<entry>2</entry>
</row>
<row>
<entry>4</entry>
<entry>16</entry>
<entry>8</entry>
<entry>4</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section id="DTV-ATSCMH-FIC-VER">
<title><constant>DTV_ATSCMH_FIC_VER</constant></title>

View File

@ -13,6 +13,19 @@ correctly with any device.</para>
<para>All controls are accessed using an ID value. V4L2 defines
several IDs for specific purposes. Drivers can also implement their
own custom controls using <constant>V4L2_CID_PRIVATE_BASE</constant>
<footnote><para>The use of <constant>V4L2_CID_PRIVATE_BASE</constant>
is problematic because different drivers may use the same
<constant>V4L2_CID_PRIVATE_BASE</constant> ID for different controls.
This makes it hard to programatically set such controls since the meaning
of the control with that ID is driver dependent. In order to resolve this
drivers use unique IDs and the <constant>V4L2_CID_PRIVATE_BASE</constant>
IDs are mapped to those unique IDs by the kernel. Consider these
<constant>V4L2_CID_PRIVATE_BASE</constant> IDs as aliases to the real
IDs.</para>
<para>Many applications today still use the <constant>V4L2_CID_PRIVATE_BASE</constant>
IDs instead of using &VIDIOC-QUERYCTRL; with the <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>
flag to enumerate all IDs, so support for <constant>V4L2_CID_PRIVATE_BASE</constant>
is still around.</para></footnote>
and higher values. The pre-defined control IDs have the prefix
<constant>V4L2_CID_</constant>, and are listed in <xref
linkend="control-id" />. The ID is used when querying the attributes of
@ -31,25 +44,22 @@ the current video input or output, tuner or modulator, or audio input
or output. Different in the sense of other bounds, another default and
current value, step size or other menu items. A control with a certain
<emphasis>custom</emphasis> ID can also change name and
type.<footnote>
<para>It will be more convenient for applications if drivers
make use of the <constant>V4L2_CTRL_FLAG_DISABLED</constant> flag, but
that was never required.</para>
</footnote> Control values are stored globally, they do not
type.</para>
<para>If a control is not applicable to the current configuration
of the device (for example, it doesn't apply to the current video input)
drivers set the <constant>V4L2_CTRL_FLAG_INACTIVE</constant> flag.</para>
<para>Control values are stored globally, they do not
change when switching except to stay within the reported bounds. They
also do not change &eg; when the device is opened or closed, when the
tuner radio frequency is changed or generally never without
application request. Since V4L2 specifies no event mechanism, panel
applications intended to cooperate with other panel applications (be
they built into a larger application, as a TV viewer) may need to
regularly poll control values to update their user
interface.<footnote>
<para>Applications could call an ioctl to request events.
After another process called &VIDIOC-S-CTRL; or another ioctl changing
shared properties the &func-select; function would indicate
readability until any ioctl (querying the properties) is
called.</para>
</footnote></para>
application request.</para>
<para>V4L2 specifies an event mechanism to notify applications
when controls change value (see &VIDIOC-SUBSCRIBE-EVENT;, event
<constant>V4L2_EVENT_CTRL</constant>), panel applications might want to make
use of that in order to always reflect the correct control value.</para>
<para>
All controls use machine endianness.
@ -398,14 +408,17 @@ to work.</entry>
<row id="v4l2-alpha-component">
<entry><constant>V4L2_CID_ALPHA_COMPONENT</constant></entry>
<entry>integer</entry>
<entry> Sets the alpha color component on the capture device or on
the capture buffer queue of a mem-to-mem device. When a mem-to-mem
device produces frame format that includes an alpha component
<entry>Sets the alpha color component. When a capture device (or
capture queue of a mem-to-mem device) produces a frame format that
includes an alpha component
(e.g. <link linkend="rgb-formats">packed RGB image formats</link>)
and the alpha value is not defined by the mem-to-mem input data
this control lets you select the alpha component value of all
pixels. It is applicable to any pixel format that contains an alpha
component.
and the alpha value is not defined by the device or the mem-to-mem
input data this control lets you select the alpha component value of
all pixels. When an output device (or output queue of a mem-to-mem
device) consumes a frame format that doesn't include an alpha
component and the device supports alpha channel processing this
control lets you set the alpha component value of all pixels for
further processing in the device.
</entry>
</row>
<row>
@ -434,73 +447,98 @@ Drivers must implement <constant>VIDIOC_QUERYCTRL</constant>,
controls, <constant>VIDIOC_QUERYMENU</constant> when it has one or
more menu type controls.</para>
<example>
<title>Enumerating all controls</title>
<example id="enum_all_controls">
<title>Enumerating all user controls</title>
<programlisting>
&v4l2-queryctrl; queryctrl;
&v4l2-querymenu; querymenu;
static void
enumerate_menu (void)
static void enumerate_menu(void)
{
printf (" Menu items:\n");
printf(" Menu items:\n");
memset (&amp;querymenu, 0, sizeof (querymenu));
memset(&amp;querymenu, 0, sizeof(querymenu));
querymenu.id = queryctrl.id;
for (querymenu.index = queryctrl.minimum;
querymenu.index &lt;= queryctrl.maximum;
querymenu.index++) {
if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &amp;querymenu)) {
printf (" %s\n", querymenu.name);
querymenu.index++) {
if (0 == ioctl(fd, &VIDIOC-QUERYMENU;, &amp;querymenu)) {
printf(" %s\n", querymenu.name);
}
}
}
memset (&amp;queryctrl, 0, sizeof (queryctrl));
memset(&amp;queryctrl, 0, sizeof(queryctrl));
for (queryctrl.id = V4L2_CID_BASE;
queryctrl.id &lt; V4L2_CID_LASTP1;
queryctrl.id++) {
if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
if (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
continue;
printf ("Control %s\n", queryctrl.name);
printf("Control %s\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu ();
enumerate_menu();
} else {
if (errno == EINVAL)
continue;
perror ("VIDIOC_QUERYCTRL");
exit (EXIT_FAILURE);
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
}
for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
queryctrl.id++) {
if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
if (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
continue;
printf ("Control %s\n", queryctrl.name);
printf("Control %s\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu ();
enumerate_menu();
} else {
if (errno == EINVAL)
break;
perror ("VIDIOC_QUERYCTRL");
exit (EXIT_FAILURE);
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
}
</programlisting>
</example>
<example>
<title>Enumerating all user controls (alternative)</title>
<programlisting>
memset(&amp;queryctrl, 0, sizeof(queryctrl));
queryctrl.id = V4L2_CTRL_CLASS_USER | V4L2_CTRL_FLAG_NEXT_CTRL;
while (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
if (V4L2_CTRL_ID2CLASS(queryctrl.id) != V4L2_CTRL_CLASS_USER)
break;
if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
continue;
printf("Control %s\n", queryctrl.name);
if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
enumerate_menu();
queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
}
if (errno != EINVAL) {
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
}
</programlisting>
</example>
<example>
<title>Changing controls</title>
@ -508,53 +546,53 @@ for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
&v4l2-queryctrl; queryctrl;
&v4l2-control; control;
memset (&amp;queryctrl, 0, sizeof (queryctrl));
memset(&amp;queryctrl, 0, sizeof(queryctrl));
queryctrl.id = V4L2_CID_BRIGHTNESS;
if (-1 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
if (-1 == ioctl(fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
if (errno != EINVAL) {
perror ("VIDIOC_QUERYCTRL");
exit (EXIT_FAILURE);
perror("VIDIOC_QUERYCTRL");
exit(EXIT_FAILURE);
} else {
printf ("V4L2_CID_BRIGHTNESS is not supported\n");
printf("V4L2_CID_BRIGHTNESS is not supported\n");
}
} else if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED) {
printf ("V4L2_CID_BRIGHTNESS is not supported\n");
printf("V4L2_CID_BRIGHTNESS is not supported\n");
} else {
memset (&amp;control, 0, sizeof (control));
memset(&amp;control, 0, sizeof (control));
control.id = V4L2_CID_BRIGHTNESS;
control.value = queryctrl.default_value;
if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &amp;control)) {
perror ("VIDIOC_S_CTRL");
exit (EXIT_FAILURE);
if (-1 == ioctl(fd, &VIDIOC-S-CTRL;, &amp;control)) {
perror("VIDIOC_S_CTRL");
exit(EXIT_FAILURE);
}
}
memset (&amp;control, 0, sizeof (control));
memset(&amp;control, 0, sizeof(control));
control.id = V4L2_CID_CONTRAST;
if (0 == ioctl (fd, &VIDIOC-G-CTRL;, &amp;control)) {
if (0 == ioctl(fd, &VIDIOC-G-CTRL;, &amp;control)) {
control.value += 1;
/* The driver may clamp the value or return ERANGE, ignored here */
if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &amp;control)
if (-1 == ioctl(fd, &VIDIOC-S-CTRL;, &amp;control)
&amp;&amp; errno != ERANGE) {
perror ("VIDIOC_S_CTRL");
exit (EXIT_FAILURE);
perror("VIDIOC_S_CTRL");
exit(EXIT_FAILURE);
}
/* Ignore if V4L2_CID_CONTRAST is unsupported */
} else if (errno != EINVAL) {
perror ("VIDIOC_G_CTRL");
exit (EXIT_FAILURE);
perror("VIDIOC_G_CTRL");
exit(EXIT_FAILURE);
}
control.id = V4L2_CID_AUDIO_MUTE;
control.value = TRUE; /* silence */
control.value = 1; /* silence */
/* Errors ignored */
ioctl (fd, VIDIOC_S_CTRL, &amp;control);
ioctl(fd, VIDIOC_S_CTRL, &amp;control);
</programlisting>
</example>
</section>
@ -625,16 +663,29 @@ supported.</para>
&v4l2-control;, except for the fact that it also allows for 64-bit
values and pointers to be passed.</para>
<para>Since the &v4l2-ext-control; supports pointers it is now
also possible to have controls with compound types such as N-dimensional arrays
and/or structures. You need to specify the <constant>V4L2_CTRL_FLAG_NEXT_COMPOUND</constant>
when enumerating controls to actually be able to see such compound controls.
In other words, these controls with compound types should only be used
programmatically.</para>
<para>Since such compound controls need to expose more information
about themselves than is possible with &VIDIOC-QUERYCTRL; the
&VIDIOC-QUERY-EXT-CTRL; ioctl was added. In particular, this ioctl gives
the dimensions of the N-dimensional array if this control consists of more than
one element.</para>
<para>It is important to realize that due to the flexibility of
controls it is necessary to check whether the control you want to set
actually is supported in the driver and what the valid range of values
is. So use the &VIDIOC-QUERYCTRL; and &VIDIOC-QUERYMENU; ioctls to
check this. Also note that it is possible that some of the menu
indices in a control of type <constant>V4L2_CTRL_TYPE_MENU</constant>
may not be supported (<constant>VIDIOC_QUERYMENU</constant> will
return an error). A good example is the list of supported MPEG audio
bitrates. Some drivers only support one or two bitrates, others
support a wider range.</para>
is. So use the &VIDIOC-QUERYCTRL; (or &VIDIOC-QUERY-EXT-CTRL;) and
&VIDIOC-QUERYMENU; ioctls to check this. Also note that it is possible
that some of the menu indices in a control of type
<constant>V4L2_CTRL_TYPE_MENU</constant> may not be supported
(<constant>VIDIOC_QUERYMENU</constant> will return an error). A good
example is the list of supported MPEG audio bitrates. Some drivers only
support one or two bitrates, others support a wider range.</para>
<para>
All controls use machine endianness.
@ -675,12 +726,12 @@ control class is found:</para>
<informalexample>
<programlisting>
qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
while (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;qctrl)) {
if (V4L2_CTRL_ID2CLASS (qctrl.id) != V4L2_CTRL_CLASS_MPEG)
while (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &amp;qctrl)) {
if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_MPEG)
break;
/* ... */
qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
}
qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
}
</programlisting>
</informalexample>
@ -700,7 +751,7 @@ ID based on a control ID.</para>
<constant>VIDIOC_QUERYCTRL</constant> will fail when used in
combination with <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>. In
that case the old method of enumerating control should be used (see
1.8). But if it is supported, then it is guaranteed to enumerate over
<xref linkend="enum_all_controls" />). But if it is supported, then it is guaranteed to enumerate over
all controls, including driver-private controls.</para>
</section>
@ -3998,6 +4049,68 @@ in Annex E of <xref linkend="iec62106" />. The length of Radio Text strings depe
used to transmit it, either 32 (2A block) or 64 (2B block). However, it is also possible
to find receivers which can scroll strings sized as 32 x N or 64 x N characters. So, this control must be configured
with steps of 32 or 64 characters. The result is it must always contain a string with size multiple of 32 or 64. </entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_MONO_STEREO</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">Sets the Mono/Stereo bit of the Decoder Identification code. If set,
then the audio was recorded as stereo.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_ARTIFICIAL_HEAD</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">Sets the
<ulink url="http://en.wikipedia.org/wiki/Artificial_head">Artificial Head</ulink> bit of the Decoder
Identification code. If set, then the audio was recorded using an artificial head.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_COMPRESSED</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">Sets the Compressed bit of the Decoder Identification code. If set,
then the audio is compressed.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_DYNAMIC_PTY</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">Sets the Dynamic PTY bit of the Decoder Identification code. If set,
then the PTY code is dynamically switched.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">If set, then a traffic announcement is in progress.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_TRAFFIC_PROGRAM</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">If set, then the tuned programme carries traffic announcements.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_MUSIC_SPEECH</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">If set, then this channel broadcasts music. If cleared, then it
broadcasts speech. If the transmitter doesn't make this distinction, then it should be set.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_ALT_FREQS_ENABLE</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">If set, then transmit alternate frequencies.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_TX_ALT_FREQS</constant>&nbsp;</entry>
<entry>__u32 array</entry>
</row>
<row><entry spanname="descr">The alternate frequencies in kHz units. The RDS standard allows
for up to 25 frequencies to be defined. Drivers may support fewer frequencies so check
the array size.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_ENABLED</constant>&nbsp;</entry>
@ -4976,6 +5089,57 @@ description of this control class.</entry>
</row><row><entry spanname="descr">Enables/disables RDS
reception by the radio tuner</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_RX_PTY</constant>&nbsp;</entry>
<entry>integer</entry>
</row>
<row><entry spanname="descr">Gets RDS Programme Type field.
This encodes up to 31 pre-defined programme types.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_RX_PS_NAME</constant>&nbsp;</entry>
<entry>string</entry>
</row>
<row><entry spanname="descr">Gets the Programme Service name (PS_NAME).
It is intended for static display on a receiver. It is the primary aid to listeners in programme service
identification and selection. In Annex E of <xref linkend="iec62106" />, the RDS specification,
there is a full description of the correct character encoding for Programme Service name strings.
Also from RDS specification, PS is usually a single eight character text. However, it is also possible
to find receivers which can scroll strings sized as 8 x N characters. So, this control must be configured
with steps of 8 characters. The result is it must always contain a string with size multiple of 8.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_RX_RADIO_TEXT</constant>&nbsp;</entry>
<entry>string</entry>
</row>
<row><entry spanname="descr">Gets the Radio Text info. It is a textual description of
what is being broadcasted. RDS Radio Text can be applied when broadcaster wishes to transmit longer PS names,
programme-related information or any other text. In these cases, RadioText can be used in addition to
<constant>V4L2_CID_RDS_RX_PS_NAME</constant>. The encoding for Radio Text strings is also fully described
in Annex E of <xref linkend="iec62106" />. The length of Radio Text strings depends on which RDS Block is being
used to transmit it, either 32 (2A block) or 64 (2B block). However, it is also possible
to find receivers which can scroll strings sized as 32 x N or 64 x N characters. So, this control must be configured
with steps of 32 or 64 characters. The result is it must always contain a string with size multiple of 32 or 64. </entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">If set, then a traffic announcement is in progress.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_RX_TRAFFIC_PROGRAM</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">If set, then the tuned programme carries traffic announcements.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_RDS_RX_MUSIC_SPEECH</constant>&nbsp;</entry>
<entry>boolean</entry>
</row>
<row><entry spanname="descr">If set, then this channel broadcasts music. If cleared, then it
broadcasts speech. If the transmitter doesn't make this distinction, then it will be set.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_TUNE_DEEMPHASIS</constant>&nbsp;</entry>
<entry>enum v4l2_deemphasis</entry>
@ -5007,6 +5171,102 @@ defines possible values for de-emphasis. Here they are:</entry>
</tbody>
</tgroup>
</table>
</section>
<section id="detect-controls">
<title>Detect Control Reference</title>
<para>The Detect class includes controls for common features of
various motion or object detection capable devices.</para>
<table pgwide="1" frame="none" id="detect-control-id">
<title>Detect 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_DETECT_CLASS</constant>&nbsp;</entry>
<entry>class</entry>
</row><row><entry spanname="descr">The Detect 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_DETECT_MD_MODE</constant>&nbsp;</entry>
<entry>menu</entry>
</row><row><entry spanname="descr">Sets the motion detection mode.</entry>
</row>
<row>
<entrytbl spanname="descr" cols="2">
<tbody valign="top">
<row>
<entry><constant>V4L2_DETECT_MD_MODE_DISABLED</constant>
</entry><entry>Disable motion detection.</entry>
</row>
<row>
<entry><constant>V4L2_DETECT_MD_MODE_GLOBAL</constant>
</entry><entry>Use a single motion detection threshold.</entry>
</row>
<row>
<entry><constant>V4L2_DETECT_MD_MODE_THRESHOLD_GRID</constant>
</entry><entry>The image is divided into a grid, each cell with its own
motion detection threshold. These thresholds are set through the
<constant>V4L2_CID_DETECT_MD_THRESHOLD_GRID</constant> matrix control.</entry>
</row>
<row>
<entry><constant>V4L2_DETECT_MD_MODE_REGION_GRID</constant>
</entry><entry>The image is divided into a grid, each cell with its own
region value that specifies which per-region motion detection thresholds
should be used. Each region has its own thresholds. How these per-region
thresholds are set up is driver-specific. The region values for the grid are set
through the <constant>V4L2_CID_DETECT_MD_REGION_GRID</constant> matrix
control.</entry>
</row>
</tbody>
</entrytbl>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD</constant>&nbsp;</entry>
<entry>integer</entry>
</row>
<row><entry spanname="descr">Sets the global motion detection threshold to be
used with the <constant>V4L2_DETECT_MD_MODE_GLOBAL</constant> motion detection mode.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_DETECT_MD_THRESHOLD_GRID</constant>&nbsp;</entry>
<entry>__u16 matrix</entry>
</row>
<row><entry spanname="descr">Sets the motion detection thresholds for each cell in the grid.
To be used with the <constant>V4L2_DETECT_MD_MODE_THRESHOLD_GRID</constant>
motion detection mode. Matrix element (0, 0) represents the cell at the top-left of the
grid.</entry>
</row>
<row>
<entry spanname="id"><constant>V4L2_CID_DETECT_MD_REGION_GRID</constant>&nbsp;</entry>
<entry>__u8 matrix</entry>
</row>
<row><entry spanname="descr">Sets the motion detection region value for each cell in the grid.
To be used with the <constant>V4L2_DETECT_MD_MODE_REGION_GRID</constant>
motion detection mode. Matrix element (0, 0) represents the cell at the top-left of the
grid.</entry>
</row>
</tbody>
</tgroup>
</table>
</section>

View File

@ -150,9 +150,15 @@ signal. Drivers shall not convert the sample format by software.</para></entry>
<entry>This is the scanning system line number
associated with the first line of the VBI image, of the first and the
second field respectively. See <xref linkend="vbi-525" /> and
<xref linkend="vbi-625" /> for valid values. VBI input drivers can
return start values 0 if the hardware cannot reliable identify
scanning lines, VBI acquisition may not require this
<xref linkend="vbi-625" /> for valid values.
The <constant>V4L2_VBI_ITU_525_F1_START</constant>,
<constant>V4L2_VBI_ITU_525_F2_START</constant>,
<constant>V4L2_VBI_ITU_625_F1_START</constant> and
<constant>V4L2_VBI_ITU_625_F2_START</constant> defines give the start line
numbers for each field for each 525 or 625 line format as a convenience.
Don't forget that ITU line numbering starts at 1, not 0.
VBI input drivers can return start values 0 if the hardware cannot
reliable identify scanning lines, VBI acquisition may not require this
information.</entry>
</row>
<row>

View File

@ -72,9 +72,12 @@ To use the <link linkend="format">format</link> ioctls applications set the
<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.
Currently there is two fields, <structfield>pixelformat</structfield> and
<structfield>buffersize</structfield>, of struct &v4l2-sdr-format; which are
used. Content of the <structfield>pixelformat</structfield> is V4L2 FourCC
code of the data format. The <structfield>buffersize</structfield> field is
maximum buffer size in bytes required for data transfer, set by the driver in
order to inform application.
</para>
<table pgwide="1" frame="none" id="v4l2-sdr-format">
@ -91,9 +94,16 @@ little endian <link linkend="v4l2-fourcc">four character code</link>.
V4L2 defines SDR formats in <xref linkend="sdr-formats" />.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>buffersize</structfield></entry>
<entry>
Maximum size in bytes required for data. Value is set by the driver.
</entry>
</row>
<row>
<entry>__u8</entry>
<entry><structfield>reserved[28]</structfield></entry>
<entry><structfield>reserved[24]</structfield></entry>
<entry>This array is reserved for future extensions.
Drivers and applications must set it to zero.</entry>
</row>

View File

@ -185,7 +185,14 @@ tables, sigh. --></para></entry>
<entry></entry>
<entry spanname="hspan">Drivers must set
<structfield>service_lines</structfield>[0][0] and
<structfield>service_lines</structfield>[1][0] to zero.</entry>
<structfield>service_lines</structfield>[1][0] to zero.
The <constant>V4L2_VBI_ITU_525_F1_START</constant>,
<constant>V4L2_VBI_ITU_525_F2_START</constant>,
<constant>V4L2_VBI_ITU_625_F1_START</constant> and
<constant>V4L2_VBI_ITU_625_F2_START</constant> defines give the start
line numbers for each field for each 525 or 625 line format as a
convenience. Don't forget that ITU line numbering starts at 1, not 0.
</entry>
</row>
<row>
<entry>__u32</entry>

View File

@ -870,7 +870,8 @@ should set this to 0.</entry>
If the application sets this to 0 for an output stream, then
<structfield>bytesused</structfield> will be set to the size of the
plane (see the <structfield>length</structfield> field of this struct)
by the driver.</entry>
by the driver. Note that the actual image data starts at
<structfield>data_offset</structfield> which may not be 0.</entry>
</row>
<row>
<entry>__u32</entry>
@ -919,6 +920,10 @@ should set this to 0.</entry>
<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.
Note that data_offset is included in <structfield>bytesused</structfield>.
So the size of the image in the plane is
<structfield>bytesused</structfield>-<structfield>data_offset</structfield> at
offset <structfield>data_offset</structfield> from the start of the plane.
</entry>
</row>
<row>
@ -1066,7 +1071,7 @@ state, in the application domain so to say.</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. Also know as
key frame (or field), &ie; can be decompressed on its own. Also known as
an I-frame. Applications can set this bit when <structfield>type</structfield>
refers to an output stream.</entry>
</row>

View File

@ -15,9 +15,6 @@ typical PC graphics frame buffers. They occupy 8, 16, 24 or 32 bits
per pixel. These are all packed-pixel formats, meaning all the data
for a pixel lie next to each other in memory.</para>
<para>When one of these formats is used, drivers shall report the
colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<table pgwide="1" frame="none" id="rgb-formats">
<title>Packed RGB Image Formats</title>
<tgroup cols="37" align="center">
@ -130,9 +127,9 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<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>
<row id="V4L2-PIX-FMT-ARGB444">
<entry><constant>V4L2_PIX_FMT_ARGB444</constant></entry>
<entry>'AR12'</entry>
<entry></entry>
<entry>g<subscript>3</subscript></entry>
<entry>g<subscript>2</subscript></entry>
@ -152,9 +149,31 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<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>
<row id="V4L2-PIX-FMT-XRGB444">
<entry><constant>V4L2_PIX_FMT_XRGB444</constant></entry>
<entry>'XR12'</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>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</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-ARGB555">
<entry><constant>V4L2_PIX_FMT_ARGB555</constant></entry>
<entry>'AR15'</entry>
<entry></entry>
<entry>g<subscript>2</subscript></entry>
<entry>g<subscript>1</subscript></entry>
@ -174,6 +193,28 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<entry>g<subscript>4</subscript></entry>
<entry>g<subscript>3</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-XRGB555">
<entry><constant>V4L2_PIX_FMT_XRGB555</constant></entry>
<entry>'XR15'</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>-</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>
@ -341,6 +382,424 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
<entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry>
</row>
<row id="V4L2-PIX-FMT-ABGR32">
<entry><constant>V4L2_PIX_FMT_ABGR32</constant></entry>
<entry>'AR24'</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-XBGR32">
<entry><constant>V4L2_PIX_FMT_XBGR32</constant></entry>
<entry>'XR24'</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>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
</row>
<row id="V4L2-PIX-FMT-ARGB32">
<entry><constant>V4L2_PIX_FMT_ARGB32</constant></entry>
<entry>'AX24'</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>
<row id="V4L2-PIX-FMT-XRGB32">
<entry><constant>V4L2_PIX_FMT_XRGB32</constant></entry>
<entry>'BX24'</entry>
<entry></entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry>-</entry>
<entry></entry>
<entry>r<subscript>7</subscript></entry>
<entry>r<subscript>6</subscript></entry>
<entry>r<subscript>5</subscript></entry>
<entry>r<subscript>4</subscript></entry>
<entry>r<subscript>3</subscript></entry>
<entry>r<subscript>2</subscript></entry>
<entry>r<subscript>1</subscript></entry>
<entry>r<subscript>0</subscript></entry>
<entry></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>Bit 7 is the most significant bit.</para>
<para>The usage and value of the alpha bits (a) in the ARGB and ABGR formats
(collectively referred to as alpha formats) depend on the device type and
hardware operation. <link linkend="capture">Capture</link> devices
(including capture queues of mem-to-mem devices) fill the alpha component in
memory. When the device outputs an alpha channel the alpha component will
have a meaningful value. Otherwise, when the device doesn't output an alpha
channel but can set the alpha bit to a user-configurable value, the <link
linkend="v4l2-alpha-component"><constant>V4L2_CID_ALPHA_COMPONENT</constant>
</link> control is used to specify that alpha value, and the alpha component
of all pixels will be set to the value specified by that control. Otherwise
a corresponding format without an alpha component (XRGB or XBGR) must be
used instead of an alpha format.</para>
<para><link linkend="output">Output</link> devices (including output queues
of mem-to-mem devices and <link linkend="osd">video output overlay</link>
devices) read the alpha component from memory. When the device processes the
alpha channel the alpha component must be filled with meaningful values by
applications. Otherwise a corresponding format without an alpha component
(XRGB or XBGR) must be used instead of an alpha format.</para>
<para>The XRGB and XBGR formats contain undefined bits (-). Applications,
devices and drivers must ignore those bits, for both <link
linkend="capture">capture</link> and <link linkend="output">output</link>
devices.</para>
<example>
<title><constant>V4L2_PIX_FMT_BGR24</constant> 4 &times; 4 pixel
image</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="13" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>B<subscript>00</subscript></entry>
<entry>G<subscript>00</subscript></entry>
<entry>R<subscript>00</subscript></entry>
<entry>B<subscript>01</subscript></entry>
<entry>G<subscript>01</subscript></entry>
<entry>R<subscript>01</subscript></entry>
<entry>B<subscript>02</subscript></entry>
<entry>G<subscript>02</subscript></entry>
<entry>R<subscript>02</subscript></entry>
<entry>B<subscript>03</subscript></entry>
<entry>G<subscript>03</subscript></entry>
<entry>R<subscript>03</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;12:</entry>
<entry>B<subscript>10</subscript></entry>
<entry>G<subscript>10</subscript></entry>
<entry>R<subscript>10</subscript></entry>
<entry>B<subscript>11</subscript></entry>
<entry>G<subscript>11</subscript></entry>
<entry>R<subscript>11</subscript></entry>
<entry>B<subscript>12</subscript></entry>
<entry>G<subscript>12</subscript></entry>
<entry>R<subscript>12</subscript></entry>
<entry>B<subscript>13</subscript></entry>
<entry>G<subscript>13</subscript></entry>
<entry>R<subscript>13</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;24:</entry>
<entry>B<subscript>20</subscript></entry>
<entry>G<subscript>20</subscript></entry>
<entry>R<subscript>20</subscript></entry>
<entry>B<subscript>21</subscript></entry>
<entry>G<subscript>21</subscript></entry>
<entry>R<subscript>21</subscript></entry>
<entry>B<subscript>22</subscript></entry>
<entry>G<subscript>22</subscript></entry>
<entry>R<subscript>22</subscript></entry>
<entry>B<subscript>23</subscript></entry>
<entry>G<subscript>23</subscript></entry>
<entry>R<subscript>23</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;36:</entry>
<entry>B<subscript>30</subscript></entry>
<entry>G<subscript>30</subscript></entry>
<entry>R<subscript>30</subscript></entry>
<entry>B<subscript>31</subscript></entry>
<entry>G<subscript>31</subscript></entry>
<entry>R<subscript>31</subscript></entry>
<entry>B<subscript>32</subscript></entry>
<entry>G<subscript>32</subscript></entry>
<entry>R<subscript>32</subscript></entry>
<entry>B<subscript>33</subscript></entry>
<entry>G<subscript>33</subscript></entry>
<entry>R<subscript>33</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
<para>Formats defined in <xref linkend="rgb-formats-deprecated"/> are
deprecated and must not be used by new drivers. They are documented here for
reference. The meaning of their alpha bits (a) is ill-defined and
interpreted as in either the corresponding ARGB or XRGB format, depending on
the driver.</para>
<table pgwide="1" frame="none" id="rgb-formats-deprecated">
<title>Deprecated Packed RGB Image Formats</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>
<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-BGR32">
<entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
<entry>'BGR4'</entry>
@ -425,93 +884,6 @@ colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
</tgroup>
</table>
<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 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>
<example>
<title><constant>V4L2_PIX_FMT_BGR24</constant> 4 &times; 4 pixel
image</title>
<formalpara>
<title>Byte Order.</title>
<para>Each cell is one byte.
<informaltable frame="none">
<tgroup cols="13" align="center">
<colspec align="left" colwidth="2*" />
<tbody valign="top">
<row>
<entry>start&nbsp;+&nbsp;0:</entry>
<entry>B<subscript>00</subscript></entry>
<entry>G<subscript>00</subscript></entry>
<entry>R<subscript>00</subscript></entry>
<entry>B<subscript>01</subscript></entry>
<entry>G<subscript>01</subscript></entry>
<entry>R<subscript>01</subscript></entry>
<entry>B<subscript>02</subscript></entry>
<entry>G<subscript>02</subscript></entry>
<entry>R<subscript>02</subscript></entry>
<entry>B<subscript>03</subscript></entry>
<entry>G<subscript>03</subscript></entry>
<entry>R<subscript>03</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;12:</entry>
<entry>B<subscript>10</subscript></entry>
<entry>G<subscript>10</subscript></entry>
<entry>R<subscript>10</subscript></entry>
<entry>B<subscript>11</subscript></entry>
<entry>G<subscript>11</subscript></entry>
<entry>R<subscript>11</subscript></entry>
<entry>B<subscript>12</subscript></entry>
<entry>G<subscript>12</subscript></entry>
<entry>R<subscript>12</subscript></entry>
<entry>B<subscript>13</subscript></entry>
<entry>G<subscript>13</subscript></entry>
<entry>R<subscript>13</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;24:</entry>
<entry>B<subscript>20</subscript></entry>
<entry>G<subscript>20</subscript></entry>
<entry>R<subscript>20</subscript></entry>
<entry>B<subscript>21</subscript></entry>
<entry>G<subscript>21</subscript></entry>
<entry>R<subscript>21</subscript></entry>
<entry>B<subscript>22</subscript></entry>
<entry>G<subscript>22</subscript></entry>
<entry>R<subscript>22</subscript></entry>
<entry>B<subscript>23</subscript></entry>
<entry>G<subscript>23</subscript></entry>
<entry>R<subscript>23</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;36:</entry>
<entry>B<subscript>30</subscript></entry>
<entry>G<subscript>30</subscript></entry>
<entry>R<subscript>30</subscript></entry>
<entry>B<subscript>31</subscript></entry>
<entry>G<subscript>31</subscript></entry>
<entry>R<subscript>31</subscript></entry>
<entry>B<subscript>32</subscript></entry>
<entry>G<subscript>32</subscript></entry>
<entry>R<subscript>32</subscript></entry>
<entry>B<subscript>33</subscript></entry>
<entry>G<subscript>33</subscript></entry>
<entry>R<subscript>33</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
<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-CS08">
<refmeta>
<refentrytitle>V4L2_SDR_FMT_CS8 ('CS08')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>
<constant>V4L2_SDR_FMT_CS8</constant>
</refname>
<refpurpose>Complex signed 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 signed number. I value comes first and Q value after
that.
</para>
<example>
<title><constant>V4L2_SDR_FMT_CS8</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,47 @@
<refentry id="V4L2-SDR-FMT-CS14LE">
<refmeta>
<refentrytitle>V4L2_SDR_FMT_CS14LE ('CS14')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>
<constant>V4L2_SDR_FMT_CS14LE</constant>
</refname>
<refpurpose>Complex signed 14-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 14 bit signed little endian number. I value comes first
and Q value after that. 14 bit value is stored in 16 bit space with unused
high bits padded with 0.
</para>
<example>
<title><constant>V4L2_SDR_FMT_CS14LE</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[13:8]</subscript></entry>
</row>
<row>
<entry>start&nbsp;+&nbsp;2:</entry>
<entry>Q'<subscript>0[7:0]</subscript></entry>
<entry>Q'<subscript>0[13:8]</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>

View File

@ -0,0 +1,40 @@
<refentry id="V4L2-SDR-FMT-RU12LE">
<refmeta>
<refentrytitle>V4L2_SDR_FMT_RU12LE ('RU12')</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>
<constant>V4L2_SDR_FMT_RU12LE</constant>
</refname>
<refpurpose>Real unsigned 12-bit little endian sample</refpurpose>
</refnamediv>
<refsect1>
<title>Description</title>
<para>
This format contains sequence of real number samples. Each sample is
represented as a 12 bit unsigned little endian number. Sample is stored
in 16 bit space with unused high bits padded with 0.
</para>
<example>
<title><constant>V4L2_SDR_FMT_RU12LE</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[11:8]</subscript></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</formalpara>
</example>
</refsect1>
</refentry>

View File

@ -18,7 +18,7 @@
<title>Description</title>
<para>The following four pixel formats are raw sRGB / Bayer formats with
12 bits per colour. Each colour component is stored in a 16-bit word, with 6
12 bits per colour. Each colour component is stored in a 16-bit word, with 4
unused high bits filled with zeros. Each n-pixel row contains n/2 green samples
and n/2 blue or red samples, with alternating red and blue rows. Bytes are
stored in memory in little endian order. They are conventionally described

View File

@ -112,9 +112,34 @@ see <xref linkend="colorspaces" />.</entry>
<row>
<entry>__u32</entry>
<entry><structfield>priv</structfield></entry>
<entry>Reserved for custom (driver defined) additional
information about formats. When not used drivers and applications must
set this field to zero.</entry>
<entry><para>This field indicates whether the remaining fields of the
<structname>v4l2_pix_format</structname> structure, also called the extended
fields, are valid. When set to <constant>V4L2_PIX_FMT_PRIV_MAGIC</constant>, it
indicates that the extended fields have been correctly initialized. When set to
any other value it indicates that the extended fields contain undefined values.
</para>
<para>Applications that wish to use the pixel format extended fields must first
ensure that the feature is supported by querying the device for the
<link linkend="querycap"><constant>V4L2_CAP_EXT_PIX_FORMAT</constant></link>
capability. If the capability isn't set the pixel format extended fields are not
supported and using the extended fields will lead to undefined results.</para>
<para>To use the extended fields, applications must set the
<structfield>priv</structfield> field to
<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant>, initialize all the extended fields
and zero the unused bytes of the <structname>v4l2_format</structname>
<structfield>raw_data</structfield> field.</para>
<para>When the <structfield>priv</structfield> field isn't set to
<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant> drivers must act as if all the
extended fields were set to zero. On return drivers must set the
<structfield>priv</structfield> field to
<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant> and all the extended fields to
applicable values.</para></entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>Flags set by the application or driver, see <xref
linkend="format-flags" />.</entry>
</row>
</tbody>
</tgroup>
@ -201,9 +226,15 @@ codes can be used.</entry>
and the number of valid entries in the
<structfield>plane_fmt</structfield> array.</entry>
</row>
<row>
<entry>__u8</entry>
<entry><structfield>flags</structfield></entry>
<entry>Flags set by the application or driver, see <xref
linkend="format-flags" />.</entry>
</row>
<row>
<entry>__u8</entry>
<entry><structfield>reserved[11]</structfield></entry>
<entry><structfield>reserved[10]</structfield></entry>
<entry>Reserved for future extensions. Should be zeroed by the
application.</entry>
</row>
@ -248,7 +279,7 @@ has just as many pad bytes after it as the other rows.</para>
<para>In V4L2 each format has an identifier which looks like
<constant>PIX_FMT_XXX</constant>, defined in the <link
linkend="videodev">videodev.h</link> header file. These identifiers
linkend="videodev">videodev2.h</link> header file. These identifiers
represent <link linkend="v4l2-fourcc">four character (FourCC) codes</link>
which are also listed below, however they are not the same as those
used in the Windows world.</para>
@ -828,6 +859,9 @@ interface only.</para>
&sub-sdr-cu08;
&sub-sdr-cu16le;
&sub-sdr-cs08;
&sub-sdr-cs14le;
&sub-sdr-ru12le;
</section>
@ -1060,4 +1094,21 @@ concatenated to form the JPEG stream. </para>
</tbody>
</tgroup>
</table>
<table frame="none" pgwide="1" id="format-flags">
<title>Format Flags</title>
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry><constant>V4L2_PIX_FMT_FLAG_PREMUL_ALPHA</constant></entry>
<entry>0x00000001</entry>
<entry>The color values are premultiplied by the alpha channel
value. For example, if a light blue pixel with 50% transparency was described by
RGBA values (128, 192, 255, 128), the same pixel described with premultiplied
colors would be described by RGBA values (64, 96, 128, 128) </entry>
</row>
</tbody>
</tgroup>
</table>
</section>

View File

@ -86,47 +86,47 @@ selection targets available for a video capture device. It is recommended to
configure the cropping targets before to the composing targets.</para>
<para>The range of coordinates of the top left corner, width and height of
areas that can be sampled is given by the <constant> V4L2_SEL_TGT_CROP_BOUNDS
</constant> target. It is recommended for the driver developers to put the
top/left corner at position <constant> (0,0) </constant>. The rectangle's
areas that can be sampled is given by the <constant>V4L2_SEL_TGT_CROP_BOUNDS</constant>
target. It is recommended for the driver developers to put the
top/left corner at position <constant>(0,0)</constant>. The rectangle's
coordinates are expressed in pixels.</para>
<para>The top left corner, width and height of the source rectangle, that is
the area actually sampled, is given by the <constant> V4L2_SEL_TGT_CROP
</constant> target. It uses the same coordinate system as <constant>
V4L2_SEL_TGT_CROP_BOUNDS </constant>. The active cropping area must lie
completely inside the capture boundaries. The driver may further adjust the
requested size and/or position according to hardware limitations.</para>
the area actually sampled, is given by the <constant>V4L2_SEL_TGT_CROP</constant>
target. It uses the same coordinate system as <constant>V4L2_SEL_TGT_CROP_BOUNDS</constant>.
The active cropping area must lie completely inside the capture boundaries. The
driver may further adjust the requested size and/or position according to hardware
limitations.</para>
<para>Each capture device has a default source rectangle, given by the
<constant> V4L2_SEL_TGT_CROP_DEFAULT </constant> target. This rectangle shall
<constant>V4L2_SEL_TGT_CROP_DEFAULT</constant> target. This rectangle shall
over what the driver writer considers the complete picture. Drivers shall set
the active crop rectangle to the default when the driver is first loaded, but
not later.</para>
<para>The composing targets refer to a memory buffer. The limits of composing
coordinates are obtained using <constant> V4L2_SEL_TGT_COMPOSE_BOUNDS
</constant>. All coordinates are expressed in pixels. The rectangle's top/left
corner must be located at position <constant> (0,0) </constant>. The width and
height are equal to the image size set by <constant> VIDIOC_S_FMT </constant>.
coordinates are obtained using <constant>V4L2_SEL_TGT_COMPOSE_BOUNDS</constant>.
All coordinates are expressed in pixels. The rectangle's top/left
corner must be located at position <constant>(0,0)</constant>. The width and
height are equal to the image size set by <constant>VIDIOC_S_FMT</constant>.
</para>
<para>The part of a buffer into which the image is inserted by the hardware is
controlled by the <constant> V4L2_SEL_TGT_COMPOSE </constant> target.
controlled by the <constant>V4L2_SEL_TGT_COMPOSE</constant> target.
The rectangle's coordinates are also expressed in the same coordinate system as
the bounds rectangle. The composing rectangle must lie completely inside bounds
rectangle. The driver must adjust the composing rectangle to fit to the
bounding limits. Moreover, the driver can perform other adjustments according
to hardware limitations. The application can control rounding behaviour using
<link linkend="v4l2-selection-flags"> constraint flags </link>.</para>
<link linkend="v4l2-selection-flags"> constraint flags</link>.</para>
<para>For capture devices the default composing rectangle is queried using
<constant> V4L2_SEL_TGT_COMPOSE_DEFAULT </constant>. It is usually equal to the
<constant>V4L2_SEL_TGT_COMPOSE_DEFAULT</constant>. It is usually equal to the
bounding rectangle.</para>
<para>The part of a buffer that is modified by the hardware is given by
<constant> V4L2_SEL_TGT_COMPOSE_PADDED </constant>. It contains all pixels
defined using <constant> V4L2_SEL_TGT_COMPOSE </constant> plus all
<constant>V4L2_SEL_TGT_COMPOSE_PADDED</constant>. It contains all pixels
defined using <constant>V4L2_SEL_TGT_COMPOSE</constant> plus all
padding data modified by hardware during insertion process. All pixels outside
this rectangle <emphasis>must not</emphasis> be changed by the hardware. The
content of pixels that lie inside the padded area but outside active area is
@ -140,52 +140,51 @@ where the rubbish pixels are located and remove them if needed.</para>
<title>Configuration of video output</title>
<para>For output devices targets and ioctls are used similarly to the video
capture case. The <emphasis> composing </emphasis> rectangle refers to the
capture case. The <emphasis>composing</emphasis> rectangle refers to the
insertion of an image into a video signal. The cropping rectangles refer to a
memory buffer. It is recommended to configure the composing targets before to
the cropping targets.</para>
<para>The cropping targets refer to the memory buffer that contains an image to
be inserted into a video signal or graphical screen. The limits of cropping
coordinates are obtained using <constant> V4L2_SEL_TGT_CROP_BOUNDS </constant>.
coordinates are obtained using <constant>V4L2_SEL_TGT_CROP_BOUNDS</constant>.
All coordinates are expressed in pixels. The top/left corner is always point
<constant> (0,0) </constant>. The width and height is equal to the image size
specified using <constant> VIDIOC_S_FMT </constant> ioctl.</para>
<constant>(0,0)</constant>. The width and height is equal to the image size
specified using <constant>VIDIOC_S_FMT</constant> ioctl.</para>
<para>The top left corner, width and height of the source rectangle, that is
the area from which image date are processed by the hardware, is given by the
<constant> V4L2_SEL_TGT_CROP </constant>. Its coordinates are expressed
<constant>V4L2_SEL_TGT_CROP</constant>. Its coordinates are expressed
in in the same coordinate system as the bounds rectangle. The active cropping
area must lie completely inside the crop boundaries and the driver may further
adjust the requested size and/or position according to hardware
limitations.</para>
<para>For output devices the default cropping rectangle is queried using
<constant> V4L2_SEL_TGT_CROP_DEFAULT </constant>. It is usually equal to the
<constant>V4L2_SEL_TGT_CROP_DEFAULT</constant>. It is usually equal to the
bounding rectangle.</para>
<para>The part of a video signal or graphics display where the image is
inserted by the hardware is controlled by <constant>
V4L2_SEL_TGT_COMPOSE </constant> target. The rectangle's coordinates
are expressed in pixels. The composing rectangle must lie completely inside the
bounds rectangle. The driver must adjust the area to fit to the bounding
limits. Moreover, the driver can perform other adjustments according to
hardware limitations. </para>
inserted by the hardware is controlled by <constant>V4L2_SEL_TGT_COMPOSE</constant>
target. The rectangle's coordinates are expressed in pixels. The composing
rectangle must lie completely inside the bounds rectangle. The driver must
adjust the area to fit to the bounding limits. Moreover, the driver can
perform other adjustments according to hardware limitations.</para>
<para>The device has a default composing rectangle, given by the <constant>
V4L2_SEL_TGT_COMPOSE_DEFAULT </constant> target. This rectangle shall cover what
<para>The device has a default composing rectangle, given by the
<constant>V4L2_SEL_TGT_COMPOSE_DEFAULT</constant> target. This rectangle shall cover what
the driver writer considers the complete picture. It is recommended for the
driver developers to put the top/left corner at position <constant> (0,0)
</constant>. Drivers shall set the active composing rectangle to the default
driver developers to put the top/left corner at position <constant>(0,0)</constant>.
Drivers shall set the active composing rectangle to the default
one when the driver is first loaded.</para>
<para>The devices may introduce additional content to video signal other than
an image from memory buffers. It includes borders around an image. However,
such a padded area is driver-dependent feature not covered by this document.
Driver developers are encouraged to keep padded rectangle equal to active one.
The padded target is accessed by the <constant> V4L2_SEL_TGT_COMPOSE_PADDED
</constant> identifier. It must contain all pixels from the <constant>
V4L2_SEL_TGT_COMPOSE </constant> target.</para>
The padded target is accessed by the <constant>V4L2_SEL_TGT_COMPOSE_PADDED</constant>
identifier. It must contain all pixels from the <constant>V4L2_SEL_TGT_COMPOSE</constant>
target.</para>
</section>
@ -194,8 +193,8 @@ V4L2_SEL_TGT_COMPOSE </constant> target.</para>
<title>Scaling control</title>
<para>An application can detect if scaling is performed by comparing the width
and the height of rectangles obtained using <constant> V4L2_SEL_TGT_CROP
</constant> and <constant> V4L2_SEL_TGT_COMPOSE </constant> targets. If
and the height of rectangles obtained using <constant>V4L2_SEL_TGT_CROP</constant>
and <constant>V4L2_SEL_TGT_COMPOSE</constant> targets. If
these are not equal then the scaling is applied. The application can compute
the scaling ratios using these values.</para>
@ -208,7 +207,7 @@ the scaling ratios using these values.</para>
<title>Comparison with old cropping API</title>
<para>The selection API was introduced to cope with deficiencies of previous
<link linkend="crop"> API </link>, that was designed to control simple capture
<link linkend="crop"> API</link>, that was designed to control simple capture
devices. Later the cropping API was adopted by video output drivers. The ioctls
are used to select a part of the display were the video signal is inserted. It
should be considered as an API abuse because the described operation is
@ -220,7 +219,7 @@ part of an image by abusing V4L2 API. Cropping a smaller image from a larger
one is achieved by setting the field
&v4l2-pix-format;<structfield>::bytesperline</structfield>. Introducing an image offsets
could be done by modifying field &v4l2-buffer;<structfield>::m_userptr</structfield>
before calling <constant> VIDIOC_QBUF </constant>. Those
before calling <constant>VIDIOC_QBUF</constant>. Those
operations should be avoided because they are not portable (endianness), and do
not work for macroblock and Bayer formats and mmap buffers. The selection API
deals with configuration of buffer cropping/composing in a clear, intuitive and
@ -229,7 +228,7 @@ and constraints flags are introduced. Finally, &v4l2-crop; and &v4l2-cropcap;
have no reserved fields. Therefore there is no way to extend their functionality.
The new &v4l2-selection; provides a lot of place for future
extensions. Driver developers are encouraged to implement only selection API.
The former cropping API would be simulated using the new one. </para>
The former cropping API would be simulated using the new one.</para>
</section>
@ -238,9 +237,9 @@ The former cropping API would be simulated using the new one. </para>
<example>
<title>Resetting the cropping parameters</title>
<para>(A video capture device is assumed; change <constant>
V4L2_BUF_TYPE_VIDEO_CAPTURE </constant> for other devices; change target to
<constant> V4L2_SEL_TGT_COMPOSE_* </constant> family to configure composing
<para>(A video capture device is assumed; change
<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> for other devices; change target to
<constant>V4L2_SEL_TGT_COMPOSE_*</constant> family to configure composing
area)</para>
<programlisting>
@ -292,8 +291,8 @@ area)</para>
<example>
<title>Querying for scaling factors</title>
<para>A video output device is assumed; change <constant>
V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> for other devices</para>
<para>A video output device is assumed; change
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> for other devices</para>
<programlisting>
&v4l2-selection; compose = {

View File

@ -151,6 +151,14 @@ 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.16</revnumber>
<date>2014-05-27</date>
<authorinitials>lp</authorinitials>
<revremark>Extended &v4l2-pix-format;. Added format flags.
</revremark>
</revision>
<revision>
<revnumber>3.15</revnumber>
<date>2014-02-03</date>

View File

@ -92,6 +92,18 @@
<entry><structfield>frame_sync</structfield></entry>
<entry>Event data for event V4L2_EVENT_FRAME_SYNC.</entry>
</row>
<row>
<entry></entry>
<entry>&v4l2-event-motion-det;</entry>
<entry><structfield>motion_det</structfield></entry>
<entry>Event data for event V4L2_EVENT_MOTION_DET.</entry>
</row>
<row>
<entry></entry>
<entry>&v4l2-event-src-change;</entry>
<entry><structfield>src_change</structfield></entry>
<entry>Event data for event V4L2_EVENT_SOURCE_CHANGE.</entry>
</row>
<row>
<entry></entry>
<entry>__u8</entry>
@ -258,6 +270,44 @@
</tgroup>
</table>
<table frame="none" pgwide="1" id="v4l2-event-motion-det">
<title>struct <structname>v4l2_event_motion_det</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>
Currently only one flag is available: if <constant>V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ</constant>
is set, then the <structfield>frame_sequence</structfield> field is valid,
otherwise that field should be ignored.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>frame_sequence</structfield></entry>
<entry>
The sequence number of the frame being received. Only valid if the
<constant>V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ</constant> flag was set.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>region_mask</structfield></entry>
<entry>
The bitmask of the regions that reported motion. There is at least one
region. If this field is 0, then no motion was detected at all.
If there is no <constant>V4L2_CID_DETECT_MD_REGION_GRID</constant> control
(see <xref linkend="detect-controls" />) to assign a different region
to each cell in the motion detection grid, then that all cells
are automatically assigned to the default region 0.
</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="changes-flags">
<title>Changes</title>
<tgroup cols="3">

View File

@ -72,23 +72,30 @@ initialize the <structfield>id</structfield>,
<structfield>size</structfield> and <structfield>reserved2</structfield> fields
of each &v4l2-ext-control; and call the
<constant>VIDIOC_G_EXT_CTRLS</constant> ioctl. String controls controls
must also set the <structfield>string</structfield> field.</para>
must also set the <structfield>string</structfield> field. Controls
of compound types (<constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant> is set)
must set the <structfield>ptr</structfield> field.</para>
<para>If the <structfield>size</structfield> is too small to
receive the control result (only relevant for pointer-type controls
like strings), then the driver will set <structfield>size</structfield>
to a valid value and return an &ENOSPC;. You should re-allocate the
string memory to this new size and try again. It is possible that the
same issue occurs again if the string has grown in the meantime. It is
memory to this new size and try again. For the string type it is possible that
the same issue occurs again if the string has grown in the meantime. It is
recommended to call &VIDIOC-QUERYCTRL; first and use
<structfield>maximum</structfield>+1 as the new <structfield>size</structfield>
value. It is guaranteed that that is sufficient memory.
</para>
<para>N-dimensional arrays are set and retrieved row-by-row. You cannot set a partial
array, all elements have to be set or retrieved. The total size is calculated
as <structfield>elems</structfield> * <structfield>elem_size</structfield>.
These values can be obtained by calling &VIDIOC-QUERY-EXT-CTRL;.</para>
<para>To change the value of a set of controls applications
initialize the <structfield>id</structfield>, <structfield>size</structfield>,
<structfield>reserved2</structfield> and
<structfield>value/string</structfield> fields of each &v4l2-ext-control; and
<structfield>value/value64/string/ptr</structfield> fields of each &v4l2-ext-control; and
call the <constant>VIDIOC_S_EXT_CTRLS</constant> ioctl. The controls
will only be set if <emphasis>all</emphasis> control values are
valid.</para>
@ -96,7 +103,7 @@ valid.</para>
<para>To check if a set of controls have correct values applications
initialize the <structfield>id</structfield>, <structfield>size</structfield>,
<structfield>reserved2</structfield> and
<structfield>value/string</structfield> fields of each &v4l2-ext-control; and
<structfield>value/value64/string/ptr</structfield> fields of each &v4l2-ext-control; and
call the <constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctl. It is up to
the driver whether wrong values are automatically adjusted to a valid
value or if an error is returned.</para>
@ -158,19 +165,47 @@ applications must set the array to zero.</entry>
<entry></entry>
<entry>__s32</entry>
<entry><structfield>value</structfield></entry>
<entry>New value or current value.</entry>
<entry>New value or current value. Valid if this control is not of
type <constant>V4L2_CTRL_TYPE_INTEGER64</constant> and
<constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant> is not set.</entry>
</row>
<row>
<entry></entry>
<entry>__s64</entry>
<entry><structfield>value64</structfield></entry>
<entry>New value or current value.</entry>
<entry>New value or current value. Valid if this control is of
type <constant>V4L2_CTRL_TYPE_INTEGER64</constant> and
<constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant> is not set.</entry>
</row>
<row>
<entry></entry>
<entry>char *</entry>
<entry><structfield>string</structfield></entry>
<entry>A pointer to a string.</entry>
<entry>A pointer to a string. Valid if this control is of
type <constant>V4L2_CTRL_TYPE_STRING</constant>.</entry>
</row>
<row>
<entry></entry>
<entry>__u8 *</entry>
<entry><structfield>p_u8</structfield></entry>
<entry>A pointer to a matrix control of unsigned 8-bit values.
Valid if this control is of type <constant>V4L2_CTRL_TYPE_U8</constant>.</entry>
</row>
<row>
<entry></entry>
<entry>__u16 *</entry>
<entry><structfield>p_u16</structfield></entry>
<entry>A pointer to a matrix control of unsigned 16-bit values.
Valid if this control is of type <constant>V4L2_CTRL_TYPE_U16</constant>.</entry>
</row>
<row>
<entry></entry>
<entry>void *</entry>
<entry><structfield>ptr</structfield></entry>
<entry>A pointer to a compound type which can be an N-dimensional array and/or a
compound type (the control's type is >= <constant>V4L2_CTRL_COMPOUND_TYPES</constant>).
Valid if <constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant> is set for this control.
</entry>
</row>
</tbody>
</tgroup>

View File

@ -152,13 +152,10 @@ a valid base address, so applications can find the corresponding Linux
framebuffer device (see <xref linkend="osd" />).</entry>
</row>
<row>
<entry>&v4l2-pix-format;</entry>
<entry>struct</entry>
<entry><structfield>fmt</structfield></entry>
<entry></entry>
<entry>Layout of the frame buffer. The
<structname>v4l2_pix_format</structname> structure is defined in <xref
linkend="pixfmt" />, for clarification the fields and acceptable values
are listed below:</entry>
<entry>Layout of the frame buffer.</entry>
</row>
<row>
<entry></entry>
@ -276,9 +273,8 @@ see <xref linkend="colorspaces" />.</entry>
<entry></entry>
<entry>__u32</entry>
<entry><structfield>priv</structfield></entry>
<entry>Reserved for additional information about custom
(driver defined) formats. When not used drivers and applications must
set this field to zero.</entry>
<entry>Reserved. Drivers and applications must set this field to
zero.</entry>
</row>
</tbody>
</tgroup>

View File

@ -58,17 +58,16 @@
<para>The ioctls are used to query and configure selection rectangles.</para>
<para> To query the cropping (composing) rectangle set &v4l2-selection;
<para>To query the cropping (composing) rectangle set &v4l2-selection;
<structfield> type </structfield> field to the respective buffer type.
Do not use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE
</constant> instead of <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
</constant>. Use <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> instead of
<constant> V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE </constant>. The next step is
Do not use multiplanar buffers. Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. Use
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>. The next step is
setting the value of &v4l2-selection; <structfield>target</structfield> field
to <constant> V4L2_SEL_TGT_CROP </constant> (<constant>
V4L2_SEL_TGT_COMPOSE </constant>). Please refer to table <xref
linkend="v4l2-selections-common" /> or <xref linkend="selection-api" /> for additional
targets. The <structfield>flags</structfield> and <structfield>reserved
to <constant>V4L2_SEL_TGT_CROP</constant> (<constant>V4L2_SEL_TGT_COMPOSE</constant>).
Please refer to table <xref linkend="v4l2-selections-common" /> or <xref linkend="selection-api" />
for additional targets. The <structfield>flags</structfield> and <structfield>reserved
</structfield> fields of &v4l2-selection; are ignored and they must be filled
with zeros. The driver fills the rest of the structure or
returns &EINVAL; if incorrect buffer type or target was used. If cropping
@ -77,19 +76,18 @@ always equal to the bounds rectangle. Finally, the &v4l2-rect;
<structfield>r</structfield> rectangle is filled with the current cropping
(composing) coordinates. The coordinates are expressed in driver-dependent
units. The only exception are rectangles for images in raw formats, whose
coordinates are always expressed in pixels. </para>
coordinates are always expressed in pixels.</para>
<para> To change the cropping (composing) rectangle set the &v4l2-selection;
<para>To change the cropping (composing) rectangle set the &v4l2-selection;
<structfield>type</structfield> field to the respective buffer type. Do not
use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE
</constant> instead of <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
</constant>. Use <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> instead of
<constant> V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE </constant>. The next step is
use multiplanar buffers. Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. Use
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>. The next step is
setting the value of &v4l2-selection; <structfield>target</structfield> to
<constant>V4L2_SEL_TGT_CROP</constant> (<constant>
V4L2_SEL_TGT_COMPOSE </constant>). Please refer to table <xref
linkend="v4l2-selections-common" /> or <xref linkend="selection-api" /> for additional
targets. The &v4l2-rect; <structfield>r</structfield> rectangle need to be
<constant>V4L2_SEL_TGT_CROP</constant> (<constant>V4L2_SEL_TGT_COMPOSE</constant>).
Please refer to table <xref linkend="v4l2-selections-common" /> or <xref linkend="selection-api" />
for additional targets. The &v4l2-rect; <structfield>r</structfield> rectangle need to be
set to the desired active area. Field &v4l2-selection; <structfield> reserved
</structfield> is ignored and must be filled with zeros. The driver may adjust
coordinates of the requested rectangle. An application may
@ -149,8 +147,8 @@ On success the &v4l2-rect; <structfield>r</structfield> field contains
the adjusted rectangle. When the parameters are unsuitable the application may
modify the cropping (composing) or image parameters and repeat the cycle until
satisfactory parameters have been negotiated. If constraints flags have to be
violated at then ERANGE is returned. The error indicates that <emphasis> there
exist no rectangle </emphasis> that satisfies the constraints.</para>
violated at then ERANGE is returned. The error indicates that <emphasis>there
exist no rectangle</emphasis> that satisfies the constraints.</para>
<para>Selection targets and flags are documented in <xref
linkend="v4l2-selections-common"/>.</para>

View File

@ -300,6 +300,12 @@ modulator programming see
<entry>0x00100000</entry>
<entry>The device supports the
<link linkend="sdr">SDR Capture</link> interface.</entry>
</row>
<row>
<entry><constant>V4L2_CAP_EXT_PIX_FORMAT</constant></entry>
<entry>0x00200000</entry>
<entry>The device supports the &v4l2-pix-format; extended
fields.</entry>
</row>
<row>
<entry><constant>V4L2_CAP_READWRITE</constant></entry>

View File

@ -1,11 +1,12 @@
<refentry id="vidioc-queryctrl">
<refmeta>
<refentrytitle>ioctl VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</refentrytitle>
<refentrytitle>ioctl VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL, VIDIOC_QUERYMENU</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_QUERYCTRL</refname>
<refname>VIDIOC_QUERY_EXT_CTRL</refname>
<refname>VIDIOC_QUERYMENU</refname>
<refpurpose>Enumerate controls and menu control items</refpurpose>
</refnamediv>
@ -19,6 +20,14 @@
<paramdef>struct v4l2_queryctrl *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_query_ext_ctrl *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
@ -42,7 +51,7 @@
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</para>
<para>VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL, VIDIOC_QUERYMENU</para>
</listitem>
</varlistentry>
<varlistentry>
@ -67,7 +76,7 @@ structure. The driver fills the rest of the structure or returns an
<constant>VIDIOC_QUERYCTRL</constant> with successive
<structfield>id</structfield> values starting from
<constant>V4L2_CID_BASE</constant> up to and exclusive
<constant>V4L2_CID_BASE_LASTP1</constant>. Drivers may return
<constant>V4L2_CID_LASTP1</constant>. Drivers may return
<errorcode>EINVAL</errorcode> if a control in this range is not
supported. Further applications can enumerate private controls, which
are not defined in this specification, by starting at
@ -89,9 +98,23 @@ prematurely end the enumeration).</para></footnote></para>
<para>When the application ORs <structfield>id</structfield> with
<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> the driver returns the
next supported control, or <errorcode>EINVAL</errorcode> if there is
none. Drivers which do not support this flag yet always return
<errorcode>EINVAL</errorcode>.</para>
next supported non-compound control, or <errorcode>EINVAL</errorcode>
if there is none. In addition, the <constant>V4L2_CTRL_FLAG_NEXT_COMPOUND</constant>
flag can be specified to enumerate all compound controls (i.e. controls
with type &ge; <constant>V4L2_CTRL_COMPOUND_TYPES</constant>). Specify both
<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> and
<constant>V4L2_CTRL_FLAG_NEXT_COMPOUND</constant> in order to enumerate
all controls, compound or not. Drivers which do not support these flags yet
always return <errorcode>EINVAL</errorcode>.</para>
<para>The <constant>VIDIOC_QUERY_EXT_CTRL</constant> ioctl was
introduced in order to better support controls that can use compound
types, and to expose additional control information that cannot be
returned in &v4l2-queryctrl; since that structure is full.</para>
<para><constant>VIDIOC_QUERY_EXT_CTRL</constant> is used in the
same way as <constant>VIDIOC_QUERYCTRL</constant>, except that the
<structfield>reserved</structfield> array must be zeroed as well.</para>
<para>Additional information is required for menu controls: the
names of the menu items. To query them applications set the
@ -142,38 +165,23 @@ string. This information is intended for the user.</entry>
<entry>__s32</entry>
<entry><structfield>minimum</structfield></entry>
<entry>Minimum value, inclusive. This field gives a lower
bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
lowest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant> controls.
For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the minimum value
gives the minimum length of the string. This length <emphasis>does not include the terminating
zero</emphasis>. It may not be valid for any other type of control, including
<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
signed value.</entry>
bound for the control. See &v4l2-ctrl-type; how the minimum value is to
be used for each possible control type. Note that this a signed 32-bit value.</entry>
</row>
<row>
<entry>__s32</entry>
<entry><structfield>maximum</structfield></entry>
<entry>Maximum value, inclusive. This field gives an upper
bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
highest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant>
controls. For <constant>V4L2_CTRL_TYPE_BITMASK</constant> controls it is the
set of usable bits.
For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the maximum value
gives the maximum length of the string. This length <emphasis>does not include the terminating
zero</emphasis>. It may not be valid for any other type of control, including
<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
signed value.</entry>
bound for the control. See &v4l2-ctrl-type; how the maximum value is to
be used for each possible control type. Note that this a signed 32-bit value.</entry>
</row>
<row>
<entry>__s32</entry>
<entry><structfield>step</structfield></entry>
<entry><para>This field gives a step size for
<constant>V4L2_CTRL_TYPE_INTEGER</constant> controls. For
<constant>V4L2_CTRL_TYPE_STRING</constant> controls this field refers to
the string length that has to be a multiple of this step size.
It may not be valid for any other type of control, including
<constant>V4L2_CTRL_TYPE_INTEGER64</constant>
controls.</para><para>Generally drivers should not scale hardware
<entry><para>This field gives a step size for the control.
See &v4l2-ctrl-type; how the step value is to be used for each possible
control type. Note that this an unsigned 32-bit value.
</para><para>Generally drivers should not scale hardware
control values. It may be necessary for example when the
<structfield>name</structfield> or <structfield>id</structfield> imply
a particular unit and the hardware actually accepts only multiples of
@ -192,10 +200,11 @@ be always positive.</para></entry>
<entry><structfield>default_value</structfield></entry>
<entry>The default value of a
<constant>V4L2_CTRL_TYPE_INTEGER</constant>,
<constant>_BOOLEAN</constant> or <constant>_MENU</constant> control.
Not valid for other types of controls. Drivers reset controls only
when the driver is loaded, not later, in particular not when the
func-open; is called.</entry>
<constant>_BOOLEAN</constant>, <constant>_BITMASK</constant>,
<constant>_MENU</constant> or <constant>_INTEGER_MENU</constant> control.
Not valid for other types of controls.
Note that drivers reset controls to their default value only when the
driver is first loaded, never afterwards.</entry>
</row>
<row>
<entry>__u32</entry>
@ -213,6 +222,126 @@ the array to zero.</entry>
</tgroup>
</table>
<table pgwide="1" frame="none" id="v4l2-query-ext-ctrl">
<title>struct <structname>v4l2_query_ext_ctrl</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>id</structfield></entry>
<entry>Identifies the control, set by the application. See
<xref linkend="control-id" /> for predefined IDs. When the ID is ORed
with <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> the driver clears the
flag and returns the first non-compound control with a higher ID. When the
ID is ORed with <constant>V4L2_CTRL_FLAG_NEXT_COMPOUND</constant> the driver
clears the flag and returns the first compound control with a higher ID.
Set both to get the first control (compound or not) with a higher ID.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>type</structfield></entry>
<entry>Type of control, see <xref
linkend="v4l2-ctrl-type" />.</entry>
</row>
<row>
<entry>char</entry>
<entry><structfield>name</structfield>[32]</entry>
<entry>Name of the control, a NUL-terminated ASCII
string. This information is intended for the user.</entry>
</row>
<row>
<entry>__s64</entry>
<entry><structfield>minimum</structfield></entry>
<entry>Minimum value, inclusive. This field gives a lower
bound for the control. See &v4l2-ctrl-type; how the minimum value is to
be used for each possible control type. Note that this a signed 64-bit value.</entry>
</row>
<row>
<entry>__s64</entry>
<entry><structfield>maximum</structfield></entry>
<entry>Maximum value, inclusive. This field gives an upper
bound for the control. See &v4l2-ctrl-type; how the maximum value is to
be used for each possible control type. Note that this a signed 64-bit value.</entry>
</row>
<row>
<entry>__u64</entry>
<entry><structfield>step</structfield></entry>
<entry><para>This field gives a step size for the control.
See &v4l2-ctrl-type; how the step value is to be used for each possible
control type. Note that this an unsigned 64-bit value.
</para><para>Generally drivers should not scale hardware
control values. It may be necessary for example when the
<structfield>name</structfield> or <structfield>id</structfield> imply
a particular unit and the hardware actually accepts only multiples of
said unit. If so, drivers must take care values are properly rounded
when scaling, such that errors will not accumulate on repeated
read-write cycles.</para><para>This field gives the smallest change of
an integer control actually affecting hardware. Often the information
is needed when the user can change controls by keyboard or GUI
buttons, rather than a slider. When for example a hardware register
accepts values 0-511 and the driver reports 0-65535, step should be
128.</para></entry>
</row>
<row>
<entry>__s64</entry>
<entry><structfield>default_value</structfield></entry>
<entry>The default value of a
<constant>V4L2_CTRL_TYPE_INTEGER</constant>, <constant>_INTEGER64</constant>,
<constant>_BOOLEAN</constant>, <constant>_BITMASK</constant>,
<constant>_MENU</constant>, <constant>_INTEGER_MENU</constant>,
<constant>_U8</constant> or <constant>_U16</constant> control.
Not valid for other types of controls.
Note that drivers reset controls to their default value only when the
driver is first loaded, never afterwards.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>flags</structfield></entry>
<entry>Control flags, see <xref
linkend="control-flags" />.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>elem_size</structfield></entry>
<entry>The size in bytes of a single element of the array.
Given a char pointer <constant>p</constant> to a 3-dimensional array you can find the
position of cell <constant>(z, y, x)</constant> as follows:
<constant>p + ((z * dims[1] + y) * dims[0] + x) * elem_size</constant>. <structfield>elem_size</structfield>
is always valid, also when the control isn't an array. For string controls
<structfield>elem_size</structfield> is equal to <structfield>maximum + 1</structfield>.
</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>elems</structfield></entry>
<entry>The number of elements in the N-dimensional array. If this control
is not an array, then <structfield>elems</structfield> is 1. The <structfield>elems</structfield>
field can never be 0.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>nr_of_dims</structfield></entry>
<entry>The number of dimension in the N-dimensional array. If this control
is not an array, then this field is 0.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>dims[V4L2_CTRL_MAX_DIMS]</structfield></entry>
<entry>The size of each dimension. The first <structfield>nr_of_dims</structfield>
elements of this array must be non-zero, all remaining elements must be zero.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[32]</entry>
<entry>Reserved for future extensions. Applications and drivers
must set the array to zero.</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="v4l2-querymenu">
<title>struct <structname>v4l2_querymenu</structname></title>
<tgroup cols="4">
@ -347,11 +476,14 @@ Drivers must ignore the value passed with
</row>
<row>
<entry><constant>V4L2_CTRL_TYPE_INTEGER64</constant></entry>
<entry>n/a</entry>
<entry>n/a</entry>
<entry>n/a</entry>
<entry>any</entry>
<entry>any</entry>
<entry>any</entry>
<entry>A 64-bit integer valued control. Minimum, maximum
and step size cannot be queried.</entry>
and step size cannot be queried using <constant>VIDIOC_QUERYCTRL</constant>.
Only <constant>VIDIOC_QUERY_EXT_CTRL</constant> can retrieve the 64-bit
min/max/step values, they should be interpreted as n/a when using
<constant>VIDIOC_QUERYCTRL</constant>.</entry>
</row>
<row>
<entry><constant>V4L2_CTRL_TYPE_STRING</constant></entry>
@ -379,6 +511,26 @@ ioctl returns the name of the control class and this control type.
Older drivers which do not support this feature return an
&EINVAL;.</entry>
</row>
<row>
<entry><constant>V4L2_CTRL_TYPE_U8</constant></entry>
<entry>any</entry>
<entry>any</entry>
<entry>any</entry>
<entry>An unsigned 8-bit valued control ranging from minimum to
maximum inclusive. The step value indicates the increment between
values which are actually different on the hardware.
</entry>
</row>
<row>
<entry><constant>V4L2_CTRL_TYPE_U16</constant></entry>
<entry>any</entry>
<entry>any</entry>
<entry>any</entry>
<entry>An unsigned 16-bit valued control ranging from minimum to
maximum inclusive. The step value indicates the increment between
values which are actually different on the hardware.
</entry>
</row>
</tbody>
</tgroup>
</table>
@ -450,6 +602,14 @@ is in auto-gain mode. In such a case the hardware calculates the gain value base
the lighting conditions which can change over time. Note that setting a new value for
a volatile control will have no effect. The new value will just be ignored.</entry>
</row>
<row>
<entry><constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant></entry>
<entry>0x0100</entry>
<entry>This control has a pointer type, so its value has to be accessed
using one of the pointer fields of &v4l2-ext-control;. This flag is set for controls
that are an array, string, or have a compound type. In all cases you have to set a
pointer to memory containing the payload of the control.</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -174,6 +174,14 @@
will have the ORed value of all the events generated.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_MOTION_DET</constant></entry>
<entry>5</entry>
<entry>
<para>Triggered whenever the motion detection state for one or more of the regions
changes. This event has a &v4l2-event-motion-det; associated with it.</para>
</entry>
</row>
<row>
<entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
<entry>0x08000000</entry>

View File

@ -0,0 +1,51 @@
Atmel Image Sensor Interface (ISI) SoC Camera Subsystem
----------------------------------------------
Required properties:
- compatible: must be "atmel,at91sam9g45-isi"
- reg: physical base address and length of the registers set for the device;
- interrupts: should contain IRQ line for the ISI;
- clocks: list of clock specifiers, corresponding to entries in
the clock-names property;
- clock-names: must contain "isi_clk", which is the isi peripherial clock.
ISI supports a single port node with parallel bus. It should contain one
'port' child node with child 'endpoint' node. Please refer to the bindings
defined in Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
isi: isi@f0034000 {
compatible = "atmel,at91sam9g45-isi";
reg = <0xf0034000 0x4000>;
interrupts = <37 IRQ_TYPE_LEVEL_HIGH 5>;
clocks = <&isi_clk>;
clock-names = "isi_clk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_isi>;
port {
#address-cells = <1>;
#size-cells = <0>;
isi_0: endpoint {
remote-endpoint = <&ov2640_0>;
bus-width = <8>;
};
};
};
i2c1: i2c@f0018000 {
ov2640: camera@0x30 {
compatible = "omnivision,ov2640";
reg = <0x30>;
port {
ov2640_0: endpoint {
remote-endpoint = <&isi_0>;
bus-width = <8>;
};
};
};
};

View File

@ -3,9 +3,13 @@ Samsung S5P/EXYNOS SoC series JPEG codec
Required properties:
- compatible : should be one of:
"samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg";
"samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg",
"samsung,exynos3250-jpeg";
- reg : address and length of the JPEG codec IP register set;
- interrupts : specifies the JPEG codec IP interrupt;
- clocks : should contain the JPEG codec IP gate clock specifier, from the
common clock bindings;
- clock-names : should contain "jpeg" entry.
- clock-names : should contain:
- "jpeg" for the core gate clock,
- "sclk" for the special clock (optional).
- clocks : should contain the clock specifier and clock ID list
matching entries in the clock-names property; from
the common clock bindings.

View File

@ -0,0 +1,28 @@
Micron 1.3Mp CMOS Digital Image Sensor
The Micron MT9M111 is a CMOS active pixel digital image sensor with an active
array size of 1280H x 1024V. It is programmable through a simple two-wire serial
interface.
Required Properties:
- compatible: value should be "micron,mt9m111"
For further reading on port node refer to
Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
i2c_master {
mt9m111@5d {
compatible = "micron,mt9m111";
reg = <0x5d>;
remote = <&pxa_camera>;
port {
mt9m111_1: endpoint {
bus-width = <8>;
remote-endpoint = <&pxa_camera>;
};
};
};
};

View File

@ -0,0 +1,43 @@
Marvell PXA camera host interface
Required properties:
- compatible: Should be "marvell,pxa270-qci"
- reg: register base and size
- interrupts: the interrupt number
- any required generic properties defined in video-interfaces.txt
Optional properties:
- clocks: input clock (see clock-bindings.txt)
- clock-output-names: should contain the name of the clock driving the
sensor master clock MCLK
- clock-frequency: host interface is driving MCLK, and MCLK rate is this rate
Example:
pxa_camera: pxa_camera@50000000 {
compatible = "marvell,pxa270-qci";
reg = <0x50000000 0x1000>;
interrupts = <33>;
clocks = <&pxa2xx_clks 24>;
clock-names = "ciclk";
clock-frequency = <50000000>;
clock-output-names = "qci_mclk";
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
/* Parallel bus endpoint */
qci: endpoint@0 {
reg = <0>; /* Local endpoint # */
remote-endpoint = <&mt9m111_1>;
bus-width = <8>; /* Used data lines */
hsync-active = <0>; /* Active low */
vsync-active = <0>; /* Active low */
pclk-sample = <1>; /* Rising */
};
};
};

View File

@ -0,0 +1,86 @@
Renesas RCar Video Input driver (rcar_vin)
------------------------------------------
The rcar_vin device provides video input capabilities for the Renesas R-Car
family of devices. The current blocks are always slaves and suppot one input
channel which can be either RGB, YUYV or BT656.
- compatible: Must be one of the following
- "renesas,vin-r8a7791" for the R8A7791 device
- "renesas,vin-r8a7790" for the R8A7790 device
- "renesas,vin-r8a7779" for the R8A7779 device
- "renesas,vin-r8a7778" for the R8A7778 device
- reg: the register base and size for the device registers
- interrupts: the interrupt for the device
- clocks: Reference to the parent clock
Additionally, an alias named vinX will need to be created to specify
which video input device this is.
The per-board settings:
- port sub-node describing a single endpoint connected to the vin
as described in video-interfaces.txt[1]. Only the first one will
be considered as each vin interface has one input port.
These settings are used to work out video input format and widths
into the system.
Device node example
-------------------
aliases {
vin0 = &vin0;
};
vin0: vin@0xe6ef0000 {
compatible = "renesas,vin-r8a7790";
clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
reg = <0 0xe6ef0000 0 0x1000>;
interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
Board setup example (vin1 composite video input)
------------------------------------------------
&i2c2 {
status = "ok";
pinctrl-0 = <&i2c2_pins>;
pinctrl-names = "default";
adv7180@20 {
compatible = "adi,adv7180";
reg = <0x20>;
remote = <&vin1>;
port {
adv7180: endpoint {
bus-width = <8>;
remote-endpoint = <&vin1ep0>;
};
};
};
};
/* composite video input */
&vin1 {
pinctrl-0 = <&vin1_pins>;
pinctrl-names = "default";
status = "ok";
port {
#address-cells = <1>;
#size-cells = <0>;
vin1ep0: endpoint {
remote-endpoint = <&adv7180>;
bus-width = <8>;
};
};
};
[1] video-interfaces.txt common video media interface

View File

@ -0,0 +1,23 @@
Device-Tree bindings for SUNXI IR controller found in sunXi SoC family
Required properties:
- compatible : should be "allwinner,sun4i-a10-ir";
- clocks : list of clock specifiers, corresponding to
entries in clock-names property;
- clock-names : should contain "apb" and "ir" entries;
- interrupts : should contain IR IRQ number;
- reg : should contain IO map address for IR.
Optional properties:
- linux,rc-map-name : Remote control map name.
Example:
ir0: ir@01c21800 {
compatible = "allwinner,sun4i-a10-ir";
clocks = <&apb0_gates 6>, <&ir0_clk>;
clock-names = "apb", "ir";
interrupts = <0 5 1>;
reg = <0x01C21800 0x40>;
linux,rc-map-name = "rc-rc6-mce";
};

View File

@ -29,7 +29,7 @@ use IO::Handle;
"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
"lme2510c_s7395_old", "drxk", "drxk_terratec_h5",
"drxk_hauppauge_hvr930c", "tda10071", "it9135", "drxk_pctv",
"drxk_terratec_htc_stick", "sms1xxx_hcw");
"drxk_terratec_htc_stick", "sms1xxx_hcw", "si2165");
# Check args
syntax() if (scalar(@ARGV) != 1);
@ -783,6 +783,37 @@ sub sms1xxx_hcw {
$allfiles;
}
sub si2165 {
my $sourcefile = "model_111xxx_122xxx_driver_6_0_119_31191_WHQL.zip";
my $url = "http://www.hauppauge.de/files/drivers/";
my $hash = "76633e7c76b0edee47c3ba18ded99336";
my $fwfile = "dvb-demod-si2165.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
checkstandard();
wgetfile($sourcefile, $url . $sourcefile);
verify($sourcefile, $hash);
unzip($sourcefile, $tmpdir);
extract("$tmpdir/Driver10/Hcw10bda.sys", 0x80788, 0x81E08-0x80788, "$tmpdir/fw1");
delzero("$tmpdir/fw1","$tmpdir/fw1-1");
#verify("$tmpdir/fw1","5e0909858fdf0b5b09ad48b9fe622e70");
my $CRC="\x0A\xCC";
my $BLOCKS_MAIN="\x27";
open FW,">$fwfile";
print FW "\x01\x00"; # just a version id for the driver itself
print FW "\x9A"; # fw version
print FW "\x00"; # padding
print FW "$BLOCKS_MAIN"; # number of blocks of main part
print FW "\x00"; # padding
print FW "$CRC"; # 16bit crc value of main part
appendfile(FW,"$tmpdir/fw1");
"$fwfile";
}
# ---------------------------------------------------------------
# Utilities

View File

@ -41,3 +41,5 @@
40 -> TurboSight TBS 6981 [6981:8888]
41 -> TurboSight TBS 6980 [6980:8888]
42 -> Leadtek Winfast PxPVR2200 [107d:6f21]
43 -> Hauppauge ImpactVCB-e [0070:7133]
44 -> DViCO FusionHDTV DVB-T Dual Express2 [18ac:db98]

View File

@ -77,7 +77,7 @@
76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340]
77 -> EM2874 Leadership ISDBT (em2874)
78 -> PCTV nanoStick T2 290e (em28174)
79 -> Terratec Cinergy H5 (em2884) [0ccd:10a2,0ccd:10ad,0ccd:10b6]
79 -> Terratec Cinergy H5 (em2884) [eb1a:2885,0ccd:10a2,0ccd:10ad,0ccd:10b6]
80 -> PCTV DVB-S2 Stick (460e) (em28174)
81 -> Hauppauge WinTV HVR 930C (em2884) [2040:1605]
82 -> Terratec Cinergy HTC Stick (em2884) [0ccd:00b2]

View File

@ -77,9 +77,9 @@ Basic usage for V4L2 and sub-device drivers
Where foo->v4l2_dev is of type struct v4l2_device.
Finally, remove all control functions from your v4l2_ioctl_ops:
vidioc_queryctrl, vidioc_querymenu, vidioc_g_ctrl, vidioc_s_ctrl,
vidioc_g_ext_ctrls, vidioc_try_ext_ctrls and vidioc_s_ext_ctrls.
Finally, remove all control functions from your v4l2_ioctl_ops (if any):
vidioc_queryctrl, vidioc_query_ext_ctrl, vidioc_querymenu, vidioc_g_ctrl,
vidioc_s_ctrl, vidioc_g_ext_ctrls, vidioc_try_ext_ctrls and vidioc_s_ext_ctrls.
Those are now no longer needed.
1.3.2) For sub-device drivers do this:
@ -258,8 +258,8 @@ The new control value has already been validated, so all you need to do is
to actually update the hardware registers.
You're done! And this is sufficient for most of the drivers we have. No need
to do any validation of control values, or implement QUERYCTRL/QUERYMENU. And
G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported.
to do any validation of control values, or implement QUERYCTRL, QUERY_EXT_CTRL
and QUERYMENU. And G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported.
==============================================================================
@ -288,30 +288,45 @@ of v4l2_device.
Accessing Control Values
========================
The v4l2_ctrl struct contains these two unions:
The following union is used inside the control framework to access control
values:
/* The current control value. */
union {
union v4l2_ctrl_ptr {
s32 *p_s32;
s64 *p_s64;
char *p_char;
void *p;
};
The v4l2_ctrl struct contains these fields that can be used to access both
current and new values:
s32 val;
struct {
s32 val;
s64 val64;
char *string;
} cur;
/* The new control value. */
union {
s32 val;
s64 val64;
char *string;
};
Within the control ops you can freely use these. The val and val64 speak for
themselves. The string pointers point to character buffers of length
union v4l2_ctrl_ptr p_new;
union v4l2_ctrl_ptr p_cur;
If the control has a simple s32 type type, then:
&ctrl->val == ctrl->p_new.p_s32
&ctrl->cur.val == ctrl->p_cur.p_s32
For all other types use ctrl->p_cur.p<something>. Basically the val
and cur.val fields can be considered an alias since these are used so often.
Within the control ops you can freely use these. The val and cur.val speak for
themselves. The p_char pointers point to character buffers of length
ctrl->maximum + 1, and are always 0-terminated.
In most cases 'cur' contains the current cached control value. When you create
a new control this value is made identical to the default value. After calling
v4l2_ctrl_handler_setup() this value is passed to the hardware. It is generally
a good idea to call this function.
Unless the control is marked volatile the p_cur field points to the the
current cached control value. When you create a new control this value is made
identical to the default value. After calling v4l2_ctrl_handler_setup() this
value is passed to the hardware. It is generally a good idea to call this
function.
Whenever a new value is set that new value is automatically cached. This means
that most drivers do not need to implement the g_volatile_ctrl() op. The
@ -362,8 +377,8 @@ will result in a deadlock since these helpers lock the handler as well.
You can also take the handler lock yourself:
mutex_lock(&state->ctrl_handler.lock);
printk(KERN_INFO "String value is '%s'\n", ctrl1->cur.string);
printk(KERN_INFO "Integer value is '%s'\n", ctrl2->cur.val);
pr_info("String value is '%s'\n", ctrl1->p_cur.p_char);
pr_info("Integer value is '%s'\n", ctrl2->cur.val);
mutex_unlock(&state->ctrl_handler.lock);

View File

@ -675,11 +675,6 @@ You should also set these fields:
video_device is initialized you *do* know which parent PCI device to use and
so you set dev_device to the correct PCI device.
- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
v4l2_fh. Eventually this flag will disappear once all drivers use the core
priority handling. But for now it has to be set explicitly.
If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2
in your v4l2_file_operations struct.
@ -909,8 +904,7 @@ struct v4l2_fh
struct v4l2_fh provides a way to easily keep file handle specific data
that is used by the V4L2 framework. New drivers must use struct v4l2_fh
since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY)
if the video_device flag V4L2_FL_USE_FH_PRIO is also set.
since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY).
The users of v4l2_fh (in the V4L2 framework, not the driver) know
whether a driver uses v4l2_fh as its file->private_data pointer by

View File

@ -883,11 +883,6 @@ static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
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);

View File

@ -580,11 +580,6 @@ release()回调必须被设置,且在最后一个 video_device 用户退出之
v4l2_device 无法与特定的 PCI 设备关联,所有没有设置父设备。但当
video_device 配置后,就知道使用哪个父 PCI 设备了。
- flags可选。如果你要让框架处理设置 VIDIOC_G/S_PRIORITY ioctls
请设置 V4L2_FL_USE_FH_PRIO。这要求你使用 v4l2_fh 结构体。
一旦所有驱动使用了核心的优先级处理,最终这个标志将消失。但现在它
必须被显式设置。
如果你使用 v4l2_ioctl_ops则应该在 v4l2_file_operations 结构体中
设置 .unlocked_ioctl 指向 video_ioctl2。
@ -789,7 +784,7 @@ v4l2_fh 结构体
-------------
v4l2_fh 结构体提供一个保存用于 V4L2 框架的文件句柄特定数据的简单方法。
如果 video_device 的 flag 设置了 V4L2_FL_USE_FH_PRIO 标志,新驱动
如果 video_device 标志,新驱动
必须使用 v4l2_fh 结构体因为它也用于实现优先级处理VIDIOC_G/S_PRIORITY
v4l2_fh 的用户(位于 V4l2 框架中,并非驱动)可通过测试

View File

@ -516,6 +516,16 @@ S: Supported
F: fs/aio.c
F: include/linux/*aio*.h
AIRSPY MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
W: http://palosaari.fi/linux/
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/usb/airspy/
ALCATEL SPEEDTOUCH USB DRIVER
M: Duncan Sands <duncan.sands@free.fr>
L: linux-usb@vger.kernel.org
@ -3993,6 +4003,12 @@ F: Documentation/isdn/README.gigaset
F: drivers/isdn/gigaset/
F: include/uapi/linux/gigaset_dev.h
GO7007 MPEG CODEC
M: Hans Verkuil <hans.verkuil@cisco.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/usb/go7007/
GPIO SUBSYSTEM
M: Linus Walleij <linus.walleij@linaro.org>
M: Alexandre Courbot <gnurou@gmail.com>
@ -5965,9 +5981,9 @@ 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*
F: drivers/media/tuners/msi001*
MSI3101 MEDIA DRIVER
MSI2500 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: http://linuxtv.org/
@ -5975,7 +5991,7 @@ 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*
F: drivers/media/usb/msi2500/
MT9M032 APTINA SENSOR DRIVER
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
@ -6499,11 +6515,12 @@ L: linux-omap@vger.kernel.org
S: Maintained
F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c
OMAP IMAGE SIGNAL PROCESSOR (ISP)
OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS)
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/platform/omap3isp/
F: drivers/staging/media/omap4iss/
OMAP USB SUPPORT
M: Felipe Balbi <balbi@ti.com>
@ -7611,7 +7628,7 @@ 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*
F: drivers/media/dvb-frontends/rtl2832_sdr*
RTL8180 WIRELESS DRIVER
M: "John W. Linville" <linville@tuxdriver.com>
@ -8380,6 +8397,12 @@ M: Chris Boot <bootc@bootc.net>
S: Maintained
F: drivers/leds/leds-net48xx.c
SOFTLOGIC 6x10 MPEG CODEC
M: Ismael Luceno <ismael.luceno@corp.bluecherry.net>
L: linux-media@vger.kernel.org
S: Supported
F: drivers/media/pci/solo6x10/
SOFTWARE RAID (Multiple Disks) SUPPORT
M: Neil Brown <neilb@suse.de>
L: linux-raid@vger.kernel.org
@ -8586,11 +8609,6 @@ M: Marek Belisko <marek.belisko@gmail.com>
S: Odd Fixes
F: drivers/staging/ft1000/
STAGING - GO7007 MPEG CODEC
M: Hans Verkuil <hans.verkuil@cisco.com>
S: Maintained
F: drivers/staging/media/go7007/
STAGING - INDUSTRIAL IO
M: Jonathan Cameron <jic23@kernel.org>
L: linux-iio@vger.kernel.org
@ -8648,11 +8666,6 @@ M: Christopher Harrer <charrer@alacritech.com>
S: Odd Fixes
F: drivers/staging/slicoss/
STAGING - SOFTLOGIC 6x10 MPEG CODEC
M: Ismael Luceno <ismael.luceno@corp.bluecherry.net>
S: Supported
F: drivers/staging/media/solo6x10/
STAGING - SPEAKUP CONSOLE SPEECH DRIVER
M: William Hubbs <w.d.hubbs@gmail.com>
M: Chris Brannon <chris@the-brannons.com>
@ -9519,15 +9532,6 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/usb/smsc95xx.*
USB SN9C1xx DRIVER
M: Luca Risolia <luca.risolia@studio.unibo.it>
L: linux-usb@vger.kernel.org
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://www.linux-projects.org
S: Maintained
F: drivers/staging/media/sn9c102/
USB SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: linux-usb@vger.kernel.org

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;
rc_set_allowed_protocols(rdev, RC_BIT_ALL);
rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = picolcd_cir_open;
rdev->close = picolcd_cir_close;
rdev->input_name = data->hdev->name;

View File

@ -59,6 +59,13 @@ config MEDIA_RADIO_SUPPORT
support radio reception. Disabling this option will
disable support for them.
config MEDIA_SDR_SUPPORT
bool "Software defined radio support"
---help---
Enable software defined radio support.
Say Y when you have a software defined radio device.
config MEDIA_RC_SUPPORT
bool "Remote Controller support"
depends on INPUT
@ -95,7 +102,7 @@ config MEDIA_CONTROLLER
config VIDEO_DEV
tristate
depends on MEDIA_SUPPORT
depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT
depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
default y
config VIDEO_V4L2_SUBDEV_API
@ -171,10 +178,11 @@ comment "Media ancillary drivers (tuners, sensors, i2c, frontends)"
config MEDIA_SUBDRV_AUTOSELECT
bool "Autoselect ancillary drivers (tuners, sensors, i2c, frontends)"
depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT
depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT || MEDIA_SDR_SUPPORT
depends on HAS_IOMEM
select I2C
select I2C_MUX
select SPI
default y
help
By default, a media driver auto-selects all possible ancillary

View File

@ -533,13 +533,12 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
saa7146_vbi_uops.init(dev,vv);
fmt = &vv->ov_fb.fmt;
fmt->width = vv->standard->h_max_out;
fmt->height = vv->standard->v_max_out;
fmt->pixelformat = V4L2_PIX_FMT_RGB565;
fmt->bytesperline = 2 * fmt->width;
fmt->sizeimage = fmt->bytesperline * fmt->height;
fmt->colorspace = V4L2_COLORSPACE_SRGB;
vv->ov_fb.fmt.width = vv->standard->h_max_out;
vv->ov_fb.fmt.height = vv->standard->v_max_out;
vv->ov_fb.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
vv->ov_fb.fmt.bytesperline = 2 * vv->ov_fb.fmt.width;
vv->ov_fb.fmt.sizeimage = vv->ov_fb.fmt.bytesperline * vv->ov_fb.fmt.height;
vv->ov_fb.fmt.colorspace = V4L2_COLORSPACE_SRGB;
fmt = &vv->video_fmt;
fmt->width = 384;
@ -613,7 +612,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
vfd->lock = &dev->v4l2_lock;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->tvnorms = 0;
set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
strlcpy(vfd->name, name, sizeof(vfd->name));

View File

@ -22,8 +22,7 @@ config SMS_SIANO_DEBUGFS
bool "Enable debugfs for smsdvb"
depends on SMS_SIANO_MDTV
depends on DEBUG_FS
depends on SMS_USB_DRV
depends on CONFIG_SMS_USB_DRV = CONFIG_SMS_SDIO_DRV
depends on SMS_USB_DRV = SMS_SDIO_DRV
---help---
Choose Y to enable visualizing a dump of the frontend

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;
rc_set_allowed_protocols(dev, RC_BIT_ALL);
dev->allowed_protocols = RC_BIT_ALL;
dev->map_name = sms_get_board(board_id)->rc_codes;
dev->driver_name = MODULE_NAME;

View File

@ -244,6 +244,7 @@
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
@ -363,6 +364,7 @@
#define USB_PID_TVWAY_PLUS 0x0002
#define USB_PID_SVEON_STV20 0xe39d
#define USB_PID_SVEON_STV20_RTL2832U 0xd39d
#define USB_PID_SVEON_STV21 0xd3b0
#define USB_PID_SVEON_STV22 0xe401
#define USB_PID_SVEON_STV22_IT9137 0xe411
#define USB_PID_AZUREWAVE_AZ6027 0x3275

View File

@ -96,10 +96,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
* FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
*/
#define DVB_FE_NO_EXIT 0
#define DVB_FE_NORMAL_EXIT 1
#define DVB_FE_DEVICE_REMOVED 2
static DEFINE_MUTEX(frontend_mutex);
struct dvb_frontend_private {
@ -113,7 +109,6 @@ struct dvb_frontend_private {
wait_queue_head_t wait_queue;
struct task_struct *thread;
unsigned long release_jiffies;
unsigned int exit;
unsigned int wakeup;
fe_status_t status;
unsigned long tune_mode_flags;
@ -565,7 +560,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
if (fepriv->exit != DVB_FE_NO_EXIT)
if (fe->exit != DVB_FE_NO_EXIT)
return 1;
if (fepriv->dvbdev->writers == 1)
@ -629,7 +624,7 @@ static int dvb_frontend_thread(void *data)
/* got signal or quitting */
if (!down_interruptible(&fepriv->sem))
semheld = true;
fepriv->exit = DVB_FE_NORMAL_EXIT;
fe->exit = DVB_FE_NORMAL_EXIT;
break;
}
@ -739,9 +734,9 @@ static int dvb_frontend_thread(void *data)
fepriv->thread = NULL;
if (kthread_should_stop())
fepriv->exit = DVB_FE_DEVICE_REMOVED;
fe->exit = DVB_FE_DEVICE_REMOVED;
else
fepriv->exit = DVB_FE_NO_EXIT;
fe->exit = DVB_FE_NO_EXIT;
mb();
if (semheld)
@ -756,7 +751,8 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s:\n", __func__);
fepriv->exit = DVB_FE_NORMAL_EXIT;
if (fe->exit != DVB_FE_DEVICE_REMOVED)
fe->exit = DVB_FE_NORMAL_EXIT;
mb();
if (!fepriv->thread)
@ -826,7 +822,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (fepriv->thread) {
if (fepriv->exit == DVB_FE_NO_EXIT)
if (fe->exit == DVB_FE_NO_EXIT)
return 0;
else
dvb_frontend_stop (fe);
@ -838,7 +834,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
return -EINTR;
fepriv->state = FESTATE_IDLE;
fepriv->exit = DVB_FE_NO_EXIT;
fe->exit = DVB_FE_NO_EXIT;
fepriv->thread = NULL;
mb();
@ -1906,7 +1902,7 @@ static int dvb_frontend_ioctl(struct file *file,
if (down_interruptible(&fepriv->sem))
return -ERESTARTSYS;
if (fepriv->exit != DVB_FE_NO_EXIT) {
if (fe->exit != DVB_FE_NO_EXIT) {
up(&fepriv->sem);
return -ENODEV;
}
@ -2424,7 +2420,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
int ret;
dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (fepriv->exit == DVB_FE_DEVICE_REMOVED)
if (fe->exit == DVB_FE_DEVICE_REMOVED)
return -ENODEV;
if (adapter->mfe_shared) {
@ -2529,7 +2525,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
if (dvbdev->users == -1) {
wake_up(&fepriv->wait_queue);
if (fepriv->exit != DVB_FE_NO_EXIT)
if (fe->exit != DVB_FE_NO_EXIT)
wake_up(&dvbdev->wait_queue);
if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0);
@ -2572,12 +2568,14 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
fe->id);
fe->exit = DVB_FE_DEVICE_RESUME;
if (fe->ops.init)
ret = fe->ops.init(fe);
if (fe->ops.tuner_ops.init)
ret = fe->ops.tuner_ops.init(fe);
fe->exit = DVB_FE_NO_EXIT;
fepriv->state = FESTATE_RETUNE;
dvb_frontend_wakeup(fe);
@ -2666,20 +2664,20 @@ void dvb_frontend_detach(struct dvb_frontend* fe)
if (fe->ops.release_sec) {
fe->ops.release_sec(fe);
symbol_put_addr(fe->ops.release_sec);
dvb_detach(fe->ops.release_sec);
}
if (fe->ops.tuner_ops.release) {
fe->ops.tuner_ops.release(fe);
symbol_put_addr(fe->ops.tuner_ops.release);
dvb_detach(fe->ops.tuner_ops.release);
}
if (fe->ops.analog_ops.release) {
fe->ops.analog_ops.release(fe);
symbol_put_addr(fe->ops.analog_ops.release);
dvb_detach(fe->ops.analog_ops.release);
}
ptr = (void*)fe->ops.release;
if (ptr) {
fe->ops.release(fe);
symbol_put_addr(ptr);
dvb_detach(ptr);
}
}
#else

View File

@ -405,6 +405,11 @@ struct dtv_frontend_properties {
struct dtv_fe_stats block_count;
};
#define DVB_FE_NO_EXIT 0
#define DVB_FE_NORMAL_EXIT 1
#define DVB_FE_DEVICE_REMOVED 2
#define DVB_FE_DEVICE_RESUME 3
struct dvb_frontend {
struct dvb_frontend_ops ops;
struct dvb_adapter *dvb;
@ -418,6 +423,7 @@ struct dvb_frontend {
#define DVB_FRONTEND_COMPONENT_DEMOD 1
int (*callback)(void *adapter_priv, int component, int cmd, int arg);
int id;
unsigned int exit;
};
extern int dvb_register_frontend(struct dvb_adapter *dvb,

View File

@ -136,11 +136,15 @@ extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
__r; \
})
#define dvb_detach(FUNC) symbol_put_addr(FUNC)
#else
#define dvb_attach(FUNCTION, ARGS...) ({ \
FUNCTION(ARGS); \
})
#define dvb_detach(FUNC) {}
#endif
#endif /* #ifndef _DVBDEV_H_ */

View File

@ -63,6 +63,15 @@ config DVB_TDA18271C2DD
Say Y when you want to support this tuner.
config DVB_SI2165
tristate "Silicon Labs si2165 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C/T demodulator.
Say Y when you want to support this frontend.
comment "DVB-S (satellite) frontends"
depends on DVB_CORE
@ -446,6 +455,15 @@ config DVB_RTL2832
help
Say Y when you want to support this frontend.
config DVB_RTL2832_SDR
tristate "Realtek RTL2832 SDR"
depends on DVB_CORE && I2C && I2C_MUX && VIDEO_V4L2 && MEDIA_SDR_SUPPORT && USB
select DVB_RTL2832
select VIDEOBUF2_VMALLOC
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this SDR module.
config DVB_SI2168
tristate "Silicon Labs Si2168"
depends on DVB_CORE && I2C && I2C_MUX

View File

@ -5,6 +5,11 @@
ccflags-y += -I$(srctree)/drivers/media/dvb-core/
ccflags-y += -I$(srctree)/drivers/media/tuners/
# FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
ifdef CONFIG_DVB_RTL2832_SDR
ccflags-y += -I$(srctree)/drivers/media/usb/dvb-usb-v2
endif
stb0899-objs := stb0899_drv.o stb0899_algo.o
stv0900-objs := stv0900_core.o stv0900_sw.o
drxd-objs := drxd_firm.o drxd_hard.o
@ -100,10 +105,12 @@ 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_SI2165) += si2165.o
obj-$(CONFIG_DVB_A8293) += a8293.o
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
obj-$(CONFIG_DVB_AF9033) += af9033.o

View File

@ -470,7 +470,6 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe)
break;
default:
goto err;
break;
}
for (i = 0; i < len; i++) {

View File

@ -220,7 +220,7 @@ static void setup_vbi(struct au8522_state *state, int aud_input)
}
static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
static void setup_decoder_defaults(struct au8522_state *state, bool is_svideo)
{
int i;
int filter_coef_type;
@ -237,13 +237,10 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
/* Other decoder registers */
au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
if (input_mode == 0x23) {
/* S-Video input mapping */
if (is_svideo)
au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
} else {
/* All other modes (CVBS/ATVRF etc.) */
else
au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
}
au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
AU8522_TVDEC_PGA_REG012H_CVBS);
@ -251,12 +248,23 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
AU8522_TVDED_DBG_MODE_REG060H_CVBS);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC);
if (state->std == V4L2_STD_PAL_M) {
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_AUTO);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M);
} else {
/* NTSC */
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN);
au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC);
}
au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
@ -275,8 +283,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
if (is_svideo) {
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
@ -317,8 +324,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
setup_vbi(state, 0);
if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
if (is_svideo) {
/* Despite what the table says, for the HVR-950q we still need
to be in CVBS mode for the S-Video input (reason unknown). */
/* filter_coef_type = 3; */
@ -346,7 +352,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
au8522_writereg(state, AU8522_REG436H, 0x3c);
}
static void au8522_setup_cvbs_mode(struct au8522_state *state)
static void au8522_setup_cvbs_mode(struct au8522_state *state, u8 input_mode)
{
/* here we're going to try the pre-programmed route */
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
@ -358,16 +364,16 @@ static void au8522_setup_cvbs_mode(struct au8522_state *state)
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
setup_decoder_defaults(state, false);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
}
static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state,
u8 input_mode)
{
/* here we're going to try the pre-programmed route */
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
@ -384,24 +390,22 @@ static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
/* Set input mode to CVBS on channel 4 with SIF audio input enabled */
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
setup_decoder_defaults(state,
AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
setup_decoder_defaults(state, false);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
}
static void au8522_setup_svideo_mode(struct au8522_state *state)
static void au8522_setup_svideo_mode(struct au8522_state *state,
u8 input_mode)
{
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
/* Set input to Y on Channe1, C on Channel 3 */
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
/* PGA in automatic mode */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
@ -409,8 +413,7 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
setup_decoder_defaults(state,
AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
setup_decoder_defaults(state, true);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
@ -432,8 +435,9 @@ static void disable_audio_input(struct au8522_state *state)
}
/* 0=disable, 1=SIF */
static void set_audio_input(struct au8522_state *state, int aud_input)
static void set_audio_input(struct au8522_state *state)
{
int aud_input = state->aud_input;
int i;
/* Note that this function needs to be used in conjunction with setting
@ -465,8 +469,9 @@ static void set_audio_input(struct au8522_state *state, int aud_input)
au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
msleep(150);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
msleep(1);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
msleep(10);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
msleep(50);
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
@ -539,58 +544,109 @@ static int au8522_s_register(struct v4l2_subdev *sd,
}
#endif
static void au8522_video_set(struct au8522_state *state)
{
u8 input_mode;
au8522_writereg(state, 0xa4, 1 << 5);
switch (state->vid_input) {
case AU8522_COMPOSITE_CH1:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH1;
au8522_setup_cvbs_mode(state, input_mode);
break;
case AU8522_COMPOSITE_CH2:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH2;
au8522_setup_cvbs_mode(state, input_mode);
break;
case AU8522_COMPOSITE_CH3:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH3;
au8522_setup_cvbs_mode(state, input_mode);
break;
case AU8522_COMPOSITE_CH4:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH4;
au8522_setup_cvbs_mode(state, input_mode);
break;
case AU8522_SVIDEO_CH13:
input_mode = AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13;
au8522_setup_svideo_mode(state, input_mode);
break;
case AU8522_SVIDEO_CH24:
input_mode = AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24;
au8522_setup_svideo_mode(state, input_mode);
break;
default:
case AU8522_COMPOSITE_CH4_SIF:
input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF;
au8522_setup_cvbs_tuner_mode(state, input_mode);
break;
}
}
static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
{
struct au8522_state *state = to_state(sd);
if (enable) {
/*
* Clear out any state associated with the digital side of the
* chip, so that when it gets powered back up it won't think
* that it is already tuned
*/
state->current_frequency = 0;
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
0x01);
msleep(1);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
msleep(10);
au8522_video_set(state);
set_audio_input(state);
state->operational_mode = AU8522_ANALOG_MODE;
} else {
/* This does not completely power down the device
(it only reduces it from around 140ma to 80ma) */
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
1 << 5);
state->operational_mode = AU8522_SUSPEND_MODE;
}
return 0;
}
static int au8522_reset(struct v4l2_subdev *sd, u32 val)
{
struct au8522_state *state = to_state(sd);
state->operational_mode = AU8522_ANALOG_MODE;
/* Clear out any state associated with the digital side of the
chip, so that when it gets powered back up it won't think
that it is already tuned */
state->current_frequency = 0;
au8522_writereg(state, 0xa4, 1 << 5);
return 0;
}
static int au8522_s_video_routing(struct v4l2_subdev *sd,
u32 input, u32 output, u32 config)
{
struct au8522_state *state = to_state(sd);
au8522_reset(sd, 0);
if (input == AU8522_COMPOSITE_CH1) {
au8522_setup_cvbs_mode(state);
} else if (input == AU8522_SVIDEO_CH13) {
au8522_setup_svideo_mode(state);
} else if (input == AU8522_COMPOSITE_CH4_SIF) {
au8522_setup_cvbs_tuner_mode(state);
} else {
switch(input) {
case AU8522_COMPOSITE_CH1:
case AU8522_SVIDEO_CH13:
case AU8522_COMPOSITE_CH4_SIF:
state->vid_input = input;
break;
default:
printk(KERN_ERR "au8522 mode not currently supported\n");
return -EINVAL;
}
if (state->operational_mode == AU8522_ANALOG_MODE)
au8522_video_set(state);
return 0;
}
static int au8522_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{
struct au8522_state *state = to_state(sd);
if ((std & (V4L2_STD_PAL_M | V4L2_STD_NTSC_M)) == 0)
return -EINVAL;
state->std = std;
if (state->operational_mode == AU8522_ANALOG_MODE)
au8522_video_set(state);
return 0;
}
@ -598,7 +654,12 @@ static int au8522_s_audio_routing(struct v4l2_subdev *sd,
u32 input, u32 output, u32 config)
{
struct au8522_state *state = to_state(sd);
set_audio_input(state, input);
state->aud_input = input;
if (state->operational_mode == AU8522_ANALOG_MODE)
set_audio_input(state);
return 0;
}
@ -629,7 +690,6 @@ static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
static const struct v4l2_subdev_core_ops au8522_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
.reset = au8522_reset,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = au8522_g_register,
.s_register = au8522_s_register,
@ -647,6 +707,7 @@ static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
static const struct v4l2_subdev_video_ops au8522_video_ops = {
.s_routing = au8522_s_video_routing,
.s_stream = au8522_s_stream,
.s_std = au8522_s_std,
};
static const struct v4l2_subdev_ops au8522_ops = {
@ -729,6 +790,7 @@ static int au8522_probe(struct i2c_client *client,
}
state->c = client;
state->std = V4L2_STD_NTSC_M;
state->vid_input = AU8522_COMPOSITE_CH1;
state->aud_input = AU8522_AUDIO_NONE;
state->id = 8522;

View File

@ -37,6 +37,7 @@
#define AU8522_ANALOG_MODE 0
#define AU8522_DIGITAL_MODE 1
#define AU8522_SUSPEND_MODE 2
struct au8522_state {
struct i2c_client *c;
@ -347,6 +348,7 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
/* Format control 2 */
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_AUTODETECT 0x00
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC 0x01
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M 0x02
#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4

View File

@ -52,6 +52,12 @@ struct cxd2820r_config {
*/
u8 ts_mode;
/* TS clock inverted.
* Default: 0
* Values: 0, 1
*/
bool ts_clock_inv;
/* IF AGC polarity.
* Default: 0
* Values: 0, 1

View File

@ -45,6 +45,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
{ 0x1008b, 0x07, 0xff },
{ 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
{ 0x10070, priv->cfg.ts_mode, 0xff },
{ 0x10071, !priv->cfg.ts_clock_inv << 4, 0x10 },
};
dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__,

View File

@ -46,6 +46,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
{ 0x00088, 0x01, 0xff },
{ 0x00070, priv->cfg.ts_mode, 0xff },
{ 0x00071, !priv->cfg.ts_clock_inv << 4, 0x10 },
{ 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
{ 0x000a5, 0x00, 0x01 },
{ 0x00082, 0x20, 0x60 },

View File

@ -47,6 +47,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
{ 0x02083, 0x0a, 0xff },
{ 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
{ 0x02070, priv->cfg.ts_mode, 0xff },
{ 0x02071, !priv->cfg.ts_clock_inv << 6, 0x40 },
{ 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
{ 0x02567, 0x07, 0x0f },
{ 0x02569, 0x03, 0x03 },

View File

@ -2557,10 +2557,19 @@ static int dib0090_set_params(struct dvb_frontend *fe)
do {
ret = dib0090_tune(fe);
if (ret != FE_CALLBACK_TIME_NEVER)
msleep(ret / 10);
else
if (ret == FE_CALLBACK_TIME_NEVER)
break;
/*
* Despite dib0090_tune returns time at a 0.1 ms range,
* the actual sleep time depends on CONFIG_HZ. The worse case
* is when CONFIG_HZ=100. In such case, the minimum granularity
* is 10ms. On some real field tests, the tuner sometimes don't
* lock when this timer is lower than 10ms. So, enforce a 10ms
* granularity and use usleep_range() instead of msleep().
*/
ret = 10 * (ret + 99)/100;
usleep_range(ret * 1000, (ret + 1) * 1000);
} while (state->tune_state != CT_TUNER_STOP);
return 0;

View File

@ -1041,10 +1041,7 @@ static int dib7000m_tune(struct dvb_frontend *demod)
u16 value;
// we are already tuned - just resuming from suspend
if (ch != NULL)
dib7000m_set_channel(state, ch, 0);
else
return -EINVAL;
dib7000m_set_channel(state, ch, 0);
// restart demod
ret |= dib7000m_write_word(state, 898, 0x4000);

View File

@ -11,6 +11,7 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <asm/div64.h>
#include "dvb_math.h"
#include "dvb_frontend.h"
@ -72,6 +73,12 @@ struct dib7000p_state {
struct mutex i2c_buffer_lock;
u8 input_mode_mpeg;
/* for DVBv5 stats */
s64 old_ucb;
unsigned long per_jiffies_stats;
unsigned long ber_jiffies_stats;
unsigned long get_stats_time;
};
enum dib7000p_power_mode {
@ -401,7 +408,7 @@ static int dib7000p_sad_calib(struct dib7000p_state *state)
return 0;
}
int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
static int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
{
struct dib7000p_state *state = demod->demodulator_priv;
if (value > 4095)
@ -409,9 +416,8 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
state->wbd_ref = value;
return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
}
EXPORT_SYMBOL(dib7000p_set_wbd_ref);
int dib7000p_get_agc_values(struct dvb_frontend *fe,
static int dib7000p_get_agc_values(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
{
struct dib7000p_state *state = fe->demodulator_priv;
@ -427,14 +433,12 @@ int dib7000p_get_agc_values(struct dvb_frontend *fe,
return 0;
}
EXPORT_SYMBOL(dib7000p_get_agc_values);
int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
static int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
{
struct dib7000p_state *state = fe->demodulator_priv;
return dib7000p_write_word(state, 108, v);
}
EXPORT_SYMBOL(dib7000p_set_agc1_min);
static void dib7000p_reset_pll(struct dib7000p_state *state)
{
@ -478,7 +482,7 @@ static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
return internal;
}
int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
@ -513,7 +517,6 @@ int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config
}
return -EIO;
}
EXPORT_SYMBOL(dib7000p_update_pll);
static int dib7000p_reset_gpio(struct dib7000p_state *st)
{
@ -546,12 +549,11 @@ static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
return 0;
}
int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
static int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
{
struct dib7000p_state *state = demod->demodulator_priv;
return dib7000p_cfg_gpio(state, num, dir, val);
}
EXPORT_SYMBOL(dib7000p_set_gpio);
static u16 dib7000p_defaults[] = {
// auto search configuration
@ -636,6 +638,8 @@ static u16 dib7000p_defaults[] = {
0,
};
static void dib7000p_reset_stats(struct dvb_frontend *fe);
static int dib7000p_demod_reset(struct dib7000p_state *state)
{
dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
@ -934,7 +938,7 @@ static void dib7000p_update_timf(struct dib7000p_state *state)
}
u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
static u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
{
struct dib7000p_state *state = fe->demodulator_priv;
switch (op) {
@ -950,7 +954,6 @@ u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
dib7000p_set_bandwidth(state, state->current_bandwidth);
return state->timf;
}
EXPORT_SYMBOL(dib7000p_ctrl_timf);
static void dib7000p_set_channel(struct dib7000p_state *state,
struct dtv_frontend_properties *ch, u8 seq)
@ -1360,6 +1363,9 @@ static int dib7000p_tune(struct dvb_frontend *demod)
dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
dib7000p_reset_stats(demod);
return 0;
}
@ -1552,6 +1558,8 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe)
return ret;
}
static int dib7000p_get_stats(struct dvb_frontend *fe, fe_status_t stat);
static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
{
struct dib7000p_state *state = fe->demodulator_priv;
@ -1570,6 +1578,8 @@ static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
if ((lock & 0x0038) == 0x38)
*stat |= FE_HAS_LOCK;
dib7000p_get_stats(fe, *stat);
return 0;
}
@ -1595,7 +1605,7 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength
return 0;
}
static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
static u32 dib7000p_get_snr(struct dvb_frontend *fe)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 val;
@ -1625,10 +1635,351 @@ static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
else
result -= intlog10(2) * 10 * noise_exp - 100;
return result;
}
static int dib7000p_read_snr(struct dvb_frontend *fe, u16 *snr)
{
u32 result;
result = dib7000p_get_snr(fe);
*snr = result / ((1 << 24) / 10);
return 0;
}
static void dib7000p_reset_stats(struct dvb_frontend *demod)
{
struct dib7000p_state *state = demod->demodulator_priv;
struct dtv_frontend_properties *c = &demod->dtv_property_cache;
u32 ucb;
memset(&c->strength, 0, sizeof(c->strength));
memset(&c->cnr, 0, sizeof(c->cnr));
memset(&c->post_bit_error, 0, sizeof(c->post_bit_error));
memset(&c->post_bit_count, 0, sizeof(c->post_bit_count));
memset(&c->block_error, 0, sizeof(c->block_error));
c->strength.len = 1;
c->cnr.len = 1;
c->block_error.len = 1;
c->block_count.len = 1;
c->post_bit_error.len = 1;
c->post_bit_count.len = 1;
c->strength.stat[0].scale = FE_SCALE_DECIBEL;
c->strength.stat[0].uvalue = 0;
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
dib7000p_read_unc_blocks(demod, &ucb);
state->old_ucb = ucb;
state->ber_jiffies_stats = 0;
state->per_jiffies_stats = 0;
}
struct linear_segments {
unsigned x;
signed y;
};
/*
* Table to estimate signal strength in dBm.
* This table should be empirically determinated by measuring the signal
* strength generated by a RF generator directly connected into
* a device.
* This table was determinated by measuring the signal strength generated
* by a DTA-2111 RF generator directly connected into a dib7000p device
* (a Hauppauge Nova-TD stick), using a good quality 3 meters length
* RC6 cable and good RC6 connectors, connected directly to antenna 1.
* As the minimum output power of DTA-2111 is -31dBm, a 16 dBm attenuator
* were used, for the lower power values.
* The real value can actually be on other devices, or even at the
* second antena input, depending on several factors, like if LNA
* is enabled or not, if diversity is enabled, type of connectors, etc.
* Yet, it is better to use this measure in dB than a random non-linear
* percentage value, especially for antenna adjustments.
* On my tests, the precision of the measure using this table is about
* 0.5 dB, with sounds reasonable enough to adjust antennas.
*/
#define DB_OFFSET 131000
static struct linear_segments strength_to_db_table[] = {
{ 63630, DB_OFFSET - 20500},
{ 62273, DB_OFFSET - 21000},
{ 60162, DB_OFFSET - 22000},
{ 58730, DB_OFFSET - 23000},
{ 58294, DB_OFFSET - 24000},
{ 57778, DB_OFFSET - 25000},
{ 57320, DB_OFFSET - 26000},
{ 56779, DB_OFFSET - 27000},
{ 56293, DB_OFFSET - 28000},
{ 55724, DB_OFFSET - 29000},
{ 55145, DB_OFFSET - 30000},
{ 54680, DB_OFFSET - 31000},
{ 54293, DB_OFFSET - 32000},
{ 53813, DB_OFFSET - 33000},
{ 53427, DB_OFFSET - 34000},
{ 52981, DB_OFFSET - 35000},
{ 52636, DB_OFFSET - 36000},
{ 52014, DB_OFFSET - 37000},
{ 51674, DB_OFFSET - 38000},
{ 50692, DB_OFFSET - 39000},
{ 49824, DB_OFFSET - 40000},
{ 49052, DB_OFFSET - 41000},
{ 48436, DB_OFFSET - 42000},
{ 47836, DB_OFFSET - 43000},
{ 47368, DB_OFFSET - 44000},
{ 46468, DB_OFFSET - 45000},
{ 45597, DB_OFFSET - 46000},
{ 44586, DB_OFFSET - 47000},
{ 43667, DB_OFFSET - 48000},
{ 42673, DB_OFFSET - 49000},
{ 41816, DB_OFFSET - 50000},
{ 40876, DB_OFFSET - 51000},
{ 0, 0},
};
static u32 interpolate_value(u32 value, struct linear_segments *segments,
unsigned len)
{
u64 tmp64;
u32 dx;
s32 dy;
int i, ret;
if (value >= segments[0].x)
return segments[0].y;
if (value < segments[len-1].x)
return segments[len-1].y;
for (i = 1; i < len - 1; i++) {
/* If value is identical, no need to interpolate */
if (value == segments[i].x)
return segments[i].y;
if (value > segments[i].x)
break;
}
/* Linear interpolation between the two (x,y) points */
dy = segments[i - 1].y - segments[i].y;
dx = segments[i - 1].x - segments[i].x;
tmp64 = value - segments[i].x;
tmp64 *= dy;
do_div(tmp64, dx);
ret = segments[i].y + tmp64;
return ret;
}
/* FIXME: may require changes - this one was borrowed from dib8000 */
static u32 dib7000p_get_time_us(struct dvb_frontend *demod, int layer)
{
struct dtv_frontend_properties *c = &demod->dtv_property_cache;
u64 time_us, tmp64;
u32 tmp, denom;
int guard, rate_num, rate_denum = 1, bits_per_symbol;
int interleaving = 0, fft_div;
switch (c->guard_interval) {
case GUARD_INTERVAL_1_4:
guard = 4;
break;
case GUARD_INTERVAL_1_8:
guard = 8;
break;
case GUARD_INTERVAL_1_16:
guard = 16;
break;
default:
case GUARD_INTERVAL_1_32:
guard = 32;
break;
}
switch (c->transmission_mode) {
case TRANSMISSION_MODE_2K:
fft_div = 4;
break;
case TRANSMISSION_MODE_4K:
fft_div = 2;
break;
default:
case TRANSMISSION_MODE_8K:
fft_div = 1;
break;
}
switch (c->modulation) {
case DQPSK:
case QPSK:
bits_per_symbol = 2;
break;
case QAM_16:
bits_per_symbol = 4;
break;
default:
case QAM_64:
bits_per_symbol = 6;
break;
}
switch ((c->hierarchy == 0 || 1 == 1) ? c->code_rate_HP : c->code_rate_LP) {
case FEC_1_2:
rate_num = 1;
rate_denum = 2;
break;
case FEC_2_3:
rate_num = 2;
rate_denum = 3;
break;
case FEC_3_4:
rate_num = 3;
rate_denum = 4;
break;
case FEC_5_6:
rate_num = 5;
rate_denum = 6;
break;
default:
case FEC_7_8:
rate_num = 7;
rate_denum = 8;
break;
}
interleaving = interleaving;
denom = bits_per_symbol * rate_num * fft_div * 384;
/* If calculus gets wrong, wait for 1s for the next stats */
if (!denom)
return 0;
/* Estimate the period for the total bit rate */
time_us = rate_denum * (1008 * 1562500L);
tmp64 = time_us;
do_div(tmp64, guard);
time_us = time_us + tmp64;
time_us += denom / 2;
do_div(time_us, denom);
tmp = 1008 * 96 * interleaving;
time_us += tmp + tmp / guard;
return time_us;
}
static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat)
{
struct dib7000p_state *state = demod->demodulator_priv;
struct dtv_frontend_properties *c = &demod->dtv_property_cache;
int i;
int show_per_stats = 0;
u32 time_us = 0, val, snr;
u64 blocks, ucb;
s32 db;
u16 strength;
/* Get Signal strength */
dib7000p_read_signal_strength(demod, &strength);
val = strength;
db = interpolate_value(val,
strength_to_db_table,
ARRAY_SIZE(strength_to_db_table)) - DB_OFFSET;
c->strength.stat[0].svalue = db;
/* UCB/BER/CNR measures require lock */
if (!(stat & FE_HAS_LOCK)) {
c->cnr.len = 1;
c->block_count.len = 1;
c->block_error.len = 1;
c->post_bit_error.len = 1;
c->post_bit_count.len = 1;
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
return 0;
}
/* Check if time for stats was elapsed */
if (time_after(jiffies, state->per_jiffies_stats)) {
state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
/* Get SNR */
snr = dib7000p_get_snr(demod);
if (snr)
snr = (1000L * snr) >> 24;
else
snr = 0;
c->cnr.stat[0].svalue = snr;
c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
/* Get UCB measures */
dib7000p_read_unc_blocks(demod, &val);
ucb = val - state->old_ucb;
if (val < state->old_ucb)
ucb += 0x100000000LL;
c->block_error.stat[0].scale = FE_SCALE_COUNTER;
c->block_error.stat[0].uvalue = ucb;
/* Estimate the number of packets based on bitrate */
if (!time_us)
time_us = dib7000p_get_time_us(demod, -1);
if (time_us) {
blocks = 1250000ULL * 1000000ULL;
do_div(blocks, time_us * 8 * 204);
c->block_count.stat[0].scale = FE_SCALE_COUNTER;
c->block_count.stat[0].uvalue += blocks;
}
show_per_stats = 1;
}
/* Get post-BER measures */
if (time_after(jiffies, state->ber_jiffies_stats)) {
time_us = dib7000p_get_time_us(demod, -1);
state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
dprintk("Next all layers stats available in %u us.", time_us);
dib7000p_read_ber(demod, &val);
c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
c->post_bit_error.stat[0].uvalue += val;
c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
c->post_bit_count.stat[0].uvalue += 100000000;
}
/* Get PER measures */
if (show_per_stats) {
dib7000p_read_unc_blocks(demod, &val);
c->block_error.stat[0].scale = FE_SCALE_COUNTER;
c->block_error.stat[0].uvalue += val;
time_us = dib7000p_get_time_us(demod, i);
if (time_us) {
blocks = 1250000ULL * 1000000ULL;
do_div(blocks, time_us * 8 * 204);
c->block_count.stat[0].scale = FE_SCALE_COUNTER;
c->block_count.stat[0].uvalue += blocks;
}
}
return 0;
}
static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 1000;
@ -1643,7 +1994,7 @@ static void dib7000p_release(struct dvb_frontend *demod)
kfree(st);
}
int dib7000pc_detection(struct i2c_adapter *i2c_adap)
static int dib7000pc_detection(struct i2c_adapter *i2c_adap)
{
u8 *tx, *rx;
struct i2c_msg msg[2] = {
@ -1688,16 +2039,14 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
kfree(tx);
return ret;
}
EXPORT_SYMBOL(dib7000pc_detection);
struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
static struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
{
struct dib7000p_state *st = demod->demodulator_priv;
return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
}
EXPORT_SYMBOL(dib7000p_get_i2c_master);
int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
static int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 val = dib7000p_read_word(state, 235) & 0xffef;
@ -1705,17 +2054,15 @@ int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
dprintk("PID filter enabled %d", onoff);
return dib7000p_write_word(state, 235, val);
}
EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
static int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{
struct dib7000p_state *state = fe->demodulator_priv;
dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
}
EXPORT_SYMBOL(dib7000p_pid_filter);
int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
static int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
{
struct dib7000p_state *dpst;
int k = 0;
@ -1774,7 +2121,6 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
kfree(dpst);
return 0;
}
EXPORT_SYMBOL(dib7000p_i2c_enumeration);
static const s32 lut_1000ln_mant[] = {
6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
@ -2032,12 +2378,11 @@ static struct i2c_algorithm dib7090_tuner_xfer_algo = {
.functionality = dib7000p_i2c_func,
};
struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
static struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
{
struct dib7000p_state *st = fe->demodulator_priv;
return &st->dib7090_tuner_adap;
}
EXPORT_SYMBOL(dib7090_get_i2c_tuner);
static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
{
@ -2329,7 +2674,7 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
return ret;
}
int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
static int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 en_cur_state;
@ -2352,15 +2697,13 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
return 0;
}
EXPORT_SYMBOL(dib7090_tuner_sleep);
int dib7090_get_adc_power(struct dvb_frontend *fe)
static int dib7090_get_adc_power(struct dvb_frontend *fe)
{
return dib7000p_get_adc_power(fe);
}
EXPORT_SYMBOL(dib7090_get_adc_power);
int dib7090_slave_reset(struct dvb_frontend *fe)
static int dib7090_slave_reset(struct dvb_frontend *fe)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 reg;
@ -2371,10 +2714,9 @@ int dib7090_slave_reset(struct dvb_frontend *fe)
dib7000p_write_word(state, 1032, 0xffff);
return 0;
}
EXPORT_SYMBOL(dib7090_slave_reset);
static struct dvb_frontend_ops dib7000p_ops;
struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
{
struct dvb_frontend *demod;
struct dib7000p_state *st;
@ -2423,6 +2765,8 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
dib7000p_demod_reset(st);
dib7000p_reset_stats(demod);
if (st->version == SOC7090) {
dib7090_set_output_mode(demod, st->cfg.output_mode);
dib7090_set_diversity_in(demod, 0);
@ -2434,6 +2778,31 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
kfree(st);
return NULL;
}
void *dib7000p_attach(struct dib7000p_ops *ops)
{
if (!ops)
return NULL;
ops->slave_reset = dib7090_slave_reset;
ops->get_adc_power = dib7090_get_adc_power;
ops->dib7000pc_detection = dib7000pc_detection;
ops->get_i2c_tuner = dib7090_get_i2c_tuner;
ops->tuner_sleep = dib7090_tuner_sleep;
ops->init = dib7000p_init;
ops->set_agc1_min = dib7000p_set_agc1_min;
ops->set_gpio = dib7000p_set_gpio;
ops->i2c_enumeration = dib7000p_i2c_enumeration;
ops->pid_filter = dib7000p_pid_filter;
ops->pid_filter_ctrl = dib7000p_pid_filter_ctrl;
ops->get_i2c_master = dib7000p_get_i2c_master;
ops->update_pll = dib7000p_update_pll;
ops->ctrl_timf = dib7000p_ctrl_timf;
ops->get_agc_values = dib7000p_get_agc_values;
ops->set_wbd_ref = dib7000p_set_wbd_ref;
return ops;
}
EXPORT_SYMBOL(dib7000p_attach);
static struct dvb_frontend_ops dib7000p_ops = {

View File

@ -46,121 +46,34 @@ struct dib7000p_config {
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
#if IS_ENABLED(CONFIG_DVB_DIB7000P)
extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
extern int dib7090_get_adc_power(struct dvb_frontend *fe);
extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
extern int dib7090_slave_reset(struct dvb_frontend *fe);
extern int dib7000p_get_agc_values(struct dvb_frontend *fe,
struct dib7000p_ops {
int (*set_wbd_ref)(struct dvb_frontend *demod, u16 value);
int (*get_agc_values)(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd);
extern int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v);
int (*set_agc1_min)(struct dvb_frontend *fe, u16 v);
int (*update_pll)(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
int (*set_gpio)(struct dvb_frontend *demod, u8 num, u8 dir, u8 val);
u32 (*ctrl_timf)(struct dvb_frontend *fe, u8 op, u32 timf);
int (*dib7000pc_detection)(struct i2c_adapter *i2c_adap);
struct i2c_adapter *(*get_i2c_master)(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating);
int (*pid_filter_ctrl)(struct dvb_frontend *fe, u8 onoff);
int (*pid_filter)(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
int (*i2c_enumeration)(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
struct i2c_adapter *(*get_i2c_tuner)(struct dvb_frontend *fe);
int (*tuner_sleep)(struct dvb_frontend *fe, int onoff);
int (*get_adc_power)(struct dvb_frontend *fe);
int (*slave_reset)(struct dvb_frontend *fe);
struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
};
#if IS_ENABLED(CONFIG_DVB_DIB7000P)
void *dib7000p_attach(struct dib7000p_ops *ops);
#else
static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
static inline void *dib7000p_attach(struct dib7000p_ops *ops)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7090_get_adc_power(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline int dib7090_slave_reset(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_get_agc_values(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -39,134 +39,34 @@ struct dib8000_config {
#define DEFAULT_DIB8000_I2C_ADDRESS 18
#if IS_ENABLED(CONFIG_DVB_DIB8000)
extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
u8 default_addr, u8 first_addr, u8 is_dib8096p);
extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe);
extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff);
extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
uint8_t op, uint32_t timf);
extern int dib8000_update_pll(struct dvb_frontend *fe,
struct dib8000_ops {
int (*set_wbd_ref)(struct dvb_frontend *fe, u16 value);
int (*update_pll)(struct dvb_frontend *fe,
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio);
extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
int (*set_gpio)(struct dvb_frontend *fe, u8 num, u8 dir, u8 val);
void (*pwm_agc_reset)(struct dvb_frontend *fe);
struct i2c_adapter *(*get_i2c_tuner)(struct dvb_frontend *fe);
int (*tuner_sleep)(struct dvb_frontend *fe, int onoff);
s32 (*get_adc_power)(struct dvb_frontend *fe, u8 mode);
int (*get_dc_power)(struct dvb_frontend *fe, u8 IQ);
u32 (*ctrl_timf)(struct dvb_frontend *fe, uint8_t op, uint32_t timf);
enum frontend_tune_state (*get_tune_state)(struct dvb_frontend *fe);
int (*set_tune_state)(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
int (*set_slave_frontend)(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
int (*remove_slave_frontend)(struct dvb_frontend *fe);
struct dvb_frontend *(*get_slave_frontend)(struct dvb_frontend *fe, int slave_index);
int (*i2c_enumeration)(struct i2c_adapter *host, int no_of_demods,
u8 default_addr, u8 first_addr, u8 is_dib8096p);
struct i2c_adapter *(*get_i2c_master)(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating);
int (*pid_filter_ctrl)(struct dvb_frontend *fe, u8 onoff);
int (*pid_filter)(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
};
#if IS_ENABLED(CONFIG_DVB_DIB8000)
void *dib8000_attach(struct dib8000_ops *ops);
#else
static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline int dib8000_i2c_enumeration(struct i2c_adapter *host,
int no_of_demods, u8 default_addr, u8 first_addr,
u8 is_dib8096p)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return CT_SHUTDOWN;
}
static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
}
static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
uint8_t op, uint32_t timf)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return 0;
}
static inline int dib8000_update_pll(struct dvb_frontend *fe,
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
static inline int dib8000_attach(struct dib8000_ops *ops)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;

View File

@ -1040,13 +1040,18 @@ static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 addres
if (address >= 1024 || !state->platform.risc.fw_is_running)
return -EINVAL;
if (len > 18)
return -EINVAL;
/* dprintk( "APB access thru wr fw %d %x", address, attribute); */
mb[0] = (unsigned short)address;
for (i = 0; i < len && i < 20; i += 2)
mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]);
mb[0] = (u16)address;
for (i = 0; i + 1 < len; i += 2)
mb[1 + i / 2] = b[i] << 8 | b[i + 1];
if (len & 1)
mb[1 + len / 2] = b[len - 1] << 8;
dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute);
dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, (3 + len) / 2, attribute);
return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
}

View File

@ -2159,7 +2159,7 @@ int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
return 0;
rw_error:
return -EIO;
return rc;
}
@ -2252,7 +2252,7 @@ static int hi_cfg_command(const struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -2363,7 +2363,7 @@ hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16
/* if ( powerdown_cmd == true ) */
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -2434,7 +2434,7 @@ static int init_hi(const struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -2650,7 +2650,7 @@ static int get_device_capabilities(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -3338,7 +3338,7 @@ ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_o
return 0;
rw_error:
return -EIO;
return rc;
}
/*----------------------------------------------------------------------------*/
@ -3421,7 +3421,7 @@ static int set_mpegtei_handling(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*----------------------------------------------------------------------------*/
@ -3464,7 +3464,7 @@ static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*----------------------------------------------------------------------------*/
@ -3508,7 +3508,7 @@ static int set_mpeg_start_width(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*----------------------------------------------------------------------------*/
@ -3652,7 +3652,7 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -3854,7 +3854,7 @@ ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
return 0;
rw_error:
return -EIO;
return rc;
}
/*---------------------------------------------------------------------------*/
@ -3969,7 +3969,7 @@ static int smart_ant_init(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
@ -4109,7 +4109,7 @@ static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -4178,7 +4178,7 @@ int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 a
return 0;
rw_error:
return -EIO;
return rc;
}
@ -4290,7 +4290,7 @@ static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -4349,7 +4349,7 @@ static int adc_synchronization(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -4734,7 +4734,7 @@ static int init_agc(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -4831,7 +4831,7 @@ set_frequency(struct drx_demod_instance *demod,
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -4879,7 +4879,7 @@ static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
return 0;
rw_error:
return -EIO;
return rc;
}
#endif
@ -5097,7 +5097,7 @@ set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings,
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -5326,7 +5326,7 @@ set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings,
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -5362,7 +5362,7 @@ static int set_iqm_af(struct drx_demod_instance *demod, bool active)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -5470,7 +5470,7 @@ static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -5686,7 +5686,7 @@ static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -6192,7 +6192,7 @@ static int set_vsb(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -6231,7 +6231,7 @@ static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -6276,7 +6276,7 @@ static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -6321,7 +6321,7 @@ static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
return 0;
rw_error:
return -EIO;
return rc;
}
@ -6434,7 +6434,7 @@ static int power_down_qam(struct drx_demod_instance *demod, bool primary)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -6646,7 +6646,7 @@ set_qam_measurement(struct drx_demod_instance *demod,
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -6881,7 +6881,7 @@ static int set_qam16(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -7116,7 +7116,7 @@ static int set_qam32(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -7351,7 +7351,7 @@ static int set_qam64(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -7586,7 +7586,7 @@ static int set_qam128(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -7821,7 +7821,7 @@ static int set_qam256(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -8650,7 +8650,7 @@ set_qam(struct drx_demod_instance *demod,
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -8831,7 +8831,7 @@ static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *c
return 0;
rw_error:
return -EIO;
return rc;
}
@ -8984,7 +8984,7 @@ qam64auto(struct drx_demod_instance *demod,
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -9068,7 +9068,7 @@ qam256auto(struct drx_demod_instance *demod,
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -9273,7 +9273,7 @@ set_qam_channel(struct drx_demod_instance *demod,
/* restore starting value */
if (auto_flag)
channel->constellation = DRX_CONSTELLATION_AUTO;
return -EIO;
return rc;
}
/*============================================================================*/
@ -9344,7 +9344,7 @@ get_qamrs_err_count(struct i2c_device_addr *dev_addr,
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -9425,8 +9425,8 @@ static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
*sig_strength = 0;
return 0;
rw_error:
return -EIO;
rw_error:
return rc;
}
/**
@ -9643,7 +9643,7 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
return -EIO;
return rc;
}
#endif /* #ifndef DRXJ_VSB_ONLY */
@ -9810,7 +9810,7 @@ power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, boo
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -9840,7 +9840,7 @@ static int power_down_aud(struct drx_demod_instance *demod)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -9874,7 +9874,7 @@ static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
return 0;
rw_error:
return -EIO;
return rc;
}
/**
@ -10398,7 +10398,7 @@ static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_par
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -10638,7 +10638,7 @@ ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
return 0;
rw_error:
return -EIO;
return rc;
}
/*=============================================================================
@ -10756,7 +10756,7 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -10844,7 +10844,7 @@ ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_st
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -10941,7 +10941,7 @@ ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
rw_error:
/* Don't know what the standard is now ... try again */
ext_attr->standard = DRX_STANDARD_UNKNOWN;
return -EIO;
return rc;
}
/*============================================================================*/
@ -11222,7 +11222,7 @@ ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -11303,7 +11303,7 @@ ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain
return 0;
rw_error:
return -EIO;
return rc;
}
/*============================================================================*/
@ -11315,6 +11315,7 @@ ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain
static int drx_ctrl_u_code(struct drx_demod_instance *demod,
struct drxu_code_info *mc_info,
enum drxu_code_action action);
static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
/**
* \fn drxj_open()
@ -11527,10 +11528,11 @@ static int drxj_open(struct drx_demod_instance *demod)
ext_attr->aud_data = drxj_default_aud_data_g;
demod->my_common_attr->is_opened = true;
drxj_set_lna_state(demod, false);
return 0;
rw_error:
common_attr->is_opened = false;
return -EIO;
return rc;
}
/*============================================================================*/
@ -11578,7 +11580,7 @@ static int drxj_close(struct drx_demod_instance *demod)
rw_error:
DRX_ATTR_ISOPENED(demod) = false;
return -EIO;
return rc;
}
/*
@ -11890,6 +11892,33 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
return rc;
}
/* caller is expeced to check if lna is supported before enabling */
static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
{
struct drxuio_cfg uio_cfg;
struct drxuio_data uio_data;
int result;
uio_cfg.uio = DRX_UIO1;
uio_cfg.mode = DRX_UIO_MODE_READWRITE;
/* Configure user-I/O #3: enable read/write */
result = ctrl_set_uio_cfg(demod, &uio_cfg);
if (result) {
pr_err("Failed to setup LNA GPIO!\n");
return result;
}
uio_data.uio = DRX_UIO1;
uio_data.value = state;
result = ctrl_uio_write(demod, &uio_data);
if (result != 0) {
pr_err("Failed to %sable LNA!\n",
state ? "en" : "dis");
return result;
}
return 0;
}
/*
* The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
*
@ -12040,7 +12069,6 @@ static int drx39xxj_set_frontend(struct dvb_frontend *fe)
enum drx_standard standard = DRX_STANDARD_8VSB;
struct drx_channel channel;
int result;
struct drxuio_data uio_data;
static const struct drx_channel def_channel = {
/* frequency */ 0,
/* bandwidth */ DRX_BANDWIDTH_6MHZ,
@ -12125,13 +12153,7 @@ static int drx39xxj_set_frontend(struct dvb_frontend *fe)
return -EINVAL;
}
/* Just for giggles, let's shut off the LNA again.... */
uio_data.uio = DRX_UIO1;
uio_data.value = false;
result = ctrl_uio_write(demod, &uio_data);
if (result != 0) {
pr_err("Failed to disable LNA!\n");
return 0;
}
drxj_set_lna_state(demod, false);
/* After set_frontend, except for strength, stats aren't available */
p->strength.stat[0].scale = FE_SCALE_RELATIVE;
@ -12180,21 +12202,28 @@ static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
static int drx39xxj_init(struct dvb_frontend *fe)
{
/* Bring the demod out of sleep */
drx39xxj_set_powerstate(fe, 1);
struct drx39xxj_state *state = fe->demodulator_priv;
struct drx_demod_instance *demod = state->demod;
int rc = 0;
return 0;
if (fe->exit == DVB_FE_DEVICE_RESUME) {
/* so drxj_open() does what it needs to do */
demod->my_common_attr->is_opened = false;
rc = drxj_open(demod);
if (rc != 0)
pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
} else
drx39xxj_set_powerstate(fe, 1);
return rc;
}
static int drx39xxj_set_lna(struct dvb_frontend *fe)
{
int result;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct drx39xxj_state *state = fe->demodulator_priv;
struct drx_demod_instance *demod = state->demod;
struct drxj_data *ext_attr = demod->my_ext_attr;
struct drxuio_cfg uio_cfg;
struct drxuio_data uio_data;
if (c->lna) {
if (!ext_attr->has_lna) {
@ -12204,26 +12233,7 @@ static int drx39xxj_set_lna(struct dvb_frontend *fe)
}
}
/* Turn off the LNA */
uio_cfg.uio = DRX_UIO1;
uio_cfg.mode = DRX_UIO_MODE_READWRITE;
/* Configure user-I/O #3: enable read/write */
result = ctrl_set_uio_cfg(demod, &uio_cfg);
if (result) {
pr_err("Failed to setup LNA GPIO!\n");
return result;
}
uio_data.uio = DRX_UIO1;
uio_data.value = c->lna;
result = ctrl_uio_write(demod, &uio_data);
if (result != 0) {
pr_err("Failed to %sable LNA!\n",
c->lna ? "en" : "dis");
return result;
}
return 0;
return drxj_set_lna_state(demod, c->lna);
}
static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
@ -12238,7 +12248,9 @@ static void drx39xxj_release(struct dvb_frontend *fe)
struct drx39xxj_state *state = fe->demodulator_priv;
struct drx_demod_instance *demod = state->demod;
drxj_close(demod);
/* if device is removed don't access it */
if (fe->exit != DVB_FE_DEVICE_REMOVED)
drxj_close(demod);
kfree(demod->my_ext_attr);
kfree(demod->my_common_attr);
@ -12259,8 +12271,6 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
struct drxj_data *demod_ext_attr = NULL;
struct drx_demod_instance *demod = NULL;
struct dtv_frontend_properties *p;
struct drxuio_cfg uio_cfg;
struct drxuio_data uio_data;
int result;
/* allocate memory for the internal state */
@ -12272,22 +12282,20 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
if (demod == NULL)
goto error;
demod_addr = kmalloc(sizeof(struct i2c_device_addr), GFP_KERNEL);
demod_addr = kmemdup(&drxj_default_addr_g,
sizeof(struct i2c_device_addr), GFP_KERNEL);
if (demod_addr == NULL)
goto error;
memcpy(demod_addr, &drxj_default_addr_g,
sizeof(struct i2c_device_addr));
demod_comm_attr = kmalloc(sizeof(struct drx_common_attr), GFP_KERNEL);
demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,
sizeof(struct drx_common_attr), GFP_KERNEL);
if (demod_comm_attr == NULL)
goto error;
memcpy(demod_comm_attr, &drxj_default_comm_attr_g,
sizeof(struct drx_common_attr));
demod_ext_attr = kmalloc(sizeof(struct drxj_data), GFP_KERNEL);
demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),
GFP_KERNEL);
if (demod_ext_attr == NULL)
goto error;
memcpy(demod_ext_attr, &drxj_data_g, sizeof(struct drxj_data));
/* setup the state */
state->i2c = i2c;
@ -12313,24 +12321,6 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
goto error;
}
/* Turn off the LNA */
uio_cfg.uio = DRX_UIO1;
uio_cfg.mode = DRX_UIO_MODE_READWRITE;
/* Configure user-I/O #3: enable read/write */
result = ctrl_set_uio_cfg(demod, &uio_cfg);
if (result) {
pr_err("Failed to setup LNA GPIO!\n");
goto error;
}
uio_data.uio = DRX_UIO1;
uio_data.value = false;
result = ctrl_uio_write(demod, &uio_data);
if (result != 0) {
pr_err("Failed to disable LNA!\n");
goto error;
}
/* create dvb_frontend */
memcpy(&state->frontend.ops, &drx39xxj_ops,
sizeof(struct dvb_frontend_ops));

View File

@ -69,5 +69,4 @@ struct dvb_frontend *drxd_attach(const struct drxd_config *config,
}
#endif
extern int drxd_config_i2c(struct dvb_frontend *, int);
#endif

View File

@ -2840,7 +2840,7 @@ static int drxd_init(struct dvb_frontend *fe)
return err;
}
int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
static int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
{
struct drxd_state *state = fe->demodulator_priv;
@ -2849,7 +2849,6 @@ int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
return DRX_ConfigureI2CBridge(state, onoff);
}
EXPORT_SYMBOL(drxd_config_i2c);
static int drxd_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *sets)

View File

@ -879,7 +879,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
/* SNR(X) dB = 10 * ln(X) / ln(10) dB */
tmp = DIV_ROUND_CLOSEST(tmp, 8 * M88DS3103_SNR_ITERATIONS);
if (tmp)
*snr = 100ul * intlog2(tmp) / intlog2(10);
*snr = div_u64((u64) 100 * intlog2(tmp), intlog2(10));
else
*snr = 0;
break;
@ -908,7 +908,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
/* SNR(X) dB = 10 * log10(X) dB */
if (signal > noise) {
tmp = signal / noise;
*snr = 100ul * intlog10(tmp) / (1 << 24);
*snr = div_u64((u64) 100 * intlog10(tmp), (1 << 24));
} else {
*snr = 0;
}
@ -926,6 +926,86 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
return ret;
}
static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
unsigned int utmp;
u8 buf[3], u8tmp;
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
switch (c->delivery_system) {
case SYS_DVBS:
ret = m88ds3103_wr_reg(priv, 0xf9, 0x04);
if (ret)
goto err;
ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp);
if (ret)
goto err;
if (!(u8tmp & 0x10)) {
u8tmp |= 0x10;
ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2);
if (ret)
goto err;
priv->ber = (buf[1] << 8) | (buf[0] << 0);
/* restart counters */
ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp);
if (ret)
goto err;
}
break;
case SYS_DVBS2:
ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3);
if (ret)
goto err;
utmp = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);
if (utmp > 3000) {
ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2);
if (ret)
goto err;
priv->ber = (buf[1] << 8) | (buf[0] << 0);
/* restart counters */
ret = m88ds3103_wr_reg(priv, 0xd1, 0x01);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0xf9, 0x01);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0xf9, 0x00);
if (ret)
goto err;
ret = m88ds3103_wr_reg(priv, 0xd1, 0x00);
if (ret)
goto err;
}
break;
default:
dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
__func__);
ret = -EINVAL;
goto err;
}
*ber = priv->ber;
return 0;
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int m88ds3103_set_tone(struct dvb_frontend *fe,
fe_sec_tone_mode_t fe_sec_tone_mode)
@ -1284,6 +1364,7 @@ static struct dvb_frontend_ops m88ds3103_ops = {
.read_status = m88ds3103_read_status,
.read_snr = m88ds3103_read_snr,
.read_ber = m88ds3103_read_ber,
.diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd,
.diseqc_send_burst = m88ds3103_diseqc_send_burst,

View File

@ -22,6 +22,7 @@
#include "dvb_math.h"
#include <linux/firmware.h>
#include <linux/i2c-mux.h>
#include <linux/math64.h>
#define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw"
#define M88DS3103_MCLK_KHZ 96000
@ -34,6 +35,7 @@ struct m88ds3103_priv {
struct dvb_frontend fe;
fe_delivery_system_t delivery_system;
fe_status_t fe_status;
u32 ber;
bool warm; /* FW running */
struct i2c_adapter *i2c_adapter;
};

View File

@ -459,6 +459,9 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
unsigned layer)
{
int rc;
int interleaving[] = {
0, 1, 2, 4, 8
};
static unsigned char reg[] = {
[0] = 0x88, /* Layer A */
@ -475,20 +478,7 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
if (rc < 0)
return rc;
switch ((rc >> 4) & 0x07) {
case 1:
return GUARD_INTERVAL_1_4;
case 2:
return GUARD_INTERVAL_1_8;
case 3:
return GUARD_INTERVAL_1_16;
case 4:
return GUARD_INTERVAL_1_32;
default:
case 0:
return GUARD_INTERVAL_AUTO;
}
return interleaving[(rc >> 4) & 0x07];
}
static int mb86a20s_get_segment_count(struct mb86a20s_state *state,
@ -566,7 +556,7 @@ static u32 isdbt_rate[3][5][4] = {
static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
u32 modulation, u32 forward_error_correction,
u32 interleaving,
u32 guard_interval,
u32 segment)
{
struct mb86a20s_state *state = fe->demodulator_priv;
@ -574,7 +564,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
int mod, fec, guard;
/*
* If modulation/fec/interleaving is not detected, the default is
* If modulation/fec/guard is not detected, the default is
* to consider the lowest bit rate, to avoid taking too long time
* to get BER.
*/
@ -612,7 +602,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
break;
}
switch (interleaving) {
switch (guard_interval) {
default:
case GUARD_INTERVAL_1_4:
guard = 0;
@ -703,7 +693,7 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
c->layer[layer].interleaving = rc;
mb86a20s_layer_bitrate(fe, layer, c->layer[layer].modulation,
c->layer[layer].fec,
c->layer[layer].interleaving,
c->guard_interval,
c->layer[layer].segment_count);
}
@ -721,11 +711,10 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
rc = mb86a20s_readreg(state, 0x07);
if (rc < 0)
return rc;
c->transmission_mode = TRANSMISSION_MODE_AUTO;
if ((rc & 0x60) == 0x20) {
switch (rc & 0x0c >> 2) {
case 0:
c->transmission_mode = TRANSMISSION_MODE_2K;
break;
/* Only modes 2 and 3 are supported */
switch ((rc >> 2) & 0x03) {
case 1:
c->transmission_mode = TRANSMISSION_MODE_4K;
break;
@ -734,7 +723,9 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
break;
}
}
c->guard_interval = GUARD_INTERVAL_AUTO;
if (!(rc & 0x10)) {
/* Guard interval 1/32 is not supported */
switch (rc & 0x3) {
case 0:
c->guard_interval = GUARD_INTERVAL_1_4;

View File

@ -35,6 +35,10 @@
#include <linux/jiffies.h>
#include <linux/math64.h>
static bool rtl2832_sdr_emulated_fmt;
module_param_named(emulated_formats, rtl2832_sdr_emulated_fmt, bool, 0644);
MODULE_PARM_DESC(emulated_formats, "enable emulated formats (disappears in future)");
#define MAX_BULK_BUFS (10)
#define BULK_BUFFER_SIZE (128 * 512)
@ -80,15 +84,18 @@ static const struct v4l2_frequency_band bands_fm[] = {
struct rtl2832_sdr_format {
char *name;
u32 pixelformat;
u32 buffersize;
};
static struct rtl2832_sdr_format formats[] = {
{
.name = "IQ U8",
.pixelformat = V4L2_SDR_FMT_CU8,
.name = "Complex U8",
.pixelformat = V4L2_SDR_FMT_CU8,
.buffersize = BULK_BUFFER_SIZE,
}, {
.name = "IQ U16LE (emulated)",
.name = "Complex U16LE (emulated)",
.pixelformat = V4L2_SDR_FMT_CU16LE,
.buffersize = BULK_BUFFER_SIZE * 2,
},
};
@ -139,6 +146,8 @@ struct rtl2832_sdr_state {
unsigned int f_adc, f_tuner;
u32 pixelformat;
u32 buffersize;
unsigned int num_formats;
/* Controls */
struct v4l2_ctrl_handler hdl;
@ -348,6 +357,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
/* convert u8 to u16 */
unsigned int i;
u16 *u16dst = dst;
for (i = 0; i < src_len; i++)
*u16dst++ = (src[i] << 8) | (src[i] >> 0);
dst_len = 2 * src_len;
@ -359,6 +369,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
#define MSECS 10000UL
unsigned int samples = s->sample - s->sample_measured;
s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
s->sample_measured = s->sample;
dev_dbg(&s->udev->dev,
@ -560,11 +571,13 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
{
unsigned long flags = 0;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
spin_lock_irqsave(&s->queued_bufs_lock, flags);
while (!list_empty(&s->queued_bufs)) {
struct rtl2832_sdr_frame_buf *buf;
buf = list_entry(s->queued_bufs.next,
struct rtl2832_sdr_frame_buf, list);
list_del(&buf->list);
@ -577,6 +590,7 @@ static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
{
struct rtl2832_sdr_state *s = fe->sec_priv;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
mutex_lock(&s->vb_queue_lock);
@ -598,6 +612,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
@ -615,14 +630,14 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
/* Need at least 8 buffers */
if (vq->num_buffers + *nbuffers < 8)
*nbuffers = 8 - vq->num_buffers;
*nplanes = 1;
/* 2 = max 16-bit sample returned */
sizes[0] = PAGE_ALIGN(BULK_BUFFER_SIZE * 2);
sizes[0] = PAGE_ALIGN(s->buffersize);
dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
__func__, *nbuffers, sizes[0]);
return 0;
@ -665,6 +680,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
u8 buf[4], u8tmp1, u8tmp2;
u64 u64tmp;
u32 u32tmp;
dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
if (!test_bit(POWER_ON, &s->flags))
@ -935,7 +951,8 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s)
/*
* bandwidth (Hz)
*/
bandwidth_auto = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
bandwidth_auto = v4l2_ctrl_find(&s->hdl,
V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
if (v4l2_ctrl_g_ctrl(bandwidth_auto)) {
c->bandwidth_hz = s->f_adc;
@ -987,6 +1004,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
int ret;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (!s->udev)
@ -1035,6 +1053,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
mutex_lock(&s->v4l2_lock);
@ -1068,6 +1087,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
__func__, v->index, v->type);
@ -1094,6 +1114,7 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *v)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (v->index > 1)
@ -1105,6 +1126,7 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
struct v4l2_frequency_band *band)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
__func__, band->tuner, band->type, band->index);
@ -1130,6 +1152,7 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
int ret = 0;
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
__func__, f->tuner, f->type);
@ -1193,9 +1216,10 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (f->index >= NUM_FORMATS)
if (f->index >= s->num_formats)
return -EINVAL;
strlcpy(f->description, formats[f->index].name, sizeof(f->description));
@ -1208,9 +1232,12 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
f->fmt.sdr.pixelformat = s->pixelformat;
f->fmt.sdr.buffersize = s->buffersize;
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
return 0;
@ -1222,6 +1249,7 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
struct vb2_queue *q = &s->vb_queue;
int i;
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
@ -1229,15 +1257,19 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
return -EBUSY;
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
for (i = 0; i < NUM_FORMATS; i++) {
for (i = 0; i < s->num_formats; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
s->pixelformat = f->fmt.sdr.pixelformat;
s->pixelformat = formats[i].pixelformat;
s->buffersize = formats[i].buffersize;
f->fmt.sdr.buffersize = formats[i].buffersize;
return 0;
}
}
f->fmt.sdr.pixelformat = formats[0].pixelformat;
s->pixelformat = formats[0].pixelformat;
s->buffersize = formats[0].buffersize;
f->fmt.sdr.pixelformat = formats[0].pixelformat;
f->fmt.sdr.buffersize = formats[0].buffersize;
return 0;
}
@ -1247,16 +1279,20 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
int i;
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
for (i = 0; i < NUM_FORMATS; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
for (i = 0; i < s->num_formats; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
f->fmt.sdr.buffersize = formats[i].buffersize;
return 0;
}
}
f->fmt.sdr.pixelformat = formats[0].pixelformat;
f->fmt.sdr.buffersize = formats[0].buffersize;
return 0;
}
@ -1316,8 +1352,9 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
struct dvb_frontend *fe = s->fe;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
dev_dbg(&s->udev->dev,
"%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
"%s: id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
__func__, ctrl->id, ctrl->name, ctrl->val,
ctrl->minimum, ctrl->maximum, ctrl->step);
@ -1327,14 +1364,16 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
/* TODO: these controls should be moved to tuner drivers */
if (s->bandwidth_auto->val) {
/* Round towards the closest legal value */
s32 val = s->f_adc + s->bandwidth->step / 2;
s32 val = s->f_adc + div_u64(s->bandwidth->step, 2);
u32 offset;
val = clamp(val, s->bandwidth->minimum, s->bandwidth->maximum);
val = clamp_t(s32, val, s->bandwidth->minimum,
s->bandwidth->maximum);
offset = val - s->bandwidth->minimum;
offset = s->bandwidth->step * (offset / s->bandwidth->step);
offset = s->bandwidth->step *
div_u64(offset, s->bandwidth->step);
s->bandwidth->val = s->bandwidth->minimum + offset;
}
c->bandwidth_hz = s->bandwidth->val;
if (!test_bit(POWER_ON, &s->flags))
@ -1390,7 +1429,11 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->cfg = cfg;
s->f_adc = bands_adc[0].rangelow;
s->f_tuner = bands_fm[0].rangelow;
s->pixelformat = V4L2_SDR_FMT_CU8;
s->pixelformat = formats[0].pixelformat;
s->buffersize = formats[0].buffersize;
s->num_formats = NUM_FORMATS;
if (rtl2832_sdr_emulated_fmt == false)
s->num_formats -= 1;
mutex_init(&s->v4l2_lock);
mutex_init(&s->vb_queue_lock);
@ -1420,15 +1463,24 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
break;
case RTL2832_TUNER_R820T:
v4l2_ctrl_handler_init(&s->hdl, 2);
s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 0, 8000000, 100000, 0);
s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops,
V4L2_CID_RF_TUNER_BANDWIDTH_AUTO,
0, 1, 1, 1);
s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops,
V4L2_CID_RF_TUNER_BANDWIDTH,
0, 8000000, 100000, 0);
v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
break;
case RTL2832_TUNER_FC0012:
case RTL2832_TUNER_FC0013:
v4l2_ctrl_handler_init(&s->hdl, 2);
s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 6000000, 8000000, 1000000, 6000000);
s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops,
V4L2_CID_RF_TUNER_BANDWIDTH_AUTO,
0, 1, 1, 1);
s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops,
V4L2_CID_RF_TUNER_BANDWIDTH,
6000000, 8000000, 1000000,
6000000);
v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
break;
default:
@ -1448,7 +1500,6 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->vdev = rtl2832_sdr_template;
s->vdev.queue = &s->vb_queue;
s->vdev.queue->lock = &s->vb_queue_lock;
set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
video_set_drvdata(&s->vdev, s);
/* Register the v4l2_device structure */
@ -1480,6 +1531,9 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
dev_info(&s->i2c->dev, "%s: Realtek RTL2832 SDR attached\n",
KBUILD_MODNAME);
dev_notice(&s->udev->dev,
"%s: SDR API is still slightly experimental and functionality changes may follow\n",
KBUILD_MODNAME);
return fe;
err_unregister_v4l2_dev:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
/*
Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
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.
References:
http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
*/
#ifndef _DVB_SI2165_H
#define _DVB_SI2165_H
#include <linux/dvb/frontend.h>
enum {
SI2165_MODE_OFF = 0x00,
SI2165_MODE_PLL_EXT = 0x20,
SI2165_MODE_PLL_XTAL = 0x21
};
struct si2165_config {
/* i2c addr
* possible values: 0x64,0x65,0x66,0x67 */
u8 i2c_addr;
/* external clock or XTAL */
u8 chip_mode;
/* frequency of external clock or xtal in Hz
* possible values: 4000000, 16000000, 20000000, 240000000, 27000000
*/
u32 ref_freq_Hz;
/* invert the spectrum */
bool inversion;
};
#if IS_ENABLED(CONFIG_DVB_SI2165)
struct dvb_frontend *si2165_attach(
const struct si2165_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *si2165_attach(
const struct si2165_config *config,
struct i2c_adapter *i2c)
{
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_SI2165 */
#endif /* _DVB_SI2165_H */

View File

@ -0,0 +1,23 @@
/*
Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
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.
*/
#ifndef _DVB_SI2165_PRIV
#define _DVB_SI2165_PRIV
#define SI2165_FIRMWARE "dvb-demod-si2165.fw"
#endif /* _DVB_SI2165_PRIV */

View File

@ -95,20 +95,17 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
switch (c->delivery_system) {
case SYS_DVBT:
cmd.args[0] = 0xa0;
cmd.args[1] = 0x01;
memcpy(cmd.args, "\xa0\x01", 2);
cmd.wlen = 2;
cmd.rlen = 13;
break;
case SYS_DVBC_ANNEX_A:
cmd.args[0] = 0x90;
cmd.args[1] = 0x01;
memcpy(cmd.args, "\x90\x01", 2);
cmd.wlen = 2;
cmd.rlen = 9;
break;
case SYS_DVBT2:
cmd.args[0] = 0x50;
cmd.args[1] = 0x01;
memcpy(cmd.args, "\x50\x01", 2);
cmd.wlen = 2;
cmd.rlen = 14;
break;
@ -144,6 +141,15 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
s->fe_status = *status;
if (*status & FE_HAS_LOCK) {
c->cnr.len = 1;
c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
c->cnr.stat[0].svalue = cmd.args[3] * 1000 / 4;
} else {
c->cnr.len = 1;
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
}
dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
__func__, *status, cmd.rlen, cmd.args);
@ -243,51 +249,23 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x04\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x03\x10\x17\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x02\x10\x15\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x0b\x10\x88\x13", 6);
cmd.wlen = 6;
cmd.rlen = 1;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
cmd.wlen = 6;
cmd.rlen = 1;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
@ -295,124 +273,66 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
cmd.args[4] = delivery_system | bandwidth;
cmd.wlen = 6;
cmd.rlen = 1;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x04\x10\x15\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x05\x10\xa1\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
/* set DVB-C symbol rate */
if (c->delivery_system == SYS_DVBC_ANNEX_A) {
memcpy(cmd.args, "\x14\x00\x02\x11", 4);
cmd.args[4] = (c->symbol_rate / 1000) & 0xff;
cmd.args[5] = ((c->symbol_rate / 1000) >> 8) & 0xff;
cmd.wlen = 6;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
}
memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x0d\x10\xd0\x02", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x10\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x04\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x03\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x08\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x07\x03\x01\x02", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x06\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x05\x03\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x40", 6);
cmd.wlen = 6;
cmd.rlen = 1;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
cmd.wlen = 6;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6);
cmd.wlen = 6;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
cmd.wlen = 6;
cmd.rlen = 1;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0x85;
memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x00", 6);
cmd.wlen = 6;
cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x85", 1);
cmd.wlen = 1;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
@ -432,59 +352,61 @@ static int si2168_init(struct dvb_frontend *fe)
struct si2168 *s = fe->demodulator_priv;
int ret, len, remaining;
const struct firmware *fw = NULL;
u8 *fw_file = SI2168_FIRMWARE;
u8 *fw_file;
const unsigned int i2c_wr_max = 8;
struct si2168_cmd cmd;
unsigned int chip_id;
dev_dbg(&s->client->dev, "%s:\n", __func__);
cmd.args[0] = 0x13;
cmd.wlen = 1;
cmd.rlen = 0;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0xc0;
cmd.args[1] = 0x12;
cmd.args[2] = 0x00;
cmd.args[3] = 0x0c;
cmd.args[4] = 0x00;
cmd.args[5] = 0x0d;
cmd.args[6] = 0x16;
cmd.args[7] = 0x00;
cmd.args[8] = 0x00;
cmd.args[9] = 0x00;
cmd.args[10] = 0x00;
cmd.args[11] = 0x00;
cmd.args[12] = 0x00;
memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
cmd.wlen = 13;
cmd.rlen = 0;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0xc0;
cmd.args[1] = 0x06;
cmd.args[2] = 0x01;
cmd.args[3] = 0x0f;
cmd.args[4] = 0x00;
cmd.args[5] = 0x20;
cmd.args[6] = 0x20;
cmd.args[7] = 0x01;
memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
cmd.wlen = 8;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
cmd.args[0] = 0x02;
/* query chip revision */
memcpy(cmd.args, "\x02", 1);
cmd.wlen = 1;
cmd.rlen = 13;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
cmd.args[4] << 0;
#define SI2168_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0)
#define SI2168_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
#define SI2168_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
switch (chip_id) {
case SI2168_A20:
fw_file = SI2168_A20_FIRMWARE;
break;
case SI2168_A30:
fw_file = SI2168_A30_FIRMWARE;
break;
case SI2168_B40:
fw_file = SI2168_B40_FIRMWARE;
break;
default:
dev_err(&s->client->dev,
"%s: unkown chip version Si21%d-%c%c%c\n",
KBUILD_MODNAME, cmd.args[2], cmd.args[1],
cmd.args[3], cmd.args[4]);
ret = -EINVAL;
goto err;
}
/* cold state - try to download firmware */
dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
KBUILD_MODNAME, si2168_ops.info.name);
@ -492,9 +414,22 @@ static int si2168_init(struct dvb_frontend *fe)
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, &s->client->dev);
if (ret) {
dev_err(&s->client->dev, "%s: firmare file '%s' not found\n",
KBUILD_MODNAME, fw_file);
goto err;
/* fallback mechanism to handle old name for Si2168 B40 fw */
if (chip_id == SI2168_B40) {
fw_file = SI2168_B40_FIRMWARE_FALLBACK;
ret = request_firmware(&fw, fw_file, &s->client->dev);
}
if (ret == 0) {
dev_notice(&s->client->dev,
"%s: please install firmware file '%s'\n",
KBUILD_MODNAME, SI2168_B40_FIRMWARE);
} else {
dev_err(&s->client->dev,
"%s: firmware file '%s' not found\n",
KBUILD_MODNAME, fw_file);
goto err;
}
}
dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
@ -520,8 +455,7 @@ static int si2168_init(struct dvb_frontend *fe)
release_firmware(fw);
fw = NULL;
cmd.args[0] = 0x01;
cmd.args[1] = 0x01;
memcpy(cmd.args, "\x01\x01", 2);
cmd.wlen = 2;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
@ -545,12 +479,24 @@ static int si2168_init(struct dvb_frontend *fe)
static int si2168_sleep(struct dvb_frontend *fe)
{
struct si2168 *s = fe->demodulator_priv;
int ret;
struct si2168_cmd cmd;
dev_dbg(&s->client->dev, "%s:\n", __func__);
s->active = false;
memcpy(cmd.args, "\x13", 1);
cmd.wlen = 1;
cmd.rlen = 0;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
return 0;
err:
dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int si2168_get_tune_settings(struct dvb_frontend *fe,
@ -660,7 +606,6 @@ static int si2168_probe(struct i2c_client *client,
struct si2168_config *config = client->dev.platform_data;
struct si2168 *s;
int ret;
struct si2168_cmd cmd;
dev_dbg(&client->dev, "%s:\n", __func__);
@ -674,18 +619,13 @@ static int si2168_probe(struct i2c_client *client,
s->client = client;
mutex_init(&s->i2c_mutex);
/* check if the demod is there */
cmd.wlen = 0;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
/* create mux i2c adapter for tuner */
s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s,
0, 0, 0, si2168_select, si2168_deselect);
if (s->adapter == NULL)
if (s->adapter == NULL) {
ret = -ENODEV;
goto err;
}
/* create dvb_frontend */
memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops));
@ -743,4 +683,6 @@ module_i2c_driver(si2168_driver);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(SI2168_FIRMWARE);
MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
MODULE_FIRMWARE(SI2168_B40_FIRMWARE);

View File

@ -22,7 +22,10 @@
#include <linux/firmware.h>
#include <linux/i2c-mux.h>
#define SI2168_FIRMWARE "dvb-demod-si2168-02.fw"
#define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw"
#define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
#define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw"
#define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
/* state struct */
struct si2168 {
@ -36,9 +39,9 @@ struct si2168 {
};
/* firmare command struct */
#define SI2157_ARGLEN 30
#define SI2168_ARGLEN 30
struct si2168_cmd {
u8 args[SI2157_ARGLEN];
u8 args[SI2168_ARGLEN];
unsigned wlen;
unsigned rlen;
};

View File

@ -21,17 +21,14 @@
static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@ -42,18 +39,16 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
t_state.frequency = frequency;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->set_state) {
if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@ -68,12 +63,9 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
struct tuner_state t_state;
int err = 0;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@ -84,18 +76,16 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
t_state.bandwidth = bandwidth;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->set_state) {
if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}

View File

@ -19,15 +19,11 @@
static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
@ -49,16 +45,13 @@ static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
state.frequency = frequency;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->set_state) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
@ -79,15 +72,11 @@ static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
@ -109,16 +98,13 @@ static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
state.bandwidth = bandwidth;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->set_state) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);

View File

@ -922,18 +922,13 @@ static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
u32 freq = 0;
int err = 0;
dprintk("%s:\n", __func__);
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_frequency) {
err = tuner_ops->get_frequency(fe, &freq);
if (err < 0) {

View File

@ -1030,7 +1030,7 @@ static int ChannelConfiguration(struct tda_state *state,
state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
if ((Standard == HF_FM_Radio) && state->m_bFMInput)
state->m_Regs[EP4] |= 80;
state->m_Regs[EP4] |= 0x80;
state->m_Regs[MPD] &= ~0x80;
if (Standard > HF_AnalogMax)

View File

@ -5,7 +5,7 @@ enum HF_S {
HF_DVBC_8MHZ, HF_DVBC
};
struct SStandardParam m_StandardTable[] = {
static struct SStandardParam m_StandardTable[] = {
{ 0, 0, 0x00, 0x00 }, /* HF_None */
{ 6000000, 7000000, 0x1D, 0x2C }, /* HF_B, */
{ 6900000, 8000000, 0x1E, 0x2C }, /* HF_DK, */
@ -27,7 +27,7 @@ struct SStandardParam m_StandardTable[] = {
{ 0, 0, 0x00, 0x00 }, /* HF_DVBC (Unused) */
};
struct SMap m_BP_Filter_Map[] = {
static struct SMap m_BP_Filter_Map[] = {
{ 62000000, 0x00 },
{ 84000000, 0x01 },
{ 100000000, 0x02 },
@ -799,14 +799,14 @@ static struct SRFBandMap m_RF_Band_Map[7] = {
{ 865000000, 489500000, 697500000, 842000000},
};
u8 m_Thermometer_Map_1[16] = {
static u8 m_Thermometer_Map_1[16] = {
60, 62, 66, 64,
74, 72, 68, 70,
90, 88, 84, 86,
76, 78, 82, 80,
};
u8 m_Thermometer_Map_2[16] = {
static u8 m_Thermometer_Map_2[16] = {
92, 94, 98, 96,
106, 104, 100, 102,
122, 120, 116, 118,

View File

@ -19,17 +19,14 @@
static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@ -41,18 +38,16 @@ static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
struct dvb_frontend_ops *frontend_ops = NULL;
struct dvb_tuner_ops *tuner_ops = NULL;
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
t_state.frequency = frequency;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->set_state) {
if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@ -68,12 +63,9 @@ static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
struct tuner_state t_state;
int err = 0;
if (&fe->ops)
frontend_ops = &fe->ops;
if (&frontend_ops->tuner_ops)
tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}

View File

@ -551,6 +551,7 @@ config VIDEO_MT9V032
tristate "Micron MT9V032 sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on MEDIA_CAMERA_SUPPORT
select REGMAP_I2C
---help---
This is a Video4Linux2 sensor-level driver for the Micron
MT9V032 752x480 CMOS sensor.

View File

@ -663,7 +663,6 @@ static int adv7180_remove(struct i2c_client *client)
if (state->irq > 0)
free_irq(client->irq, state);
v4l2_device_unregister_subdev(sd);
adv7180_exit_controls(state);
mutex_destroy(&state->mutex);
return 0;

View File

@ -2588,8 +2588,11 @@ static const struct adv7604_reg_seq adv7604_recommended_settings_hdmi[] = {
};
static const struct adv7604_reg_seq adv7611_recommended_settings_hdmi[] = {
/* ADV7611 Register Settings Recommendations Rev 1.5, May 2014 */
{ ADV7604_REG(ADV7604_PAGE_CP, 0x6c), 0x00 },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x6f), 0x0c },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x9b), 0x03 },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x6f), 0x08 },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x85), 0x1f },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x87), 0x70 },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x57), 0xda },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x58), 0x01 },

View File

@ -62,8 +62,8 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
/* ----------------------------------------------------------------------- */
static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
int size, int offset)
static int get_key_haup_common(struct IR_i2c *ir, enum rc_type *protocol,
u32 *scancode, u8 *ptoggle, int size, int offset)
{
unsigned char buf[6];
int start, range, toggle, dev, code, ircode;
@ -86,19 +86,10 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
if (!start)
/* no key pressed */
return 0;
/*
* Hauppauge remotes (black/silver) always use
* specific device ids. If we do not filter the
* device ids then messages destined for devices
* such as TVs (id=0) will get through causing
* mis-fired events.
*
* We also filter out invalid key presses which
* produce annoying debug log entries.
*/
ircode= (start << 12) | (toggle << 11) | (dev << 6) | code;
if ((ircode & 0x1fff)==0x1fff)
/* invalid key press */
/* filter out invalid key presses */
ircode = (start << 12) | (toggle << 11) | (dev << 6) | code;
if ((ircode & 0x1fff) == 0x1fff)
return 0;
if (!range)
@ -107,18 +98,20 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
dprintk(1,"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
start, range, toggle, dev, code);
/* return key */
*ir_key = (dev << 8) | code;
*ir_raw = ircode;
*protocol = RC_TYPE_RC5;
*scancode = RC_SCANCODE_RC5(dev, code);
*ptoggle = toggle;
return 1;
}
static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
static int get_key_haup(struct IR_i2c *ir, enum rc_type *protocol,
u32 *scancode, u8 *toggle)
{
return get_key_haup_common (ir, ir_key, ir_raw, 3, 0);
return get_key_haup_common (ir, protocol, scancode, toggle, 3, 0);
}
static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
static int get_key_haup_xvr(struct IR_i2c *ir, enum rc_type *protocol,
u32 *scancode, u8 *toggle)
{
int ret;
unsigned char buf[1] = { 0 };
@ -133,10 +126,11 @@ static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (ret != 1)
return (ret < 0) ? ret : -EINVAL;
return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
return get_key_haup_common(ir, protocol, scancode, toggle, 6, 3);
}
static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
static int get_key_pixelview(struct IR_i2c *ir, enum rc_type *protocol,
u32 *scancode, u8 *toggle)
{
unsigned char b;
@ -145,12 +139,15 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
dprintk(1,"read error\n");
return -EIO;
}
*ir_key = b;
*ir_raw = b;
*protocol = RC_TYPE_OTHER;
*scancode = b;
*toggle = 0;
return 1;
}
static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_type *protocol,
u32 *scancode, u8 *toggle)
{
unsigned char buf[4];
@ -168,13 +165,14 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if(buf[0] != 0x1 || buf[1] != 0xfe)
return 0;
*ir_key = buf[2];
*ir_raw = (buf[2] << 8) | buf[3];
*protocol = RC_TYPE_UNKNOWN;
*scancode = buf[2];
*toggle = 0;
return 1;
}
static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
static int get_key_knc1(struct IR_i2c *ir, enum rc_type *protocol,
u32 *scancode, u8 *toggle)
{
unsigned char b;
@ -197,13 +195,14 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
/* keep old data */
return 1;
*ir_key = b;
*ir_raw = b;
*protocol = RC_TYPE_UNKNOWN;
*scancode = b;
*toggle = 0;
return 1;
}
static int get_key_avermedia_cardbus(struct IR_i2c *ir,
u32 *ir_key, u32 *ir_raw)
static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_type *protocol,
u32 *scancode, u8 *toggle)
{
unsigned char subaddr, key, keygroup;
struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
@ -237,12 +236,11 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
}
key |= (keygroup & 1) << 6;
*ir_key = key;
*ir_raw = key;
if (!strcmp(ir->ir_codes, RC_MAP_AVERMEDIA_M733A_RM_K6)) {
*ir_key |= keygroup << 8;
*ir_raw |= keygroup << 8;
}
*protocol = RC_TYPE_UNKNOWN;
*scancode = key;
if (ir->c->addr == 0x41) /* AVerMedia EM78P153 */
*scancode |= keygroup << 8;
*toggle = 0;
return 1;
}
@ -250,19 +248,22 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
static int ir_key_poll(struct IR_i2c *ir)
{
static u32 ir_key, ir_raw;
enum rc_type protocol;
u32 scancode;
u8 toggle;
int rc;
dprintk(3, "%s\n", __func__);
rc = ir->get_key(ir, &ir_key, &ir_raw);
rc = ir->get_key(ir, &protocol, &scancode, &toggle);
if (rc < 0) {
dprintk(2,"error\n");
return rc;
}
if (rc) {
dprintk(1, "%s: keycode = 0x%04x\n", __func__, ir_key);
rc_keydown(ir->rc, ir_key, 0);
dprintk(1, "%s: proto = 0x%04x, scancode = 0x%08x\n",
__func__, protocol, scancode);
rc_keydown(ir->rc, protocol, scancode, toggle);
}
return 0;
}
@ -327,7 +328,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
case 0x6b:
name = "FusionHDTV";
ir->get_key = get_key_fusionhdtv;
rc_type = RC_BIT_RC5;
rc_type = RC_BIT_UNKNOWN;
ir_codes = RC_MAP_FUSIONHDTV_MCE;
break;
case 0x40:
@ -431,8 +432,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_set_allowed_protocols(rc, rc_type);
rc_set_enabled_protocols(rc, rc_type);
rc->allowed_protocols = rc_type;
rc->enabled_protocols = rc_type;
if (!rc->driver_name)
rc->driver_name = MODULE_NAME;

View File

@ -1,5 +1,5 @@
/*
* Driver for MT9V032 CMOS Image Sensor from Micron
* Driver for MT9V022, MT9V024, MT9V032, and MT9V034 CMOS Image Sensors
*
* Copyright (C) 2010, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*
@ -17,6 +17,7 @@
#include <linux/i2c.h>
#include <linux/log2.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/v4l2-mediabus.h>
@ -87,6 +88,7 @@
#define MT9V032_READ_MODE_COLUMN_FLIP (1 << 5)
#define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6)
#define MT9V032_READ_MODE_DARK_ROWS (1 << 7)
#define MT9V032_READ_MODE_RESERVED 0x0300
#define MT9V032_PIXEL_OPERATION_MODE 0x0f
#define MT9V034_PIXEL_OPERATION_MODE_HDR (1 << 0)
#define MT9V034_PIXEL_OPERATION_MODE_COLOR (1 << 1)
@ -133,8 +135,12 @@
#define MT9V032_THERMAL_INFO 0xc1
enum mt9v032_model {
MT9V032_MODEL_V032_COLOR,
MT9V032_MODEL_V032_MONO,
MT9V032_MODEL_V022_COLOR, /* MT9V022IX7ATC */
MT9V032_MODEL_V022_MONO, /* MT9V022IX7ATM */
MT9V032_MODEL_V024_COLOR, /* MT9V024IA7XTC */
MT9V032_MODEL_V024_MONO, /* MT9V024IA7XTM */
MT9V032_MODEL_V032_COLOR, /* MT9V032C12STM */
MT9V032_MODEL_V032_MONO, /* MT9V032C12STC */
MT9V032_MODEL_V034_COLOR,
MT9V032_MODEL_V034_MONO,
};
@ -160,14 +166,14 @@ struct mt9v032_model_info {
};
static const struct mt9v032_model_version mt9v032_versions[] = {
{ MT9V032_CHIP_ID_REV1, "MT9V032 rev1/2" },
{ MT9V032_CHIP_ID_REV3, "MT9V032 rev3" },
{ MT9V034_CHIP_ID_REV1, "MT9V034 rev1" },
{ MT9V032_CHIP_ID_REV1, "MT9V022/MT9V032 rev1/2" },
{ MT9V032_CHIP_ID_REV3, "MT9V022/MT9V032 rev3" },
{ MT9V034_CHIP_ID_REV1, "MT9V024/MT9V034 rev1" },
};
static const struct mt9v032_model_data mt9v032_model_data[] = {
{
/* MT9V032 revisions 1/2/3 */
/* MT9V022, MT9V032 revisions 1/2/3 */
.min_row_time = 660,
.min_hblank = MT9V032_HORIZONTAL_BLANKING_MIN,
.min_vblank = MT9V032_VERTICAL_BLANKING_MIN,
@ -176,7 +182,7 @@ static const struct mt9v032_model_data mt9v032_model_data[] = {
.max_shutter = MT9V032_TOTAL_SHUTTER_WIDTH_MAX,
.pclk_reg = MT9V032_PIXEL_CLOCK,
}, {
/* MT9V034 */
/* MT9V024, MT9V034 */
.min_row_time = 690,
.min_hblank = MT9V034_HORIZONTAL_BLANKING_MIN,
.min_vblank = MT9V034_VERTICAL_BLANKING_MIN,
@ -188,6 +194,22 @@ static const struct mt9v032_model_data mt9v032_model_data[] = {
};
static const struct mt9v032_model_info mt9v032_models[] = {
[MT9V032_MODEL_V022_COLOR] = {
.data = &mt9v032_model_data[0],
.color = true,
},
[MT9V032_MODEL_V022_MONO] = {
.data = &mt9v032_model_data[0],
.color = false,
},
[MT9V032_MODEL_V024_COLOR] = {
.data = &mt9v032_model_data[1],
.color = true,
},
[MT9V032_MODEL_V024_MONO] = {
.data = &mt9v032_model_data[1],
.color = false,
},
[MT9V032_MODEL_V032_COLOR] = {
.data = &mt9v032_model_data[0],
.color = true,
@ -224,6 +246,7 @@ struct mt9v032 {
struct mutex power_lock;
int power_count;
struct regmap *regmap;
struct clk *clk;
struct mt9v032_platform_data *pdata;
@ -231,7 +254,6 @@ struct mt9v032 {
const struct mt9v032_model_version *version;
u32 sysclk;
u16 chip_control;
u16 aec_agc;
u16 hblank;
struct {
@ -245,40 +267,10 @@ static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
return container_of(sd, struct mt9v032, subdev);
}
static int mt9v032_read(struct i2c_client *client, const u8 reg)
{
s32 data = i2c_smbus_read_word_swapped(client, reg);
dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
data, reg);
return data;
}
static int mt9v032_write(struct i2c_client *client, const u8 reg,
const u16 data)
{
dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
data, reg);
return i2c_smbus_write_word_swapped(client, reg, data);
}
static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
{
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
u16 value = (mt9v032->chip_control & ~clear) | set;
int ret;
ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value);
if (ret < 0)
return ret;
mt9v032->chip_control = value;
return 0;
}
static int
mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
{
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
struct regmap *map = mt9v032->regmap;
u16 value = mt9v032->aec_agc;
int ret;
@ -287,7 +279,7 @@ mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
else
value &= ~which;
ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value);
ret = regmap_write(map, MT9V032_AEC_AGC_ENABLE, value);
if (ret < 0)
return ret;
@ -298,23 +290,23 @@ mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
static int
mt9v032_update_hblank(struct mt9v032 *mt9v032)
{
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
struct v4l2_rect *crop = &mt9v032->crop;
unsigned int min_hblank = mt9v032->model->data->min_hblank;
unsigned int hblank;
if (mt9v032->version->version == MT9V034_CHIP_ID_REV1)
min_hblank += (mt9v032->hratio - 1) * 10;
min_hblank = max_t(unsigned int, (int)mt9v032->model->data->min_row_time - crop->width,
(int)min_hblank);
min_hblank = max_t(int, mt9v032->model->data->min_row_time - crop->width,
min_hblank);
hblank = max_t(unsigned int, mt9v032->hblank, min_hblank);
return mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING, hblank);
return regmap_write(mt9v032->regmap, MT9V032_HORIZONTAL_BLANKING,
hblank);
}
static int mt9v032_power_on(struct mt9v032 *mt9v032)
{
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
struct regmap *map = mt9v032->regmap;
int ret;
ret = clk_set_rate(mt9v032->clk, mt9v032->sysclk);
@ -328,15 +320,15 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
udelay(1);
/* Reset the chip and stop data read out */
ret = mt9v032_write(client, MT9V032_RESET, 1);
ret = regmap_write(map, MT9V032_RESET, 1);
if (ret < 0)
return ret;
ret = mt9v032_write(client, MT9V032_RESET, 0);
ret = regmap_write(map, MT9V032_RESET, 0);
if (ret < 0)
return ret;
return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0);
return regmap_write(map, MT9V032_CHIP_CONTROL, 0);
}
static void mt9v032_power_off(struct mt9v032 *mt9v032)
@ -346,7 +338,7 @@ static void mt9v032_power_off(struct mt9v032 *mt9v032)
static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
{
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
struct regmap *map = mt9v032->regmap;
int ret;
if (!on) {
@ -360,14 +352,14 @@ static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
/* Configure the pixel clock polarity */
if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
ret = mt9v032_write(client, mt9v032->model->data->pclk_reg,
ret = regmap_write(map, mt9v032->model->data->pclk_reg,
MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
if (ret < 0)
return ret;
}
/* Disable the noise correction algorithm and restore the controls. */
ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
ret = regmap_write(map, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
if (ret < 0)
return ret;
@ -411,38 +403,39 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE
| MT9V032_CHIP_CONTROL_DOUT_ENABLE
| MT9V032_CHIP_CONTROL_SEQUENTIAL;
struct i2c_client *client = v4l2_get_subdevdata(subdev);
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
struct v4l2_rect *crop = &mt9v032->crop;
struct regmap *map = mt9v032->regmap;
unsigned int hbin;
unsigned int vbin;
int ret;
if (!enable)
return mt9v032_set_chip_control(mt9v032, mode, 0);
return regmap_update_bits(map, MT9V032_CHIP_CONTROL, mode, 0);
/* Configure the window size and row/column bin */
hbin = fls(mt9v032->hratio) - 1;
vbin = fls(mt9v032->vratio) - 1;
ret = mt9v032_write(client, MT9V032_READ_MODE,
hbin << MT9V032_READ_MODE_COLUMN_BIN_SHIFT |
vbin << MT9V032_READ_MODE_ROW_BIN_SHIFT);
ret = regmap_update_bits(map, MT9V032_READ_MODE,
~MT9V032_READ_MODE_RESERVED,
hbin << MT9V032_READ_MODE_COLUMN_BIN_SHIFT |
vbin << MT9V032_READ_MODE_ROW_BIN_SHIFT);
if (ret < 0)
return ret;
ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left);
ret = regmap_write(map, MT9V032_COLUMN_START, crop->left);
if (ret < 0)
return ret;
ret = mt9v032_write(client, MT9V032_ROW_START, crop->top);
ret = regmap_write(map, MT9V032_ROW_START, crop->top);
if (ret < 0)
return ret;
ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width);
ret = regmap_write(map, MT9V032_WINDOW_WIDTH, crop->width);
if (ret < 0)
return ret;
ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height);
ret = regmap_write(map, MT9V032_WINDOW_HEIGHT, crop->height);
if (ret < 0)
return ret;
@ -451,7 +444,7 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
return ret;
/* Switch to master "normal" mode */
return mt9v032_set_chip_control(mt9v032, 0, mode);
return regmap_update_bits(map, MT9V032_CHIP_CONTROL, mode, mode);
}
static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
@ -633,7 +626,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct mt9v032 *mt9v032 =
container_of(ctrl->handler, struct mt9v032, ctrls);
struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
struct regmap *map = mt9v032->regmap;
u32 freq;
u16 data;
@ -643,23 +636,23 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
ctrl->val);
case V4L2_CID_GAIN:
return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val);
return regmap_write(map, MT9V032_ANALOG_GAIN, ctrl->val);
case V4L2_CID_EXPOSURE_AUTO:
return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
!ctrl->val);
case V4L2_CID_EXPOSURE:
return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
ctrl->val);
return regmap_write(map, MT9V032_TOTAL_SHUTTER_WIDTH,
ctrl->val);
case V4L2_CID_HBLANK:
mt9v032->hblank = ctrl->val;
return mt9v032_update_hblank(mt9v032);
case V4L2_CID_VBLANK:
return mt9v032_write(client, MT9V032_VERTICAL_BLANKING,
ctrl->val);
return regmap_write(map, MT9V032_VERTICAL_BLANKING,
ctrl->val);
case V4L2_CID_PIXEL_RATE:
case V4L2_CID_LINK_FREQ:
@ -667,7 +660,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
break;
freq = mt9v032->pdata->link_freqs[mt9v032->link_freq->val];
mt9v032->pixel_rate->val64 = freq;
*mt9v032->pixel_rate->p_new.p_s64 = freq;
mt9v032->sysclk = freq;
break;
@ -696,7 +689,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
| MT9V032_TEST_PATTERN_FLIP;
break;
}
return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
return regmap_write(map, MT9V032_TEST_PATTERN, data);
}
return 0;
@ -764,7 +757,7 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
struct i2c_client *client = v4l2_get_subdevdata(subdev);
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
unsigned int i;
s32 version;
u32 version;
int ret;
dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
@ -777,10 +770,10 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
}
/* Read and check the sensor version */
version = mt9v032_read(client, MT9V032_CHIP_VERSION);
if (version < 0) {
ret = regmap_read(mt9v032->regmap, MT9V032_CHIP_VERSION, &version);
if (ret < 0) {
dev_err(&client->dev, "Failed reading chip version\n");
return version;
return ret;
}
for (i = 0; i < ARRAY_SIZE(mt9v032_versions); ++i) {
@ -867,6 +860,13 @@ static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
.close = mt9v032_close,
};
static const struct regmap_config mt9v032_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.max_register = 0xff,
.cache_type = REGCACHE_RBTREE,
};
/* -----------------------------------------------------------------------------
* Driver initialization and probing
*/
@ -890,6 +890,10 @@ static int mt9v032_probe(struct i2c_client *client,
if (!mt9v032)
return -ENOMEM;
mt9v032->regmap = devm_regmap_init_i2c(client, &mt9v032_regmap_config);
if (IS_ERR(mt9v032->regmap))
return PTR_ERR(mt9v032->regmap);
mt9v032->clk = devm_clk_get(&client->dev, NULL);
if (IS_ERR(mt9v032->clk))
return PTR_ERR(mt9v032->clk);
@ -931,7 +935,7 @@ static int mt9v032_probe(struct i2c_client *client,
mt9v032->pixel_rate =
v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
if (pdata && pdata->link_freqs) {
unsigned int def = 0;
@ -984,10 +988,19 @@ static int mt9v032_probe(struct i2c_client *client,
mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
if (ret < 0)
v4l2_ctrl_handler_free(&mt9v032->ctrls);
goto err;
mt9v032->subdev.dev = &client->dev;
ret = v4l2_async_register_subdev(&mt9v032->subdev);
if (ret < 0)
goto err;
return 0;
err:
media_entity_cleanup(&mt9v032->subdev.entity);
v4l2_ctrl_handler_free(&mt9v032->ctrls);
return ret;
}
@ -996,6 +1009,7 @@ static int mt9v032_remove(struct i2c_client *client)
struct v4l2_subdev *subdev = i2c_get_clientdata(client);
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
v4l2_async_unregister_subdev(subdev);
v4l2_ctrl_handler_free(&mt9v032->ctrls);
v4l2_device_unregister_subdev(subdev);
media_entity_cleanup(&subdev->entity);
@ -1004,6 +1018,10 @@ static int mt9v032_remove(struct i2c_client *client)
}
static const struct i2c_device_id mt9v032_id[] = {
{ "mt9v022", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V022_COLOR] },
{ "mt9v022m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V022_MONO] },
{ "mt9v024", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V024_COLOR] },
{ "mt9v024m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V024_MONO] },
{ "mt9v032", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_COLOR] },
{ "mt9v032m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_MONO] },
{ "mt9v034", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_COLOR] },

View File

@ -554,6 +554,7 @@ static int noon010_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
nf = noon010_try_fmt(sd, &fmt->format);
noon010_try_frame_size(&fmt->format, &size);
fmt->format.colorspace = V4L2_COLORSPACE_JPEG;
fmt->format.field = V4L2_FIELD_NONE;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
if (fh) {

View File

@ -594,6 +594,7 @@ static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
pf = s5k4ecgx_try_fmt(sd, &fmt->format);
s5k4ecgx_try_frame_size(&fmt->format, &fsize);
fmt->format.colorspace = V4L2_COLORSPACE_JPEG;
fmt->format.field = V4L2_FIELD_NONE;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
if (fh) {

View File

@ -1313,6 +1313,8 @@ static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
const struct s5k5baf_pixfmt *pixfmt;
int ret = 0;
mf->field = V4L2_FIELD_NONE;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(fh, fmt->pad) = *mf;
return 0;

View File

@ -115,6 +115,7 @@ static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf)
fmt = find_sensor_format(mf);
mf->code = fmt->code;
mf->field = V4L2_FIELD_NONE;
v4l_bound_align_image(&mf->width, S5K6A3_SENSOR_MIN_WIDTH,
S5K6A3_SENSOR_MAX_WIDTH, 0,
&mf->height, S5K6A3_SENSOR_MIN_HEIGHT,

View File

@ -297,8 +297,8 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor)
if (rval < 0)
return rval;
sensor->pixel_rate_parray->cur.val64 = pll->vt_pix_clk_freq_hz;
sensor->pixel_rate_csi->cur.val64 = pll->pixel_rate_csi;
*sensor->pixel_rate_parray->p_cur.p_s64 = pll->vt_pix_clk_freq_hz;
*sensor->pixel_rate_csi->p_cur.p_s64 = pll->pixel_rate_csi;
return 0;
}
@ -533,7 +533,7 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor)
sensor->pixel_rate_parray = v4l2_ctrl_new_std(
&sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
if (sensor->pixel_array->ctrl_handler.error) {
dev_err(&client->dev,
@ -562,7 +562,7 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor)
sensor->pixel_rate_csi = v4l2_ctrl_new_std(
&sensor->src->ctrl_handler, &smiapp_ctrl_ops,
V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
if (sensor->src->ctrl_handler.error) {
dev_err(&client->dev,
@ -1554,6 +1554,7 @@ static int __smiapp_get_format(struct v4l2_subdev *subdev,
fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
fmt->format.width = r->width;
fmt->format.height = r->height;
fmt->format.field = V4L2_FIELD_NONE;
}
return 0;
@ -1687,6 +1688,7 @@ static int smiapp_set_format(struct v4l2_subdev *subdev,
fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
fmt->format.width &= ~1;
fmt->format.height &= ~1;
fmt->format.field = V4L2_FIELD_NONE;
fmt->format.width =
clamp(fmt->format.width,
@ -2544,9 +2546,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
}
snprintf(this->sd.name,
sizeof(this->sd.name), "%s %d-%4.4x %s",
sensor->minfo.name, i2c_adapter_id(client->adapter),
client->addr, _this->name);
sizeof(this->sd.name), "%s %s %d-%4.4x",
sensor->minfo.name, _this->name,
i2c_adapter_id(client->adapter), client->addr);
this->sink_fmt.width =
sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
@ -2674,6 +2676,7 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
try_fmt->width = sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
try_fmt->height = sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
try_fmt->code = mbus_code;
try_fmt->field = V4L2_FIELD_NONE;
try_crop->top = 0;
try_crop->left = 0;

View File

@ -403,7 +403,7 @@ static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
if (ctrl->val <= ctrl->default_value) {
/* Pack it into 0..1 step 0.125, register values 0..8 */
unsigned long range = ctrl->default_value - ctrl->minimum;
data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
data = ((ctrl->val - (s32)ctrl->minimum) * 8 + range / 2) / range;
dev_dbg(&client->dev, "Setting gain %d\n", data);
data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
@ -413,7 +413,7 @@ static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
/* Pack it into 1.125..15 variable step, register values 9..67 */
/* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
unsigned long range = ctrl->maximum - ctrl->default_value - 1;
unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
unsigned long gain = ((ctrl->val - (s32)ctrl->default_value - 1) *
111 + range / 2) / range + 9;
if (gain <= 32)
@ -434,7 +434,7 @@ static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
unsigned long range = exp->maximum - exp->minimum;
unsigned long shutter = ((exp->val - exp->minimum) * 1048 +
unsigned long shutter = ((exp->val - (s32)exp->minimum) * 1048 +
range / 2) / range + 1;
dev_dbg(&client->dev,

View File

@ -931,6 +931,12 @@ static int mt9m111_probe(struct i2c_client *client,
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
int ret;
if (client->dev.of_node) {
ssdd = devm_kzalloc(&client->dev, sizeof(*ssdd), GFP_KERNEL);
if (!ssdd)
return -ENOMEM;
client->dev.platform_data = ssdd;
}
if (!ssdd) {
dev_err(&client->dev, "mt9m111: driver needs platform data\n");
return -EINVAL;
@ -1015,6 +1021,11 @@ static int mt9m111_remove(struct i2c_client *client)
return 0;
}
static const struct of_device_id mt9m111_of_match[] = {
{ .compatible = "micron,mt9m111", },
{},
};
MODULE_DEVICE_TABLE(of, mt9m111_of_match);
static const struct i2c_device_id mt9m111_id[] = {
{ "mt9m111", 0 },
@ -1025,6 +1036,7 @@ MODULE_DEVICE_TABLE(i2c, mt9m111_id);
static struct i2c_driver mt9m111_i2c_driver = {
.driver = {
.name = "mt9m111",
.of_match_table = of_match_ptr(mt9m111_of_match),
},
.probe = mt9m111_probe,
.remove = mt9m111_remove,

View File

@ -474,7 +474,7 @@ static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
if (ctrl->val <= ctrl->default_value) {
/* Pack it into 0..1 step 0.125, register values 0..8 */
unsigned long range = ctrl->default_value - ctrl->minimum;
data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
data = ((ctrl->val - (s32)ctrl->minimum) * 8 + range / 2) / range;
dev_dbg(&client->dev, "Setting gain %d\n", data);
data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
@ -485,7 +485,7 @@ static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
/* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
unsigned long range = ctrl->maximum - ctrl->default_value - 1;
/* calculated gain: map 65..127 to 9..1024 step 0.125 */
unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
unsigned long gain = ((ctrl->val - (s32)ctrl->default_value - 1) *
1015 + range / 2) / range + 9;
if (gain <= 32) /* calculated gain 9..32 -> 9..32 */
@ -507,7 +507,7 @@ static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
unsigned int range = exp->maximum - exp->minimum;
unsigned int shutter = ((exp->val - exp->minimum) * 1048 +
unsigned int shutter = ((exp->val - (s32)exp->minimum) * 1048 +
range / 2) / range + 1;
u32 old;

View File

@ -583,7 +583,7 @@ static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
/* mt9v022 has minimum == default */
unsigned long range = gain->maximum - gain->minimum;
/* Valid values 16 to 64, 32 to 64 must be even. */
unsigned long gain_val = ((gain->val - gain->minimum) *
unsigned long gain_val = ((gain->val - (s32)gain->minimum) *
48 + range / 2) / range + 16;
if (gain_val >= 32)
@ -608,7 +608,7 @@ static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
} else {
struct v4l2_ctrl *exp = mt9v022->exposure;
unsigned long range = exp->maximum - exp->minimum;
unsigned long shutter = ((exp->val - exp->minimum) *
unsigned long shutter = ((exp->val - (s32)exp->minimum) *
479 + range / 2) / range + 1;
/*

View File

@ -56,38 +56,29 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
{
struct i2c_client *c = v4l2_get_subdevdata(sd);
unsigned char buffer[1];
int rc;
struct i2c_msg msg[] = {
{ .addr = c->addr, .flags = 0,
.buf = &addr, .len = 1 },
{ .addr = c->addr, .flags = I2C_M_RD,
.buf = buffer, .len = 1 }
};
rc = i2c_transfer(c->adapter, msg, 2);
if (rc < 0 || rc != 2) {
v4l2_err(sd, "i2c i/o error: rc == %d (should be 2)\n", rc);
return rc < 0 ? rc : -EIO;
rc = i2c_smbus_read_byte_data(c, addr);
if (rc < 0) {
v4l2_err(sd, "i2c i/o error: rc == %d\n", rc);
return rc;
}
v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);
v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, rc);
return (buffer[0]);
return rc;
}
static inline void tvp5150_write(struct v4l2_subdev *sd, unsigned char addr,
unsigned char value)
{
struct i2c_client *c = v4l2_get_subdevdata(sd);
unsigned char buffer[2];
int rc;
buffer[0] = addr;
buffer[1] = value;
v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
if (2 != (rc = i2c_master_send(c, buffer, 2)))
v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 2)\n", rc);
v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", addr, value);
rc = i2c_smbus_write_byte_data(c, addr, value);
if (rc < 0)
v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d\n", rc);
}
static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init,
@ -1148,10 +1139,10 @@ static int tvp5150_probe(struct i2c_client *c,
/* Is TVP5150A */
if (tvp5150_id[2] == 3 || tvp5150_id[3] == 0x21) {
v4l2_info(sd, "tvp%02x%02xa detected.\n",
tvp5150_id[2], tvp5150_id[3]);
tvp5150_id[0], tvp5150_id[1]);
} else {
v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
tvp5150_id[2], tvp5150_id[3]);
tvp5150_id[0], tvp5150_id[1]);
v4l2_info(sd, "*** Rom ver is %d.%d\n",
tvp5150_id[2], tvp5150_id[3]);
}

View File

@ -106,8 +106,6 @@ static long media_device_enum_entities(struct media_device *mdev,
if (ent->name) {
strncpy(u_ent.name, ent->name, sizeof(u_ent.name));
u_ent.name[sizeof(u_ent.name) - 1] = '\0';
} else {
memset(u_ent.name, 0, sizeof(u_ent.name));
}
u_ent.type = ent->type;
u_ent.revision = ent->revision;

View File

@ -759,7 +759,6 @@ static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
pix->sizeimage = pix->width * pix->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SRGB;
pix->priv = 0;
return 0;
}
@ -785,7 +784,6 @@ static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format
pix->sizeimage = pix->width * pix->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SRGB;
pix->priv = 0;
return 0;
}
@ -990,7 +988,6 @@ static struct qcam *qcam_init(struct parport *port)
qcam->vdev.fops = &qcam_fops;
qcam->vdev.lock = &qcam->lock;
qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
qcam->vdev.release = video_device_release_empty;
video_set_drvdata(&qcam->vdev, qcam);

View File

@ -761,7 +761,6 @@ static struct qcam *qcam_init(struct parport *port)
qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
qcam->vdev.release = video_device_release_empty;
qcam->vdev.ctrl_handler = &qcam->hdl;
set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
video_set_drvdata(&qcam->vdev, qcam);
mutex_init(&qcam->lock);

View File

@ -1091,7 +1091,6 @@ static int pms_probe(struct device *pdev, unsigned int card)
dev->vdev.release = video_device_release_empty;
dev->vdev.lock = &dev->lock;
dev->vdev.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
video_set_drvdata(&dev->vdev, dev);
dev->std = V4L2_STD_NTSC_M;
dev->height = 240;

View File

@ -883,7 +883,6 @@ static int w9966_init(struct w9966 *cam, struct parport *port)
cam->vdev.ioctl_ops = &w9966_ioctl_ops;
cam->vdev.release = video_device_release_empty;
cam->vdev.ctrl_handler = &cam->hdl;
set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
video_set_drvdata(&cam->vdev, cam);
mutex_init(&cam->lock);

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