mirror of https://gitee.com/openkylin/linux.git
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:
commit
f4d33337ea
|
@ -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"
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 ⪚ 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 (&querymenu, 0, sizeof (querymenu));
|
||||
memset(&querymenu, 0, sizeof(querymenu));
|
||||
querymenu.id = queryctrl.id;
|
||||
|
||||
for (querymenu.index = queryctrl.minimum;
|
||||
querymenu.index <= queryctrl.maximum;
|
||||
querymenu.index++) {
|
||||
if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &querymenu)) {
|
||||
printf (" %s\n", querymenu.name);
|
||||
querymenu.index++) {
|
||||
if (0 == ioctl(fd, &VIDIOC-QUERYMENU;, &querymenu)) {
|
||||
printf(" %s\n", querymenu.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset (&queryctrl, 0, sizeof (queryctrl));
|
||||
memset(&queryctrl, 0, sizeof(queryctrl));
|
||||
|
||||
for (queryctrl.id = V4L2_CID_BASE;
|
||||
queryctrl.id < V4L2_CID_LASTP1;
|
||||
queryctrl.id++) {
|
||||
if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &queryctrl)) {
|
||||
if (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &queryctrl)) {
|
||||
if (queryctrl.flags & 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;, &queryctrl)) {
|
||||
if (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &queryctrl)) {
|
||||
if (queryctrl.flags & 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(&queryctrl, 0, sizeof(queryctrl));
|
||||
|
||||
queryctrl.id = V4L2_CTRL_CLASS_USER | V4L2_CTRL_FLAG_NEXT_CTRL;
|
||||
while (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &queryctrl)) {
|
||||
if (V4L2_CTRL_ID2CLASS(queryctrl.id) != V4L2_CTRL_CLASS_USER)
|
||||
break;
|
||||
if (queryctrl.flags & 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 (&queryctrl, 0, sizeof (queryctrl));
|
||||
memset(&queryctrl, 0, sizeof(queryctrl));
|
||||
queryctrl.id = V4L2_CID_BRIGHTNESS;
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-QUERYCTRL;, &queryctrl)) {
|
||||
if (-1 == ioctl(fd, &VIDIOC-QUERYCTRL;, &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 & V4L2_CTRL_FLAG_DISABLED) {
|
||||
printf ("V4L2_CID_BRIGHTNESS is not supported\n");
|
||||
printf("V4L2_CID_BRIGHTNESS is not supported\n");
|
||||
} else {
|
||||
memset (&control, 0, sizeof (control));
|
||||
memset(&control, 0, sizeof (control));
|
||||
control.id = V4L2_CID_BRIGHTNESS;
|
||||
control.value = queryctrl.default_value;
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &control)) {
|
||||
perror ("VIDIOC_S_CTRL");
|
||||
exit (EXIT_FAILURE);
|
||||
if (-1 == ioctl(fd, &VIDIOC-S-CTRL;, &control)) {
|
||||
perror("VIDIOC_S_CTRL");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
memset (&control, 0, sizeof (control));
|
||||
memset(&control, 0, sizeof(control));
|
||||
control.id = V4L2_CID_CONTRAST;
|
||||
|
||||
if (0 == ioctl (fd, &VIDIOC-G-CTRL;, &control)) {
|
||||
if (0 == ioctl(fd, &VIDIOC-G-CTRL;, &control)) {
|
||||
control.value += 1;
|
||||
|
||||
/* The driver may clamp the value or return ERANGE, ignored here */
|
||||
|
||||
if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &control)
|
||||
if (-1 == ioctl(fd, &VIDIOC-S-CTRL;, &control)
|
||||
&& 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, &control);
|
||||
ioctl(fd, VIDIOC_S_CTRL, &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;, &qctrl)) {
|
||||
if (V4L2_CTRL_ID2CLASS (qctrl.id) != V4L2_CTRL_CLASS_MPEG)
|
||||
while (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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> </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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 × 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 + 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 + 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 + 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 + 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> </entry>
|
||||
<entry spanname="b0">Byte 0 in memory</entry>
|
||||
<entry spanname="b1">Byte 1</entry>
|
||||
<entry spanname="b2">Byte 2</entry>
|
||||
<entry spanname="b3">Byte 3</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry> </entry>
|
||||
<entry> </entry>
|
||||
<entry>Bit</entry>
|
||||
<entry>7</entry>
|
||||
<entry>6</entry>
|
||||
<entry>5</entry>
|
||||
<entry>4</entry>
|
||||
<entry>3</entry>
|
||||
<entry>2</entry>
|
||||
<entry>1</entry>
|
||||
<entry>0</entry>
|
||||
<entry> </entry>
|
||||
<entry>7</entry>
|
||||
<entry>6</entry>
|
||||
<entry>5</entry>
|
||||
<entry>4</entry>
|
||||
<entry>3</entry>
|
||||
<entry>2</entry>
|
||||
<entry>1</entry>
|
||||
<entry>0</entry>
|
||||
<entry> </entry>
|
||||
<entry>7</entry>
|
||||
<entry>6</entry>
|
||||
<entry>5</entry>
|
||||
<entry>4</entry>
|
||||
<entry>3</entry>
|
||||
<entry>2</entry>
|
||||
<entry>1</entry>
|
||||
<entry>0</entry>
|
||||
<entry> </entry>
|
||||
<entry>7</entry>
|
||||
<entry>6</entry>
|
||||
<entry>5</entry>
|
||||
<entry>4</entry>
|
||||
<entry>3</entry>
|
||||
<entry>2</entry>
|
||||
<entry>1</entry>
|
||||
<entry>0</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<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 × 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 + 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 + 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 + 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 + 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>
|
||||
|
|
|
@ -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 + 0:</entry>
|
||||
<entry>I'<subscript>0</subscript></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>start + 1:</entry>
|
||||
<entry>Q'<subscript>0</subscript></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</para>
|
||||
</formalpara>
|
||||
</example>
|
||||
</refsect1>
|
||||
</refentry>
|
|
@ -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 + 0:</entry>
|
||||
<entry>I'<subscript>0[7:0]</subscript></entry>
|
||||
<entry>I'<subscript>0[13:8]</subscript></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>start + 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>
|
|
@ -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 + 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>
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 ≥ <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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -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.
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -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 */
|
||||
};
|
||||
};
|
||||
};
|
|
@ -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
|
|
@ -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";
|
||||
};
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 框架中,并非驱动)可通过测试
|
||||
|
|
52
MAINTAINERS
52
MAINTAINERS
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__,
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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 */
|
|
@ -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 */
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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] },
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue