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:
"This series contain:
- new i2c video drivers: ml86v7667 (video decoder),
ths8200 (video encoder)
- a new video driver for EasyCap cards based on Fushicai USBTV007
- Improved support for OF and embedded systems, with V4L2 async
initialization and a better support for clocks
- API cleanups on the ioctls used by the v4l2 debug tool
- Lots of cleanups
- As usual, several driver improvements and new cards additions
- Revert two changesets that change the minimal symbol rate for
stv0399, as request by Manu
- Update MAINTAINERS and other files to point to my new e-mail"
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (378 commits)
MAINTAINERS & ABI: Update to point to my new email
[media] stb0899: restore minimal rate to 5Mbauds
[media] exynos4-is: Correct colorspace handling at FIMC-LITE
[media] exynos4-is: Set valid initial format on FIMC.n subdevs
[media] exynos4-is: Set valid initial format on FIMC-IS-ISP subdev pads
[media] exynos4-is: Fix format propagation on FIMC-IS-ISP subdev
[media] exynos4-is: Set valid initial format at FIMC-LITE
[media] exynos4-is: Fix format propagation on FIMC-LITE.n subdevs
[media] MAINTAINERS: Update S5P/Exynos FIMC driver entry
[media] Documentation: Update driver's directory in video4linux/fimc.txt
[media] exynos4-is: Change fimc-is firmware file names
[media] exynos4-is: Add support for Exynos5250 MIPI-CSIS
[media] exynos4-is: Add Exynos5250 SoC support to fimc-lite driver
[media] exynos4-is: Drop drvdata handling in fimc-lite for non-dt platforms
[media] media: i2c: tvp514x: remove manual setting of subdev name
[media] media: i2c: tvp7002: remove manual setting of subdev name
[media] mem2mem: set missing v4l2_dev pointer
[media] wl128x: add missing struct v4l2_device
[media] tvp514x: Fix init seqeunce
[media] saa7134: Fix sparse warnings by adding __user annotation
...
diff --git a/Documentation/ABI/testing/sysfs-devices-edac b/Documentation/ABI/testing/sysfs-devices-edac
index 30ee78a..6568e00 100644
--- a/Documentation/ABI/testing/sysfs-devices-edac
+++ b/Documentation/ABI/testing/sysfs-devices-edac
@@ -77,7 +77,7 @@
What: /sys/devices/system/edac/mc/mc*/max_location
Date: April 2012
-Contact: Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
linux-edac@vger.kernel.org
Description: This attribute file displays the information about the last
available memory slot in this memory controller. It is used by
@@ -85,7 +85,7 @@
What: /sys/devices/system/edac/mc/mc*/(dimm|rank)*/size
Date: April 2012
-Contact: Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
linux-edac@vger.kernel.org
Description: This attribute file will display the size of dimm or rank.
For dimm*/size, this is the size, in MB of the DIMM memory
@@ -96,14 +96,14 @@
What: /sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_dev_type
Date: April 2012
-Contact: Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
linux-edac@vger.kernel.org
Description: This attribute file will display what type of DRAM device is
being utilized on this DIMM (x1, x2, x4, x8, ...).
What: /sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_edac_mode
Date: April 2012
-Contact: Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
linux-edac@vger.kernel.org
Description: This attribute file will display what type of Error detection
and correction is being utilized. For example: S4ECD4ED would
@@ -111,7 +111,7 @@
What: /sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_label
Date: April 2012
-Contact: Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
linux-edac@vger.kernel.org
Description: This control file allows this DIMM to have a label assigned
to it. With this label in the module, when errors occur
@@ -126,14 +126,14 @@
What: /sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_location
Date: April 2012
-Contact: Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
linux-edac@vger.kernel.org
Description: This attribute file will display the location (csrow/channel,
branch/channel/slot or channel/slot) of the dimm or rank.
What: /sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_mem_type
Date: April 2012
-Contact: Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact: Mauro Carvalho Chehab <m.chehab@samsung.com>
linux-edac@vger.kernel.org
Description: This attribute file will display what type of memory is
currently on this csrow. Normally, either buffered or
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index f43542a..0c7195e 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2254,7 +2254,7 @@
<orderedlist>
<listitem>
<para>The <constant>VIDIOC_G_CHIP_IDENT</constant> ioctl was renamed
-to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and &VIDIOC-DBG-G-CHIP-IDENT;
+to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and <constant>VIDIOC_DBG_G_CHIP_IDENT</constant>
was introduced in its place. The old struct <structname>v4l2_chip_ident</structname>
was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structname>.</para>
</listitem>
@@ -2513,6 +2513,16 @@
</orderedlist>
</section>
+ <section>
+ <title>V4L2 in Linux 3.11</title>
+ <orderedlist>
+ <listitem>
+ <para>Remove obsolete <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> ioctl.
+ </para>
+ </listitem>
+ </orderedlist>
+ </section>
+
<section id="other">
<title>Relation of V4L2 to other Linux multimedia APIs</title>
@@ -2596,7 +2606,7 @@
ioctls.</para>
</listitem>
<listitem>
- <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
+ <para>&VIDIOC-DBG-G-CHIP-INFO; ioctl.</para>
</listitem>
<listitem>
<para>&VIDIOC-ENUM-DV-TIMINGS;, &VIDIOC-QUERY-DV-TIMINGS; and
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index bfe823d..8469fe1 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -141,6 +141,14 @@
applications. -->
<revision>
+ <revnumber>3.11</revnumber>
+ <date>2013-05-26</date>
+ <authorinitials>hv</authorinitials>
+ <revremark>Remove obsolete VIDIOC_DBG_G_CHIP_IDENT ioctl.
+ </revremark>
+ </revision>
+
+ <revision>
<revnumber>3.10</revnumber>
<date>2013-03-25</date>
<authorinitials>hv</authorinitials>
@@ -493,7 +501,7 @@
</partinfo>
<title>Video for Linux Two API Specification</title>
- <subtitle>Revision 3.10</subtitle>
+ <subtitle>Revision 3.11</subtitle>
<chapter id="common">
&sub-common;
@@ -547,7 +555,6 @@
<!-- All ioctls go here. -->
&sub-create-bufs;
&sub-cropcap;
- &sub-dbg-g-chip-ident;
&sub-dbg-g-chip-info;
&sub-dbg-g-register;
&sub-decoder-cmd;
diff --git a/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml b/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml
deleted file mode 100644
index 921e185..0000000
--- a/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml
+++ /dev/null
@@ -1,271 +0,0 @@
-<refentry id="vidioc-dbg-g-chip-ident">
- <refmeta>
- <refentrytitle>ioctl VIDIOC_DBG_G_CHIP_IDENT</refentrytitle>
- &manvol;
- </refmeta>
-
- <refnamediv>
- <refname>VIDIOC_DBG_G_CHIP_IDENT</refname>
- <refpurpose>Identify the chips on a TV card</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <funcsynopsis>
- <funcprototype>
- <funcdef>int <function>ioctl</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- <paramdef>int <parameter>request</parameter></paramdef>
- <paramdef>struct v4l2_dbg_chip_ident
-*<parameter>argp</parameter></paramdef>
- </funcprototype>
- </funcsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Arguments</title>
-
- <variablelist>
- <varlistentry>
- <term><parameter>fd</parameter></term>
- <listitem>
- <para>&fd;</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><parameter>request</parameter></term>
- <listitem>
- <para>VIDIOC_DBG_G_CHIP_IDENT</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><parameter>argp</parameter></term>
- <listitem>
- <para></para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>Description</title>
-
- <note>
- <title>Experimental</title>
-
- <para>This is an <link
-linkend="experimental">experimental</link> interface and may change in
-the future.</para>
- </note>
-
- <para>For driver debugging purposes this ioctl allows test
-applications to query the driver about the chips present on the TV
-card. Regular applications must not use it. When you found a chip
-specific bug, please contact the linux-media mailing list (&v4l-ml;)
-so it can be fixed.</para>
-
- <para>To query the driver applications must initialize the
-<structfield>match.type</structfield> and
-<structfield>match.addr</structfield> or <structfield>match.name</structfield>
-fields of a &v4l2-dbg-chip-ident;
-and call <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> with a pointer to
-this structure. On success the driver stores information about the
-selected chip in the <structfield>ident</structfield> and
-<structfield>revision</structfield> fields. On failure the structure
-remains unchanged.</para>
-
- <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_HOST</constant>,
-<structfield>match.addr</structfield> selects the nth non-&i2c; chip
-on the TV card. You can enumerate all chips by starting at zero and
-incrementing <structfield>match.addr</structfield> by one until
-<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.
-The number zero always selects the host chip, ⪚ the chip connected
-to the PCI or USB bus.</para>
-
- <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
-<structfield>match.name</structfield> contains the I2C driver name.
-For instance
-<constant>"saa7127"</constant> will match any chip
-supported by the saa7127 driver, regardless of its &i2c; bus address.
-When multiple chips supported by the same driver are present, the
-ioctl will return <constant>V4L2_IDENT_AMBIGUOUS</constant> in the
-<structfield>ident</structfield> field.</para>
-
- <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
-<structfield>match.addr</structfield> selects a chip by its 7 bit
-&i2c; bus address.</para>
-
- <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_AC97</constant>,
-<structfield>match.addr</structfield> selects the nth AC97 chip
-on the TV card. You can enumerate all chips by starting at zero and
-incrementing <structfield>match.addr</structfield> by one until
-<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.</para>
-
- <para>On success, the <structfield>ident</structfield> field will
-contain a chip ID from the Linux
-<filename>media/v4l2-chip-ident.h</filename> header file, and the
-<structfield>revision</structfield> field will contain a driver
-specific value, or zero if no particular revision is associated with
-this chip.</para>
-
- <para>When the driver could not identify the selected chip,
-<structfield>ident</structfield> will contain
-<constant>V4L2_IDENT_UNKNOWN</constant>. When no chip matched
-the ioctl will succeed but the
-<structfield>ident</structfield> field will contain
-<constant>V4L2_IDENT_NONE</constant>. If multiple chips matched,
-<structfield>ident</structfield> will contain
-<constant>V4L2_IDENT_AMBIGUOUS</constant>. In all these cases the
-<structfield>revision</structfield> field remains unchanged.</para>
-
- <para>This ioctl is optional, not all drivers may support it. It
-was introduced in Linux 2.6.21, but the API was changed to the
-one described here in 2.6.29.</para>
-
- <para>We recommended the <application>v4l2-dbg</application>
-utility over calling this ioctl directly. It is available from the
-LinuxTV v4l-dvb repository; see <ulink
-url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
-access instructions.</para>
-
- <!-- Note for convenience vidioc-dbg-g-register.sgml
- contains a duplicate of this table. -->
- <table pgwide="1" frame="none" id="ident-v4l2-dbg-match">
- <title>struct <structname>v4l2_dbg_match</structname></title>
- <tgroup cols="4">
- &cs-ustr;
- <tbody valign="top">
- <row>
- <entry>__u32</entry>
- <entry><structfield>type</structfield></entry>
- <entry>See <xref linkend="ident-chip-match-types" /> for a list of
-possible types.</entry>
- </row>
- <row>
- <entry>union</entry>
- <entry>(anonymous)</entry>
- </row>
- <row>
- <entry></entry>
- <entry>__u32</entry>
- <entry><structfield>addr</structfield></entry>
- <entry>Match a chip by this number, interpreted according
-to the <structfield>type</structfield> field.</entry>
- </row>
- <row>
- <entry></entry>
- <entry>char</entry>
- <entry><structfield>name[32]</structfield></entry>
- <entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table pgwide="1" frame="none" id="v4l2-dbg-chip-ident">
- <title>struct <structname>v4l2_dbg_chip_ident</structname></title>
- <tgroup cols="3">
- &cs-str;
- <tbody valign="top">
- <row>
- <entry>struct v4l2_dbg_match</entry>
- <entry><structfield>match</structfield></entry>
- <entry>How to match the chip, see <xref linkend="ident-v4l2-dbg-match" />.</entry>
- </row>
- <row>
- <entry>__u32</entry>
- <entry><structfield>ident</structfield></entry>
- <entry>A chip identifier as defined in the Linux
-<filename>media/v4l2-chip-ident.h</filename> header file, or one of
-the values from <xref linkend="chip-ids" />.</entry>
- </row>
- <row>
- <entry>__u32</entry>
- <entry><structfield>revision</structfield></entry>
- <entry>A chip revision, chip and driver specific.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <!-- Note for convenience vidioc-dbg-g-register.sgml
- contains a duplicate of this table. -->
- <table pgwide="1" frame="none" id="ident-chip-match-types">
- <title>Chip Match Types</title>
- <tgroup cols="3">
- &cs-def;
- <tbody valign="top">
- <row>
- <entry><constant>V4L2_CHIP_MATCH_BRIDGE</constant></entry>
- <entry>0</entry>
- <entry>Match the nth chip on the card, zero for the
- bridge chip. Does not match sub-devices.</entry>
- </row>
- <row>
- <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
- <entry>1</entry>
- <entry>Match an &i2c; chip by its driver name.</entry>
- </row>
- <row>
- <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
- <entry>2</entry>
- <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
- </row>
- <row>
- <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
- <entry>3</entry>
- <entry>Match the nth anciliary AC97 chip.</entry>
- </row>
- <row>
- <entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
- <entry>4</entry>
- <entry>Match the nth sub-device. Can't be used with this ioctl.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <!-- This is an anonymous enum in media/v4l2-chip-ident.h. -->
- <table pgwide="1" frame="none" id="chip-ids">
- <title>Chip Identifiers</title>
- <tgroup cols="3">
- &cs-def;
- <tbody valign="top">
- <row>
- <entry><constant>V4L2_IDENT_NONE</constant></entry>
- <entry>0</entry>
- <entry>No chip matched.</entry>
- </row>
- <row>
- <entry><constant>V4L2_IDENT_AMBIGUOUS</constant></entry>
- <entry>1</entry>
- <entry>Multiple chips matched.</entry>
- </row>
- <row>
- <entry><constant>V4L2_IDENT_UNKNOWN</constant></entry>
- <entry>2</entry>
- <entry>A chip is present at this address, but the driver
-could not identify it.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </refsect1>
-
- <refsect1>
- &return-value;
-
- <variablelist>
- <varlistentry>
- <term><errorcode>EINVAL</errorcode></term>
- <listitem>
- <para>The <structfield>match_type</structfield> is invalid.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
-</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml b/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml
index e1cece6..4c4603c 100644
--- a/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml
@@ -73,8 +73,7 @@
and call <constant>VIDIOC_DBG_G_CHIP_INFO</constant> with a pointer to
this structure. On success the driver stores information about the
selected chip in the <structfield>name</structfield> and
-<structfield>flags</structfield> fields. On failure the structure
-remains unchanged.</para>
+<structfield>flags</structfield> fields.</para>
<para>When <structfield>match.type</structfield> is
<constant>V4L2_CHIP_MATCH_BRIDGE</constant>,
@@ -132,7 +131,7 @@
<entry>char</entry>
<entry><structfield>name[32]</structfield></entry>
<entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
+to the <structfield>type</structfield> field. Currently unused.</entry>
</row>
</tbody>
</tgroup>
@@ -183,21 +182,6 @@
bridge chip. Does not match sub-devices.</entry>
</row>
<row>
- <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
- <entry>1</entry>
- <entry>Match an &i2c; chip by its driver name. Can't be used with this ioctl.</entry>
- </row>
- <row>
- <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
- <entry>2</entry>
- <entry>Match a chip by its 7 bit &i2c; bus address. Can't be used with this ioctl.</entry>
- </row>
- <row>
- <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
- <entry>3</entry>
- <entry>Match the nth anciliary AC97 chip. Can't be used with this ioctl.</entry>
- </row>
- <row>
<entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
<entry>4</entry>
<entry>Match the nth sub-device.</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml b/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml
index d13bac9..3d038e7 100644
--- a/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml
@@ -76,7 +76,7 @@
to enable these ioctls.</para>
<para>To write a register applications must initialize all fields
-of a &v4l2-dbg-register; and call
+of a &v4l2-dbg-register; except for <structfield>size</structfield> and call
<constant>VIDIOC_DBG_S_REGISTER</constant> with a pointer to this
structure. The <structfield>match.type</structfield> and
<structfield>match.addr</structfield> or <structfield>match.name</structfield>
@@ -91,8 +91,8 @@
<structfield>reg</structfield> fields, and call
<constant>VIDIOC_DBG_G_REGISTER</constant> with a pointer to this
structure. On success the driver stores the register value in the
-<structfield>val</structfield> field. On failure the structure remains
-unchanged.</para>
+<structfield>val</structfield> field and the size (in bytes) of the
+value in <structfield>size</structfield>.</para>
<para>When <structfield>match.type</structfield> is
<constant>V4L2_CHIP_MATCH_BRIDGE</constant>,
@@ -102,39 +102,9 @@
present with the &VIDIOC-DBG-G-CHIP-INFO; ioctl.</para>
<para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
-<structfield>match.name</structfield> contains the I2C driver name.
-For instance
-<constant>"saa7127"</constant> will match any chip
-supported by the saa7127 driver, regardless of its &i2c; bus address.
-When multiple chips supported by the same driver are present, the
-effect of these ioctls is undefined. Again with the
-&VIDIOC-DBG-G-CHIP-INFO; ioctl you can find out which &i2c; chips are
-present.</para>
-
- <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
-<structfield>match.addr</structfield> selects a chip by its 7 bit &i2c;
-bus address.</para>
-
- <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_AC97</constant>,
-<structfield>match.addr</structfield> selects the nth AC97 chip
-on the TV card.</para>
-
- <para>When <structfield>match.type</structfield> is
<constant>V4L2_CHIP_MATCH_SUBDEV</constant>,
<structfield>match.addr</structfield> selects the nth sub-device.</para>
- <note>
- <title>Success not guaranteed</title>
-
- <para>Due to a flaw in the Linux &i2c; bus driver these ioctls may
-return successfully without actually reading or writing a register. To
-catch the most likely failure we recommend a &VIDIOC-DBG-G-CHIP-INFO;
-call confirming the presence of the selected &i2c; chip.</para>
- </note>
-
<para>These ioctls are optional, not all drivers may support them.
However when a driver supports these ioctls it must also support
&VIDIOC-DBG-G-CHIP-INFO;. Conversely it may support
@@ -150,7 +120,7 @@
url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
access instructions.</para>
- <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+ <!-- Note for convenience vidioc-dbg-g-chip-info.sgml
contains a duplicate of this table. -->
<table pgwide="1" frame="none" id="v4l2-dbg-match">
<title>struct <structname>v4l2_dbg_match</structname></title>
@@ -160,7 +130,7 @@
<row>
<entry>__u32</entry>
<entry><structfield>type</structfield></entry>
- <entry>See <xref linkend="ident-chip-match-types" /> for a list of
+ <entry>See <xref linkend="chip-match-types" /> for a list of
possible types.</entry>
</row>
<row>
@@ -179,7 +149,7 @@
<entry>char</entry>
<entry><structfield>name[32]</structfield></entry>
<entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
+to the <structfield>type</structfield> field. Currently unused.</entry>
</row>
</tbody>
</tgroup>
@@ -199,6 +169,11 @@
<entry>How to match the chip, see <xref linkend="v4l2-dbg-match" />.</entry>
</row>
<row>
+ <entry>__u32</entry>
+ <entry><structfield>size</structfield></entry>
+ <entry>The register size in bytes.</entry>
+ </row>
+ <row>
<entry>__u64</entry>
<entry><structfield>reg</structfield></entry>
<entry>A register number.</entry>
@@ -213,7 +188,7 @@
</tgroup>
</table>
- <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+ <!-- Note for convenience vidioc-dbg-g-chip-info.sgml
contains a duplicate of this table. -->
<table pgwide="1" frame="none" id="chip-match-types">
<title>Chip Match Types</title>
@@ -227,21 +202,6 @@
bridge chip. Does not match sub-devices.</entry>
</row>
<row>
- <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
- <entry>1</entry>
- <entry>Match an &i2c; chip by its driver name.</entry>
- </row>
- <row>
- <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
- <entry>2</entry>
- <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
- </row>
- <row>
- <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
- <entry>3</entry>
- <entry>Match the nth anciliary AC97 chip.</entry>
- </row>
- <row>
<entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
<entry>4</entry>
<entry>Match the nth sub-device.</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-querystd.xml b/Documentation/DocBook/media/v4l/vidioc-querystd.xml
index fe80a18..2223485 100644
--- a/Documentation/DocBook/media/v4l/vidioc-querystd.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-querystd.xml
@@ -54,7 +54,8 @@
VIDIOC_QUERYSTD</constant> with a pointer to a &v4l2-std-id; type. The
driver stores here a set of candidates, this can be a single flag or a
set of supported standards if for example the hardware can only
-distinguish between 50 and 60 Hz systems. When detection is not
+distinguish between 50 and 60 Hz systems. If no signal was detected,
+then the driver will return V4L2_STD_UNKNOWN. When detection is not
possible or fails, the set must contain all standards supported by the
current video input or output.</para>
diff --git a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
index de9f6b7..0bf6fb7 100644
--- a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
+++ b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
@@ -2,8 +2,10 @@
Required properties:
-- compatible : should be "samsung,exynos4212-fimc-lite" for Exynos4212 and
- Exynos4412 SoCs;
+- compatible : should be one of:
+ "samsung,exynos4212-fimc-lite" for Exynos4212/4412 SoCs,
+ "samsung,exynos5250-fimc-lite" for Exynos5250 compatible
+ devices;
- reg : physical base address and size of the device memory mapped
registers;
- interrupts : should contain FIMC-LITE interrupt;
diff --git a/Documentation/devicetree/bindings/media/i2c/mt9p031.txt b/Documentation/devicetree/bindings/media/i2c/mt9p031.txt
new file mode 100644
index 0000000..cb60443
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/mt9p031.txt
@@ -0,0 +1,40 @@
+* Aptina 1/2.5-Inch 5Mp CMOS Digital Image Sensor
+
+The Aptina MT9P031 is a 1/2.5-inch CMOS active pixel digital image sensor with
+an active array size of 2592H x 1944V. It is programmable through a simple
+two-wire serial interface.
+
+Required Properties:
+- compatible: value should be either one among the following
+ (a) "aptina,mt9p031" for mt9p031 sensor
+ (b) "aptina,mt9p031m" for mt9p031m sensor
+
+- input-clock-frequency: Input clock frequency.
+
+- pixel-clock-frequency: Pixel clock frequency.
+
+Optional Properties:
+- reset-gpios: Chip reset GPIO
+
+For further reading on port node refer to
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+
+ i2c0@1c22000 {
+ ...
+ ...
+ mt9p031@5d {
+ compatible = "aptina,mt9p031";
+ reg = <0x5d>;
+ reset-gpios = <&gpio3 30 0>;
+
+ port {
+ mt9p031_1: endpoint {
+ input-clock-frequency = <6000000>;
+ pixel-clock-frequency = <96000000>;
+ };
+ };
+ };
+ ...
+ };
diff --git a/Documentation/devicetree/bindings/media/i2c/tvp514x.txt b/Documentation/devicetree/bindings/media/i2c/tvp514x.txt
new file mode 100644
index 0000000..46752cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/tvp514x.txt
@@ -0,0 +1,44 @@
+* Texas Instruments TVP514x video decoder
+
+The TVP5146/TVP5146m2/TVP5147/TVP5147m1 device is high quality, single-chip
+digital video decoder that digitizes and decodes all popular baseband analog
+video formats into digital video component. The tvp514x decoder supports analog-
+to-digital (A/D) conversion of component RGB and YPbPr signals as well as A/D
+conversion and decoding of NTSC, PAL and SECAM composite and S-video into
+component YCbCr.
+
+Required Properties :
+- compatible : value should be either one among the following
+ (a) "ti,tvp5146" for tvp5146 decoder.
+ (b) "ti,tvp5146m2" for tvp5146m2 decoder.
+ (c) "ti,tvp5147" for tvp5147 decoder.
+ (d) "ti,tvp5147m1" for tvp5147m1 decoder.
+
+- hsync-active: HSYNC Polarity configuration for endpoint.
+
+- vsync-active: VSYNC Polarity configuration for endpoint.
+
+- pclk-sample: Clock polarity of the endpoint.
+
+For further reading on port node refer to Documentation/devicetree/bindings/
+media/video-interfaces.txt.
+
+Example:
+
+ i2c0@1c22000 {
+ ...
+ ...
+ tvp514x@5c {
+ compatible = "ti,tvp5146";
+ reg = <0x5c>;
+
+ port {
+ tvp514x_1: endpoint {
+ hsync-active = <1>;
+ vsync-active = <1>;
+ pclk-sample = <0>;
+ };
+ };
+ };
+ ...
+ };
diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt
index 51c776b..96312f6 100644
--- a/Documentation/devicetree/bindings/media/samsung-fimc.txt
+++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt
@@ -127,22 +127,22 @@
};
};
};
- };
- /* MIPI CSI-2 bus IF sensor */
- s5c73m3: sensor@0x1a {
- compatible = "samsung,s5c73m3";
- reg = <0x1a>;
- vddio-supply = <...>;
+ /* MIPI CSI-2 bus IF sensor */
+ s5c73m3: sensor@0x1a {
+ compatible = "samsung,s5c73m3";
+ reg = <0x1a>;
+ vddio-supply = <...>;
- clock-frequency = <24000000>;
- clocks = <...>;
- clock-names = "mclk";
+ clock-frequency = <24000000>;
+ clocks = <...>;
+ clock-names = "mclk";
- port {
- s5c73m3_1: endpoint {
- data-lanes = <1 2 3 4>;
- remote-endpoint = <&csis0_ep>;
+ port {
+ s5c73m3_1: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csis0_ep>;
+ };
};
};
};
diff --git a/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt b/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
index 5f8e28e..be45f0b 100644
--- a/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
+++ b/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
@@ -5,8 +5,8 @@
- compatible : "samsung,s5pv210-csis" for S5PV210 (S5PC110),
"samsung,exynos4210-csis" for Exynos4210 (S5PC210),
- "samsung,exynos4212-csis" for Exynos4212/Exynos4412
- SoC series;
+ "samsung,exynos4212-csis" for Exynos4212/Exynos4412,
+ "samsung,exynos5250-csis" for Exynos5250;
- reg : offset and length of the register set for the device;
- interrupts : should contain MIPI CSIS interrupt; the format of the
interrupt specifier depends on the interrupt controller;
diff --git a/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt b/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt
new file mode 100644
index 0000000..1ce4e46
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt
@@ -0,0 +1,18 @@
+Bindings, specific for the sh_mobile_ceu_camera.c driver:
+ - compatible: Should be "renesas,sh-mobile-ceu"
+ - reg: register base and size
+ - interrupts: the interrupt number
+ - interrupt-parent: the interrupt controller
+ - renesas,max-width: maximum image width, supported on this SoC
+ - renesas,max-height: maximum image height, supported on this SoC
+
+Example:
+
+ceu0: ceu@0xfe910000 {
+ compatible = "renesas,sh-mobile-ceu";
+ reg = <0xfe910000 0xa0>;
+ interrupt-parent = <&intcs>;
+ interrupts = <0x880>;
+ renesas,max-width = <8188>;
+ renesas,max-height = <8188>;
+};
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index eeced24..f552a75 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -265,7 +265,7 @@
media_entity_find_link(struct media_pad *source,
struct media_pad *sink);
- media_entity_remote_source(struct media_pad *pad);
+ media_entity_remote_pad(struct media_pad *pad);
Refer to the kerneldoc documentation for more information.
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 581f666..f144750 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -160,3 +160,6 @@
159 -> ProVideo PV183 [1830:1540,1831:1540,1832:1540,1833:1540,1834:1540,1835:1540,1836:1540,1837:1540]
160 -> Tongwei Video Technology TD-3116 [f200:3116]
161 -> Aposonic W-DVR [0279:0228]
+162 -> Adlink MPG24
+163 -> Bt848 Capture 14MHz
+164 -> CyberVision CV06 (SV)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index b3ad683..8df17d0 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -190,3 +190,4 @@
189 -> Kworld PC150-U [17de:a134]
190 -> Asus My Cinema PS3-100 [1043:48cd]
191 -> Hawell HW-9004V1
+192 -> AverMedia AverTV Satellite Hybrid+FM A706 [1461:2055]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index 5b83a3f..ac88621 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -86,6 +86,6 @@
tuner=86 - Tena TNF5337 MFD
tuner=87 - Xceive 4000 tuner
tuner=88 - Xceive 5000C tuner
-tuner=89 - Sony PAL+SECAM (BTF-PG472Z)
-tuner=90 - Sony NTSC-M-JP (BTF-PK467Z)
-tuner=91 - Sony NTSC-M (BTF-PB463Z)
+tuner=89 - Sony BTF-PG472Z PAL/SECAM
+tuner=90 - Sony BTF-PK467Z NTSC-M-JP
+tuner=91 - Sony BTF-PB463Z NTSC-M
diff --git a/Documentation/video4linux/fimc.txt b/Documentation/video4linux/fimc.txt
index 25f4d34..e51f1b5 100644
--- a/Documentation/video4linux/fimc.txt
+++ b/Documentation/video4linux/fimc.txt
@@ -1,6 +1,6 @@
Samsung S5P/EXYNOS4 FIMC driver
-Copyright (C) 2012 Samsung Electronics Co., Ltd.
+Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
---------------------------------------------------------------------------
The FIMC (Fully Interactive Mobile Camera) device available in Samsung
@@ -10,7 +10,7 @@
path. There are multiple FIMC instances in the SoCs (up to 4), having
slightly different capabilities, like pixel alignment constraints, rotator
availability, LCD writeback support, etc. The driver is located at
-drivers/media/platform/s5p-fimc directory.
+drivers/media/platform/exynos4-is directory.
1. Supported SoCs
=================
@@ -36,21 +36,21 @@
=====================
- media device driver
- drivers/media/platform/s5p-fimc/fimc-mdevice.[ch]
+ drivers/media/platform/exynos4-is/media-dev.[ch]
- camera capture video device driver
- drivers/media/platform/s5p-fimc/fimc-capture.c
+ drivers/media/platform/exynos4-is/fimc-capture.c
- MIPI-CSI2 receiver subdev
- drivers/media/platform/s5p-fimc/mipi-csis.[ch]
+ drivers/media/platform/exynos4-is/mipi-csis.[ch]
- video post-processor (mem-to-mem)
- drivers/media/platform/s5p-fimc/fimc-core.c
+ drivers/media/platform/exynos4-is/fimc-core.c
- common files
- drivers/media/platform/s5p-fimc/fimc-core.h
- drivers/media/platform/s5p-fimc/fimc-reg.h
- drivers/media/platform/s5p-fimc/regs-fimc.h
+ drivers/media/platform/exynos4-is/fimc-core.h
+ drivers/media/platform/exynos4-is/fimc-reg.h
+ drivers/media/platform/exynos4-is/regs-fimc.h
4. User space interfaces
========================
@@ -143,7 +143,8 @@
6. Platform support
===================
-The machine code (plat-s5p and arch/arm/mach-*) must select following options
+The machine code (arch/arm/plat-samsung and arch/arm/mach-*) must select
+following options:
CONFIG_S5P_DEV_FIMC0 mandatory
CONFIG_S5P_DEV_FIMC1 \
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index a300b28..6c4866b 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -246,7 +246,6 @@
It looks like this:
struct v4l2_subdev_core_ops {
- int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
int (*log_status)(struct v4l2_subdev *sd);
int (*init)(struct v4l2_subdev *sd, u32 val);
...
@@ -326,8 +325,27 @@
sink of the link. Subdev drivers are also free to use this function to
perform the checks mentioned above in addition to their own checks.
-A device (bridge) driver needs to register the v4l2_subdev with the
-v4l2_device:
+There are currently two ways to register subdevices with the V4L2 core. The
+first (traditional) possibility is to have subdevices registered by bridge
+drivers. This can be done when the bridge driver has the complete information
+about subdevices connected to it and knows exactly when to register them. This
+is typically the case for internal subdevices, like video data processing units
+within SoCs or complex PCI(e) boards, camera sensors in USB cameras or connected
+to SoCs, which pass information about them to bridge drivers, usually in their
+platform data.
+
+There are however also situations where subdevices have to be registered
+asynchronously to bridge devices. An example of such a configuration is a Device
+Tree based system where information about subdevices is made available to the
+system independently from the bridge devices, e.g. when subdevices are defined
+in DT as I2C device nodes. The API used in this second case is described further
+below.
+
+Using one or the other registration method only affects the probing process, the
+run-time bridge-subdevice interaction is in both cases the same.
+
+In the synchronous case a device (bridge) driver needs to register the
+v4l2_subdev with the v4l2_device:
int err = v4l2_device_register_subdev(v4l2_dev, sd);
@@ -346,24 +364,24 @@
You can call an ops function either directly:
- err = sd->ops->core->g_chip_ident(sd, &chip);
+ err = sd->ops->core->g_std(sd, &norm);
but it is better and easier to use this macro:
- err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+ err = v4l2_subdev_call(sd, core, g_std, &norm);
The macro will to the right NULL pointer checks and returns -ENODEV if subdev
-is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is
-NULL, or the actual result of the subdev->ops->core->g_chip_ident ops.
+is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_std is
+NULL, or the actual result of the subdev->ops->core->g_std ops.
It is also possible to call all or a subset of the sub-devices:
- v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
+ v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
Any subdev that does not support this ops is skipped and error results are
ignored. If you want to check for errors use this:
- err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
+ err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
Any error except -ENOIOCTLCMD will exit the loop with that error. If no
errors (except -ENOIOCTLCMD) occurred, then 0 is returned.
@@ -394,6 +412,30 @@
up the device, but once the subdev is registered it is completely transparent.
+In the asynchronous case subdevice probing can be invoked independently of the
+bridge driver availability. The subdevice driver then has to verify whether all
+the requirements for a successful probing are satisfied. This can include a
+check for a master clock availability. If any of the conditions aren't satisfied
+the driver might decide to return -EPROBE_DEFER to request further reprobing
+attempts. Once all conditions are met the subdevice shall be registered using
+the v4l2_async_register_subdev() function. Unregistration is performed using
+the v4l2_async_unregister_subdev() call. Subdevices registered this way are
+stored in a global list of subdevices, ready to be picked up by bridge drivers.
+
+Bridge drivers in turn have to register a notifier object with an array of
+subdevice descriptors that the bridge device needs for its operation. This is
+performed using the v4l2_async_notifier_register() call. To unregister the
+notifier the driver has to call v4l2_async_notifier_unregister(). The former of
+the two functions takes two arguments: a pointer to struct v4l2_device and a
+pointer to struct v4l2_async_notifier. The latter contains a pointer to an array
+of pointers to subdevice descriptors of type struct v4l2_async_subdev type. The
+V4L2 core will then use these descriptors to match asynchronously registered
+subdevices to them. If a match is detected the .bound() notifier callback is
+called. After all subdevices have been located the .complete() callback is
+called. When a subdevice is removed from the system the .unbind() method is
+called. All three callbacks are optional.
+
+
V4L2 sub-device userspace API
-----------------------------
@@ -575,9 +617,13 @@
The default video_device_release() callback just calls kfree to free the
allocated memory.
+There is also a video_device_release_empty() function that does nothing
+(is empty) and can be used if the struct is embedded and there is nothing
+to do when it is released.
+
You should also set these fields:
-- v4l2_dev: set to the v4l2_device parent device.
+- v4l2_dev: must be set to the v4l2_device parent device.
- name: set to something descriptive and unique.
@@ -614,15 +660,16 @@
If you want to have a separate priority state per (group of) device node(s),
then you can point it to your own struct v4l2_prio_state.
-- parent: you only set this if v4l2_device was registered with NULL as
+- dev_parent: you only set this if v4l2_device was registered with NULL as
the parent device struct. This only happens in cases where one hardware
device has multiple PCI devices that all share the same v4l2_device core.
The cx88 driver is an example of this: one core v4l2_device struct, but
- it is used by both an raw video PCI device (cx8800) and a MPEG PCI device
- (cx8802). Since the v4l2_device cannot be associated with a particular
- PCI device it is setup without a parent device. But when the struct
- video_device is setup you do know which parent PCI device to use.
+ it is used by both a raw video PCI device (cx8800) and a MPEG PCI device
+ (cx8802). Since the v4l2_device cannot be associated with two PCI devices
+ at the same time it is setup without a parent device. But when the struct
+ 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
@@ -1061,3 +1108,29 @@
An example on how the V4L2 events may be used can be found in the OMAP
3 ISP driver (drivers/media/platform/omap3isp).
+
+
+V4L2 clocks
+-----------
+
+Many subdevices, like camera sensors, TV decoders and encoders, need a clock
+signal to be supplied by the system. Often this clock is supplied by the
+respective bridge device. The Linux kernel provides a Common Clock Framework for
+this purpose. However, it is not (yet) available on all architectures. Besides,
+the nature of the multi-functional (clock, data + synchronisation, I2C control)
+connection of subdevices to the system might impose special requirements on the
+clock API usage. E.g. V4L2 has to support clock provider driver unregistration
+while a subdevice driver is holding a reference to the clock. For these reasons
+a V4L2 clock helper API has been developed and is provided to bridge and
+subdevice drivers.
+
+The API consists of two parts: two functions to register and unregister a V4L2
+clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control
+a clock object, similar to the respective generic clock API calls:
+v4l2_clk_get(), v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(),
+v4l2_clk_get_rate(), and v4l2_clk_set_rate(). Clock suppliers have to provide
+clock operations that will be called when clock users invoke respective API
+methods.
+
+It is expected that once the CCF becomes available on all relevant
+architectures this API will be removed.
diff --git a/Documentation/zh_CN/video4linux/v4l2-framework.txt b/Documentation/zh_CN/video4linux/v4l2-framework.txt
index 44c1d93..0da95db 100644
--- a/Documentation/zh_CN/video4linux/v4l2-framework.txt
+++ b/Documentation/zh_CN/video4linux/v4l2-framework.txt
@@ -247,7 +247,6 @@
这些结构体定义如下:
struct v4l2_subdev_core_ops {
- int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
int (*log_status)(struct v4l2_subdev *sd);
int (*init)(struct v4l2_subdev *sd, u32 val);
...
@@ -337,24 +336,24 @@
注册之设备后,可通过以下方式直接调用其操作函数:
- err = sd->ops->core->g_chip_ident(sd, &chip);
+ err = sd->ops->core->g_std(sd, &norm);
但使用如下宏会比较容易且合适:
- err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+ err = v4l2_subdev_call(sd, core, g_std, &norm);
这个宏将会做 NULL 指针检查,如果 subdev 为 NULL,则返回-ENODEV;如果
-subdev->core 或 subdev->core->g_chip_ident 为 NULL,则返回 -ENOIOCTLCMD;
-否则将返回 subdev->ops->core->g_chip_ident ops 调用的实际结果。
+subdev->core 或 subdev->core->g_std 为 NULL,则返回 -ENOIOCTLCMD;
+否则将返回 subdev->ops->core->g_std ops 调用的实际结果。
有时也可能同时调用所有或一系列子设备的某个操作函数:
- v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
+ v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
任何不支持此操作的子设备都会被跳过,并忽略错误返回值。但如果你需要
检查出错码,则可使用如下函数:
- err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
+ err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
除 -ENOIOCTLCMD 外的任何错误都会跳出循环并返回错误值。如果(除 -ENOIOCTLCMD
外)没有错误发生,则返回 0。
diff --git a/MAINTAINERS b/MAINTAINERS
index 9d771d9..b41a9fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1165,15 +1165,6 @@
S: Maintained
F: drivers/media/platform/s5p-g2d/
-ARM/SAMSUNG S5P SERIES FIMC SUPPORT
-M: Kyungmin Park <kyungmin.park@samsung.com>
-M: Sylwester Nawrocki <s.nawrocki@samsung.com>
-L: linux-arm-kernel@lists.infradead.org
-L: linux-media@vger.kernel.org
-S: Maintained
-F: arch/arm/plat-samsung/include/plat/*fimc*
-F: drivers/media/platform/s5p-fimc/
-
ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
M: Kyungmin Park <kyungmin.park@samsung.com>
M: Kamil Debski <k.debski@samsung.com>
@@ -1595,7 +1586,7 @@
F: net/ax25/
AZ6007 DVB DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -1880,7 +1871,7 @@
F: fs/btrfs/
BTTV VIDEO4LINUX DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -2368,7 +2359,7 @@
F: include/media/cx2341x*
CX88 VIDEO4LINUX DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -2990,7 +2981,7 @@
F: drivers/edac/e7xxx_edac.c
EDAC-GHES
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
S: Maintained
@@ -3018,21 +3009,21 @@
F: drivers/edac/i5000_edac.c
EDAC-I5400
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
S: Maintained
F: drivers/edac/i5400_edac.c
EDAC-I7300
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
S: Maintained
F: drivers/edac/i7300_edac.c
EDAC-I7CORE
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
S: Maintained
@@ -3061,7 +3052,7 @@
F: drivers/edac/r82600_edac.c
EDAC-SBRIDGE
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
S: Maintained
@@ -3121,7 +3112,7 @@
F: drivers/net/ethernet/ibm/ehea/
EM28XX VIDEO4LINUX DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -5317,7 +5308,7 @@
F: drivers/media/radio/radio-maxiradio*
MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
P: LinuxTV.org Project
L: linux-media@vger.kernel.org
W: http://linuxtv.org
@@ -7013,7 +7004,7 @@
F: drivers/media/i2c/saa6588*
SAA7134 VIDEO4LINUX DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -7058,6 +7049,15 @@
F: drivers/rtc/rtc-sec.c
F: include/linux/mfd/samsung/
+SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
+M: Kyungmin Park <kyungmin.park@samsung.com>
+M: Sylwester Nawrocki <s.nawrocki@samsung.com>
+L: linux-media@vger.kernel.org
+Q: https://patchwork.linuxtv.org/project/linux-media/list/
+S: Supported
+F: drivers/media/platform/exynos4-is/
+F: include/media/s5p_fimc.h
+
SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER
M: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
L: linux-media@vger.kernel.org
@@ -7375,7 +7375,7 @@
F: drivers/media/radio/radio-si4713.h
SIANO DVB DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -8080,7 +8080,7 @@
F: drivers/media/i2c/tda9840*
TEA5761 TUNER DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -8088,7 +8088,7 @@
F: drivers/media/tuners/tea5761.*
TEA5767 TUNER DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -8327,7 +8327,7 @@
F: mm/shmem.c
TM6000 VIDEO4LINUX DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
@@ -9184,7 +9184,7 @@
F: arch/x86/kernel/cpu/mcheck/*
XC2028/3028 TUNER DRIVER
-M: Mauro Carvalho Chehab <mchehab@redhat.com>
+M: Mauro Carvalho Chehab <m.chehab@samsung.com>
L: linux-media@vger.kernel.org
W: http://linuxtv.org
T: git git://linuxtv.org/media_tree.git
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index fd38c8d..afbc439 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -509,7 +509,6 @@
.ch_1 = 3,
.ch_2 = 3,
.ch_3 = 3,
- .init_enable = 1,
};
static struct amp_config_info vpbe_amp = {
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index 08fe897..6687ba7 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -680,10 +680,7 @@
d = debugfs_create_file(name, S_IRUGO, dma_buf_debugfs_dir,
write, &dma_buf_debug_fops);
- if (IS_ERR(d))
- return PTR_ERR(d);
-
- return 0;
+ return PTR_RET(d);
}
#else
static inline int dma_buf_init_debugfs(void)
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index fe907f2..3077949 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -1,7 +1,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <media/saa7146_vv.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <linux/module.h>
@@ -988,26 +987,6 @@
return err;
}
-static int vidioc_g_chip_ident(struct file *file, void *__fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct saa7146_fh *fh = __fh;
- struct saa7146_dev *dev = fh->dev;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(&chip->match))
- chip->ident = V4L2_IDENT_SAA7146;
- return 0;
- }
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
- return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
- core, g_chip_ident, chip);
-}
-
const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
@@ -1018,7 +997,6 @@
.vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
.vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
.vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
.vidioc_overlay = vidioc_overlay,
.vidioc_g_fbuf = vidioc_g_fbuf,
@@ -1039,7 +1017,6 @@
const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
index 45ac9ee..a142f79 100644
--- a/drivers/media/common/siano/smscoreapi.c
+++ b/drivers/media/common/siano/smscoreapi.c
@@ -1154,7 +1154,7 @@
char *fw_filename = smscore_get_fw_filename(coredev, mode);
if (!fw_filename) {
- sms_info("mode %d not supported on this device", mode);
+ sms_err("mode %d not supported on this device", mode);
return -ENOENT;
}
sms_debug("Firmware name: %s", fw_filename);
@@ -1165,23 +1165,24 @@
rc = request_firmware(&fw, fw_filename, coredev->device);
if (rc < 0) {
- sms_info("failed to open \"%s\"", fw_filename);
+ sms_err("failed to open firmware file \"%s\"", fw_filename);
return rc;
}
sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size);
fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
GFP_KERNEL | GFP_DMA);
if (!fw_buf) {
- sms_info("failed to allocate firmware buffer");
- return -ENOMEM;
- }
- memcpy(fw_buf, fw->data, fw->size);
- fw_buf_size = fw->size;
+ sms_err("failed to allocate firmware buffer");
+ rc = -ENOMEM;
+ } else {
+ memcpy(fw_buf, fw->data, fw->size);
+ fw_buf_size = fw->size;
- rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
- smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
- : loadfirmware_handler(coredev->context, fw_buf,
- fw_buf_size);
+ rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
+ smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
+ : loadfirmware_handler(coredev->context, fw_buf,
+ fw_buf_size);
+ }
kfree(fw_buf);
release_firmware(fw);
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
index 297f1b2..0862622 100644
--- a/drivers/media/common/siano/smsdvb-main.c
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -140,6 +140,7 @@
case DEVICE_MODE_ISDBT:
case DEVICE_MODE_ISDBT_BDA:
n_layers = 4;
+ break;
default:
n_layers = 1;
}
diff --git a/drivers/media/common/tveeprom.c b/drivers/media/common/tveeprom.c
index cc1e172..c7dace6 100644
--- a/drivers/media/common/tveeprom.c
+++ b/drivers/media/common/tveeprom.c
@@ -40,7 +40,6 @@
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
MODULE_AUTHOR("John Klar");
@@ -67,13 +66,10 @@
* The Hauppauge eeprom uses an 8bit field to determine which
* tuner formats the tuner supports.
*/
-static struct HAUPPAUGE_TUNER_FMT
-{
+static const struct {
int id;
- char *name;
-}
-hauppauge_tuner_fmt[] =
-{
+ const char * const name;
+} hauppauge_tuner_fmt[] = {
{ V4L2_STD_UNKNOWN, " UNKNOWN" },
{ V4L2_STD_UNKNOWN, " FM" },
{ V4L2_STD_B|V4L2_STD_GH, " PAL(B/G)" },
@@ -88,13 +84,10 @@
supplying this information. Note that many tuners where only used for
testing and never made it to the outside world. So you will only see
a subset in actual produced cards. */
-static struct HAUPPAUGE_TUNER
-{
+static const struct {
int id;
- char *name;
-}
-hauppauge_tuner[] =
-{
+ const char * const name;
+} hauppauge_tuner[] = {
/* 0-9 */
{ TUNER_ABSENT, "None" },
{ TUNER_ABSENT, "External" },
@@ -298,69 +291,66 @@
{ TUNER_ABSENT, "NXP 18272S"},
};
-/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
+/* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are
* internal to a video chip, i.e. not a separate audio chip. */
-static struct HAUPPAUGE_AUDIOIC
-{
+static const struct {
u32 id;
- char *name;
-}
-audioIC[] =
-{
+ const char * const name;
+} audio_ic[] = {
/* 0-4 */
- { V4L2_IDENT_NONE, "None" },
- { V4L2_IDENT_UNKNOWN, "TEA6300" },
- { V4L2_IDENT_UNKNOWN, "TEA6320" },
- { V4L2_IDENT_UNKNOWN, "TDA9850" },
- { V4L2_IDENT_MSPX4XX, "MSP3400C" },
+ { TVEEPROM_AUDPROC_NONE, "None" },
+ { TVEEPROM_AUDPROC_OTHER, "TEA6300" },
+ { TVEEPROM_AUDPROC_OTHER, "TEA6320" },
+ { TVEEPROM_AUDPROC_OTHER, "TDA9850" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3400C" },
/* 5-9 */
- { V4L2_IDENT_MSPX4XX, "MSP3410D" },
- { V4L2_IDENT_MSPX4XX, "MSP3415" },
- { V4L2_IDENT_MSPX4XX, "MSP3430" },
- { V4L2_IDENT_MSPX4XX, "MSP3438" },
- { V4L2_IDENT_UNKNOWN, "CS5331" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3410D" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3415" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3430" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3438" },
+ { TVEEPROM_AUDPROC_OTHER, "CS5331" },
/* 10-14 */
- { V4L2_IDENT_MSPX4XX, "MSP3435" },
- { V4L2_IDENT_MSPX4XX, "MSP3440" },
- { V4L2_IDENT_MSPX4XX, "MSP3445" },
- { V4L2_IDENT_MSPX4XX, "MSP3411" },
- { V4L2_IDENT_MSPX4XX, "MSP3416" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3435" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3440" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3445" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3411" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3416" },
/* 15-19 */
- { V4L2_IDENT_MSPX4XX, "MSP3425" },
- { V4L2_IDENT_MSPX4XX, "MSP3451" },
- { V4L2_IDENT_MSPX4XX, "MSP3418" },
- { V4L2_IDENT_UNKNOWN, "Type 0x12" },
- { V4L2_IDENT_UNKNOWN, "OKI7716" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3425" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3451" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3418" },
+ { TVEEPROM_AUDPROC_OTHER, "Type 0x12" },
+ { TVEEPROM_AUDPROC_OTHER, "OKI7716" },
/* 20-24 */
- { V4L2_IDENT_MSPX4XX, "MSP4410" },
- { V4L2_IDENT_MSPX4XX, "MSP4420" },
- { V4L2_IDENT_MSPX4XX, "MSP4440" },
- { V4L2_IDENT_MSPX4XX, "MSP4450" },
- { V4L2_IDENT_MSPX4XX, "MSP4408" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4410" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4420" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4440" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4450" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4408" },
/* 25-29 */
- { V4L2_IDENT_MSPX4XX, "MSP4418" },
- { V4L2_IDENT_MSPX4XX, "MSP4428" },
- { V4L2_IDENT_MSPX4XX, "MSP4448" },
- { V4L2_IDENT_MSPX4XX, "MSP4458" },
- { V4L2_IDENT_MSPX4XX, "Type 0x1d" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4418" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4428" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4448" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4458" },
+ { TVEEPROM_AUDPROC_MSP, "Type 0x1d" },
/* 30-34 */
- { V4L2_IDENT_AMBIGUOUS, "CX880" },
- { V4L2_IDENT_AMBIGUOUS, "CX881" },
- { V4L2_IDENT_AMBIGUOUS, "CX883" },
- { V4L2_IDENT_AMBIGUOUS, "CX882" },
- { V4L2_IDENT_AMBIGUOUS, "CX25840" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX880" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX881" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX883" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX882" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX25840" },
/* 35-39 */
- { V4L2_IDENT_AMBIGUOUS, "CX25841" },
- { V4L2_IDENT_AMBIGUOUS, "CX25842" },
- { V4L2_IDENT_AMBIGUOUS, "CX25843" },
- { V4L2_IDENT_AMBIGUOUS, "CX23418" },
- { V4L2_IDENT_AMBIGUOUS, "CX23885" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX25841" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX25842" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX25843" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX23418" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX23885" },
/* 40-44 */
- { V4L2_IDENT_AMBIGUOUS, "CX23888" },
- { V4L2_IDENT_AMBIGUOUS, "SAA7131" },
- { V4L2_IDENT_AMBIGUOUS, "CX23887" },
- { V4L2_IDENT_AMBIGUOUS, "SAA7164" },
- { V4L2_IDENT_AMBIGUOUS, "AU8522" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX23888" },
+ { TVEEPROM_AUDPROC_INTERNAL, "SAA7131" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX23887" },
+ { TVEEPROM_AUDPROC_INTERNAL, "SAA7164" },
+ { TVEEPROM_AUDPROC_INTERNAL, "AU8522" },
};
/* This list is supplied by Hauppauge. Thanks! */
@@ -453,11 +443,11 @@
int i, j, len, done, beenhere, tag, start;
int tuner1 = 0, t_format1 = 0, audioic = -1;
- char *t_name1 = NULL;
+ const char *t_name1 = NULL;
const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
int tuner2 = 0, t_format2 = 0;
- char *t_name2 = NULL;
+ const char *t_name2 = NULL;
const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
memset(tvee, 0, sizeof(*tvee));
@@ -545,10 +535,10 @@
to indicate 4052 mux was removed in favor of using MSP
inputs directly. */
audioic = eeprom_data[i+2] & 0x7f;
- if (audioic < ARRAY_SIZE(audioIC))
- tvee->audio_processor = audioIC[audioic].id;
+ if (audioic < ARRAY_SIZE(audio_ic))
+ tvee->audio_processor = audio_ic[audioic].id;
else
- tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+ tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
break;
/* case 0x03: tag 'EEInfo' */
@@ -578,10 +568,10 @@
to indicate 4052 mux was removed in favor of using MSP
inputs directly. */
audioic = eeprom_data[i+1] & 0x7f;
- if (audioic < ARRAY_SIZE(audioIC))
- tvee->audio_processor = audioIC[audioic].id;
+ if (audioic < ARRAY_SIZE(audio_ic))
+ tvee->audio_processor = audio_ic[audioic].id;
else
- tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+ tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
break;
@@ -726,11 +716,11 @@
t_fmt_name2[6], t_fmt_name2[7], t_format2);
if (audioic < 0) {
tveeprom_info("audio processor is unknown (no idx)\n");
- tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+ tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
} else {
- if (audioic < ARRAY_SIZE(audioIC))
+ if (audioic < ARRAY_SIZE(audio_ic))
tveeprom_info("audio processor is %s (idx %d)\n",
- audioIC[audioic].name, audioic);
+ audio_ic[audioic].name, audioic);
else
tveeprom_info("audio processor is unknown (idx %d)\n",
audioic);
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index a1a3a51..0b4616b 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -377,10 +377,8 @@
ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
buffer2_len);
}
- if (ret < 0) {
- dvb_ringbuffer_flush(&dmxdevfilter->buffer);
+ if (ret < 0)
dmxdevfilter->buffer.error = ret;
- }
if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
dmxdevfilter->state = DMXDEV_STATE_DONE;
spin_unlock(&dmxdevfilter->dev->lock);
@@ -416,10 +414,8 @@
ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
if (ret == buffer1_len)
ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
- if (ret < 0) {
- dvb_ringbuffer_flush(buffer);
+ if (ret < 0)
buffer->error = ret;
- }
spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&buffer->queue);
return 0;
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 335a8f4..886da16 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -367,4 +367,6 @@
#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002
#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004
#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500
+#define USB_PID_CPYTO_REDI_PC50A 0xa803
+#define USB_PID_CTVDIGDUAL_V2 0xe410
#endif
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index 2099f21..23a0d05 100644
--- a/drivers/media/dvb-frontends/au8522_decoder.c
+++ b/drivers/media/dvb-frontends/au8522_decoder.c
@@ -35,7 +35,6 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-device.h>
#include "au8522.h"
#include "au8522_priv.h"
@@ -524,13 +523,8 @@
static int au8522_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct au8522_state *state = to_state(sd);
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = au8522_readreg(state, reg->reg & 0xffff);
return 0;
}
@@ -538,13 +532,8 @@
static int au8522_s_register(struct v4l2_subdev *sd,
const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct au8522_state *state = to_state(sd);
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
au8522_writereg(state, reg->reg, reg->val & 0xff);
return 0;
}
@@ -636,20 +625,10 @@
return 0;
}
-static int au8522_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct au8522_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops au8522_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
- .g_chip_ident = au8522_g_chip_ident,
.reset = au8522_reset,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = au8522_g_register,
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index a54182d..9053614 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -3406,7 +3406,7 @@
{
struct dib8000_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
- int l, i, active, time, ret, time_slave = FE_CALLBACK_TIME_NEVER;
+ int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER;
u8 exit_condition, index_frontend;
u32 delay, callback_time;
@@ -3553,7 +3553,7 @@
}
}
- return ret;
+ return 0;
}
static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
diff --git a/drivers/media/dvb-frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h
index e666718..f22eb9f 100644
--- a/drivers/media/dvb-frontends/drxk.h
+++ b/drivers/media/dvb-frontends/drxk.h
@@ -8,7 +8,7 @@
/**
* struct drxk_config - Configure the initial parameters for DRX-K
*
- * @adr: I2C Address of the DRX-K
+ * @adr: I2C address of the DRX-K
* @parallel_ts: True means that the device uses parallel TS,
* Serial otherwise.
* @dynamic_clk: True means that the clock will be dynamically
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index ec24d71..082014d 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -21,6 +21,8 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -34,35 +36,36 @@
#include "dvb_frontend.h"
#include "drxk.h"
#include "drxk_hard.h"
+#include "dvb_math.h"
-static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
-static int PowerDownQAM(struct drxk_state *state);
-static int SetDVBTStandard(struct drxk_state *state,
- enum OperationMode oMode);
-static int SetQAMStandard(struct drxk_state *state,
- enum OperationMode oMode);
-static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
- s32 tunerFreqOffset);
-static int SetDVBTStandard(struct drxk_state *state,
- enum OperationMode oMode);
-static int DVBTStart(struct drxk_state *state);
-static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
- s32 tunerFreqOffset);
-static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
-static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
-static int SwitchAntennaToQAM(struct drxk_state *state);
-static int SwitchAntennaToDVBT(struct drxk_state *state);
+static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
+static int power_down_qam(struct drxk_state *state);
+static int set_dvbt_standard(struct drxk_state *state,
+ enum operation_mode o_mode);
+static int set_qam_standard(struct drxk_state *state,
+ enum operation_mode o_mode);
+static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
+ s32 tuner_freq_offset);
+static int set_dvbt_standard(struct drxk_state *state,
+ enum operation_mode o_mode);
+static int dvbt_start(struct drxk_state *state);
+static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
+ s32 tuner_freq_offset);
+static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
+static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
+static int switch_antenna_to_qam(struct drxk_state *state);
+static int switch_antenna_to_dvbt(struct drxk_state *state);
-static bool IsDVBT(struct drxk_state *state)
+static bool is_dvbt(struct drxk_state *state)
{
- return state->m_OperationMode == OM_DVBT;
+ return state->m_operation_mode == OM_DVBT;
}
-static bool IsQAM(struct drxk_state *state)
+static bool is_qam(struct drxk_state *state)
{
- return state->m_OperationMode == OM_QAM_ITU_A ||
- state->m_OperationMode == OM_QAM_ITU_B ||
- state->m_OperationMode == OM_QAM_ITU_C;
+ return state->m_operation_mode == OM_QAM_ITU_A ||
+ state->m_operation_mode == OM_QAM_ITU_B ||
+ state->m_operation_mode == OM_QAM_ITU_C;
}
#define NOA1ROM 0
@@ -165,7 +168,7 @@
#define dprintk(level, fmt, arg...) do { \
if (debug >= level) \
- printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
+ pr_debug(fmt, ##arg); \
} while (0)
@@ -186,8 +189,10 @@
u32 R0 = 0;
R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
- Q1 = a / c; /* integer part, only the 4 least significant bits
- will be visible in the result */
+ Q1 = a / c; /*
+ * integer part, only the 4 least significant
+ * bits will be visible in the result
+ */
/* division using radix 16, 7 nibbles in the result */
for (i = 0; i < 7; i++) {
@@ -201,98 +206,9 @@
return Q1;
}
-static u32 Log10Times100(u32 x)
+static inline u32 log10times100(u32 value)
{
- static const u8 scale = 15;
- static const u8 indexWidth = 5;
- u8 i = 0;
- u32 y = 0;
- u32 d = 0;
- u32 k = 0;
- u32 r = 0;
- /*
- log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
- 0 <= n < ((1<<INDEXWIDTH)+1)
- */
-
- static const u32 log2lut[] = {
- 0, /* 0.000000 */
- 290941, /* 290941.300628 */
- 573196, /* 573196.476418 */
- 847269, /* 847269.179851 */
- 1113620, /* 1113620.489452 */
- 1372674, /* 1372673.576986 */
- 1624818, /* 1624817.752104 */
- 1870412, /* 1870411.981536 */
- 2109788, /* 2109787.962654 */
- 2343253, /* 2343252.817465 */
- 2571091, /* 2571091.461923 */
- 2793569, /* 2793568.696416 */
- 3010931, /* 3010931.055901 */
- 3223408, /* 3223408.452106 */
- 3431216, /* 3431215.635215 */
- 3634553, /* 3634553.498355 */
- 3833610, /* 3833610.244726 */
- 4028562, /* 4028562.434393 */
- 4219576, /* 4219575.925308 */
- 4406807, /* 4406806.721144 */
- 4590402, /* 4590401.736809 */
- 4770499, /* 4770499.491025 */
- 4947231, /* 4947230.734179 */
- 5120719, /* 5120719.018555 */
- 5291081, /* 5291081.217197 */
- 5458428, /* 5458427.996830 */
- 5622864, /* 5622864.249668 */
- 5784489, /* 5784489.488298 */
- 5943398, /* 5943398.207380 */
- 6099680, /* 6099680.215452 */
- 6253421, /* 6253420.939751 */
- 6404702, /* 6404701.706649 */
- 6553600, /* 6553600.000000 */
- };
-
-
- if (x == 0)
- return 0;
-
- /* Scale x (normalize) */
- /* computing y in log(x/y) = log(x) - log(y) */
- if ((x & ((0xffffffff) << (scale + 1))) == 0) {
- for (k = scale; k > 0; k--) {
- if (x & (((u32) 1) << scale))
- break;
- x <<= 1;
- }
- } else {
- for (k = scale; k < 31; k++) {
- if ((x & (((u32) (-1)) << (scale + 1))) == 0)
- break;
- x >>= 1;
- }
- }
- /*
- Now x has binary point between bit[scale] and bit[scale-1]
- and 1.0 <= x < 2.0 */
-
- /* correction for divison: log(x) = log(x/y)+log(y) */
- y = k * ((((u32) 1) << scale) * 200);
-
- /* remove integer part */
- x &= ((((u32) 1) << scale) - 1);
- /* get index */
- i = (u8) (x >> (scale - indexWidth));
- /* compute delta (x - a) */
- d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
- /* compute log, multiplication (d* (..)) must be within range ! */
- y += log2lut[i] +
- ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
- /* Conver to log10() */
- y /= 108853; /* (log2(10) << scale) */
- r = (y >> 1);
- /* rounding */
- if (y & ((u32) 1))
- r++;
- return r;
+ return (100L * intlog10(value)) >> 24;
}
/****************************************************************************/
@@ -344,15 +260,15 @@
if (debug > 2) {
int i;
for (i = 0; i < len; i++)
- printk(KERN_CONT " %02x", data[i]);
- printk(KERN_CONT "\n");
+ pr_cont(" %02x", data[i]);
+ pr_cont("\n");
}
status = drxk_i2c_transfer(state, &msg, 1);
if (status >= 0 && status != 1)
status = -EIO;
if (status < 0)
- printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
+ pr_err("i2c write error at addr 0x%02x\n", adr);
return status;
}
@@ -371,22 +287,22 @@
status = drxk_i2c_transfer(state, msgs, 2);
if (status != 2) {
if (debug > 2)
- printk(KERN_CONT ": ERROR!\n");
+ pr_cont(": ERROR!\n");
if (status >= 0)
status = -EIO;
- printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
+ pr_err("i2c read error at addr 0x%02x\n", adr);
return status;
}
if (debug > 2) {
int i;
dprintk(2, ": read from");
for (i = 0; i < len; i++)
- printk(KERN_CONT " %02x", msg[i]);
- printk(KERN_CONT ", value = ");
+ pr_cont(" %02x", msg[i]);
+ pr_cont(", value = ");
for (i = 0; i < alen; i++)
- printk(KERN_CONT " %02x", answ[i]);
- printk(KERN_CONT "\n");
+ pr_cont(" %02x", answ[i]);
+ pr_cont("\n");
}
return 0;
}
@@ -520,55 +436,55 @@
return write32_flags(state, reg, data, 0);
}
-static int write_block(struct drxk_state *state, u32 Address,
- const int BlockSize, const u8 pBlock[])
+static int write_block(struct drxk_state *state, u32 address,
+ const int block_size, const u8 p_block[])
{
- int status = 0, BlkSize = BlockSize;
- u8 Flags = 0;
+ int status = 0, blk_size = block_size;
+ u8 flags = 0;
if (state->single_master)
- Flags |= 0xC0;
+ flags |= 0xC0;
- while (BlkSize > 0) {
- int Chunk = BlkSize > state->m_ChunkSize ?
- state->m_ChunkSize : BlkSize;
- u8 *AdrBuf = &state->Chunk[0];
- u32 AdrLength = 0;
+ while (blk_size > 0) {
+ int chunk = blk_size > state->m_chunk_size ?
+ state->m_chunk_size : blk_size;
+ u8 *adr_buf = &state->chunk[0];
+ u32 adr_length = 0;
- if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
- AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
- AdrBuf[1] = ((Address >> 16) & 0xFF);
- AdrBuf[2] = ((Address >> 24) & 0xFF);
- AdrBuf[3] = ((Address >> 7) & 0xFF);
- AdrBuf[2] |= Flags;
- AdrLength = 4;
- if (Chunk == state->m_ChunkSize)
- Chunk -= 2;
+ if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
+ adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
+ adr_buf[1] = ((address >> 16) & 0xFF);
+ adr_buf[2] = ((address >> 24) & 0xFF);
+ adr_buf[3] = ((address >> 7) & 0xFF);
+ adr_buf[2] |= flags;
+ adr_length = 4;
+ if (chunk == state->m_chunk_size)
+ chunk -= 2;
} else {
- AdrBuf[0] = ((Address << 1) & 0xFF);
- AdrBuf[1] = (((Address >> 16) & 0x0F) |
- ((Address >> 18) & 0xF0));
- AdrLength = 2;
+ adr_buf[0] = ((address << 1) & 0xFF);
+ adr_buf[1] = (((address >> 16) & 0x0F) |
+ ((address >> 18) & 0xF0));
+ adr_length = 2;
}
- memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
- dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
+ memcpy(&state->chunk[adr_length], p_block, chunk);
+ dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
if (debug > 1) {
int i;
- if (pBlock)
- for (i = 0; i < Chunk; i++)
- printk(KERN_CONT " %02x", pBlock[i]);
- printk(KERN_CONT "\n");
+ if (p_block)
+ for (i = 0; i < chunk; i++)
+ pr_cont(" %02x", p_block[i]);
+ pr_cont("\n");
}
status = i2c_write(state, state->demod_address,
- &state->Chunk[0], Chunk + AdrLength);
+ &state->chunk[0], chunk + adr_length);
if (status < 0) {
- printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
- __func__, Address);
+ pr_err("%s: i2c write error at addr 0x%02x\n",
+ __func__, address);
break;
}
- pBlock += Chunk;
- Address += (Chunk >> 1);
- BlkSize -= Chunk;
+ p_block += chunk;
+ address += (chunk >> 1);
+ blk_size -= chunk;
}
return status;
}
@@ -577,11 +493,11 @@
#define DRXK_MAX_RETRIES_POWERUP 20
#endif
-static int PowerUpDevice(struct drxk_state *state)
+static int power_up_device(struct drxk_state *state)
{
int status;
u8 data = 0;
- u16 retryCount = 0;
+ u16 retry_count = 0;
dprintk(1, "\n");
@@ -591,15 +507,15 @@
data = 0;
status = i2c_write(state, state->demod_address,
&data, 1);
- msleep(10);
- retryCount++;
+ usleep_range(10000, 11000);
+ retry_count++;
if (status < 0)
continue;
status = i2c_read1(state, state->demod_address,
&data);
} while (status < 0 &&
- (retryCount < DRXK_MAX_RETRIES_POWERUP));
- if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
+ (retry_count < DRXK_MAX_RETRIES_POWERUP));
+ if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
goto error;
}
@@ -615,11 +531,11 @@
if (status < 0)
goto error;
- state->m_currentPowerMode = DRX_POWER_UP;
+ state->m_current_power_mode = DRX_POWER_UP;
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -631,106 +547,106 @@
* FIXME: most (all?) of the values bellow should be moved into
* struct drxk_config, as they are probably board-specific
*/
- u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
- u32 ulVSBIfAgcOutputLevel = 0;
- u32 ulVSBIfAgcMinLevel = 0;
- u32 ulVSBIfAgcMaxLevel = 0x7FFF;
- u32 ulVSBIfAgcSpeed = 3;
+ u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
+ u32 ul_vsb_if_agc_output_level = 0;
+ u32 ul_vsb_if_agc_min_level = 0;
+ u32 ul_vsb_if_agc_max_level = 0x7FFF;
+ u32 ul_vsb_if_agc_speed = 3;
- u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
- u32 ulVSBRfAgcOutputLevel = 0;
- u32 ulVSBRfAgcMinLevel = 0;
- u32 ulVSBRfAgcMaxLevel = 0x7FFF;
- u32 ulVSBRfAgcSpeed = 3;
- u32 ulVSBRfAgcTop = 9500;
- u32 ulVSBRfAgcCutOffCurrent = 4000;
+ u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
+ u32 ul_vsb_rf_agc_output_level = 0;
+ u32 ul_vsb_rf_agc_min_level = 0;
+ u32 ul_vsb_rf_agc_max_level = 0x7FFF;
+ u32 ul_vsb_rf_agc_speed = 3;
+ u32 ul_vsb_rf_agc_top = 9500;
+ u32 ul_vsb_rf_agc_cut_off_current = 4000;
- u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
- u32 ulATVIfAgcOutputLevel = 0;
- u32 ulATVIfAgcMinLevel = 0;
- u32 ulATVIfAgcMaxLevel = 0;
- u32 ulATVIfAgcSpeed = 3;
+ u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
+ u32 ul_atv_if_agc_output_level = 0;
+ u32 ul_atv_if_agc_min_level = 0;
+ u32 ul_atv_if_agc_max_level = 0;
+ u32 ul_atv_if_agc_speed = 3;
- u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
- u32 ulATVRfAgcOutputLevel = 0;
- u32 ulATVRfAgcMinLevel = 0;
- u32 ulATVRfAgcMaxLevel = 0;
- u32 ulATVRfAgcTop = 9500;
- u32 ulATVRfAgcCutOffCurrent = 4000;
- u32 ulATVRfAgcSpeed = 3;
+ u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
+ u32 ul_atv_rf_agc_output_level = 0;
+ u32 ul_atv_rf_agc_min_level = 0;
+ u32 ul_atv_rf_agc_max_level = 0;
+ u32 ul_atv_rf_agc_top = 9500;
+ u32 ul_atv_rf_agc_cut_off_current = 4000;
+ u32 ul_atv_rf_agc_speed = 3;
u32 ulQual83 = DEFAULT_MER_83;
u32 ulQual93 = DEFAULT_MER_93;
- u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
- u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
+ u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
+ u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
/* io_pad_cfg_mode output mode is drive always */
/* io_pad_cfg_drive is set to power 2 (23 mA) */
- u32 ulGPIOCfg = 0x0113;
- u32 ulInvertTSClock = 0;
- u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
- u32 ulDVBTBitrate = 50000000;
- u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
+ u32 ul_gpio_cfg = 0x0113;
+ u32 ul_invert_ts_clock = 0;
+ u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
+ u32 ul_dvbt_bitrate = 50000000;
+ u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
- u32 ulInsertRSByte = 0;
+ u32 ul_insert_rs_byte = 0;
- u32 ulRfMirror = 1;
- u32 ulPowerDown = 0;
+ u32 ul_rf_mirror = 1;
+ u32 ul_power_down = 0;
dprintk(1, "\n");
- state->m_hasLNA = false;
- state->m_hasDVBT = false;
- state->m_hasDVBC = false;
- state->m_hasATV = false;
- state->m_hasOOB = false;
- state->m_hasAudio = false;
+ state->m_has_lna = false;
+ state->m_has_dvbt = false;
+ state->m_has_dvbc = false;
+ state->m_has_atv = false;
+ state->m_has_oob = false;
+ state->m_has_audio = false;
- if (!state->m_ChunkSize)
- state->m_ChunkSize = 124;
+ if (!state->m_chunk_size)
+ state->m_chunk_size = 124;
- state->m_oscClockFreq = 0;
- state->m_smartAntInverted = false;
- state->m_bPDownOpenBridge = false;
+ state->m_osc_clock_freq = 0;
+ state->m_smart_ant_inverted = false;
+ state->m_b_p_down_open_bridge = false;
/* real system clock frequency in kHz */
- state->m_sysClockFreq = 151875;
+ state->m_sys_clock_freq = 151875;
/* Timing div, 250ns/Psys */
/* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
- state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
+ state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
HI_I2C_DELAY) / 1000;
/* Clipping */
- if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
- state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
- state->m_HICfgWakeUpKey = (state->demod_address << 1);
+ if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
+ state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
+ state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
/* port/bridge/power down ctrl */
- state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
+ state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
- state->m_bPowerDown = (ulPowerDown != 0);
+ state->m_b_power_down = (ul_power_down != 0);
- state->m_DRXK_A3_PATCH_CODE = false;
+ state->m_drxk_a3_patch_code = false;
/* Init AGC and PGA parameters */
/* VSB IF */
- state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
- state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
- state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
- state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
- state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
- state->m_vsbPgaCfg = 140;
+ state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
+ state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
+ state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
+ state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
+ state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
+ state->m_vsb_pga_cfg = 140;
/* VSB RF */
- state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
- state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
- state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
- state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
- state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
- state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
- state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
- state->m_vsbPreSawCfg.reference = 0x07;
- state->m_vsbPreSawCfg.usePreSaw = true;
+ state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
+ state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
+ state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
+ state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
+ state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
+ state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
+ state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
+ state->m_vsb_pre_saw_cfg.reference = 0x07;
+ state->m_vsb_pre_saw_cfg.use_pre_saw = true;
state->m_Quality83percent = DEFAULT_MER_83;
state->m_Quality93percent = DEFAULT_MER_93;
@@ -740,127 +656,127 @@
}
/* ATV IF */
- state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
- state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
- state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
- state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
- state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
+ state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
+ state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
+ state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
+ state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
+ state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
/* ATV RF */
- state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
- state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
- state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
- state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
- state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
- state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
- state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
- state->m_atvPreSawCfg.reference = 0x04;
- state->m_atvPreSawCfg.usePreSaw = true;
+ state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
+ state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
+ state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
+ state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
+ state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
+ state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
+ state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
+ state->m_atv_pre_saw_cfg.reference = 0x04;
+ state->m_atv_pre_saw_cfg.use_pre_saw = true;
/* DVBT RF */
- state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
- state->m_dvbtRfAgcCfg.outputLevel = 0;
- state->m_dvbtRfAgcCfg.minOutputLevel = 0;
- state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
- state->m_dvbtRfAgcCfg.top = 0x2100;
- state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
- state->m_dvbtRfAgcCfg.speed = 1;
+ state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
+ state->m_dvbt_rf_agc_cfg.output_level = 0;
+ state->m_dvbt_rf_agc_cfg.min_output_level = 0;
+ state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
+ state->m_dvbt_rf_agc_cfg.top = 0x2100;
+ state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
+ state->m_dvbt_rf_agc_cfg.speed = 1;
/* DVBT IF */
- state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
- state->m_dvbtIfAgcCfg.outputLevel = 0;
- state->m_dvbtIfAgcCfg.minOutputLevel = 0;
- state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
- state->m_dvbtIfAgcCfg.top = 13424;
- state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
- state->m_dvbtIfAgcCfg.speed = 3;
- state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
- state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
+ state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
+ state->m_dvbt_if_agc_cfg.output_level = 0;
+ state->m_dvbt_if_agc_cfg.min_output_level = 0;
+ state->m_dvbt_if_agc_cfg.max_output_level = 9000;
+ state->m_dvbt_if_agc_cfg.top = 13424;
+ state->m_dvbt_if_agc_cfg.cut_off_current = 0;
+ state->m_dvbt_if_agc_cfg.speed = 3;
+ state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
+ state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
/* state->m_dvbtPgaCfg = 140; */
- state->m_dvbtPreSawCfg.reference = 4;
- state->m_dvbtPreSawCfg.usePreSaw = false;
+ state->m_dvbt_pre_saw_cfg.reference = 4;
+ state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
/* QAM RF */
- state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
- state->m_qamRfAgcCfg.outputLevel = 0;
- state->m_qamRfAgcCfg.minOutputLevel = 6023;
- state->m_qamRfAgcCfg.maxOutputLevel = 27000;
- state->m_qamRfAgcCfg.top = 0x2380;
- state->m_qamRfAgcCfg.cutOffCurrent = 4000;
- state->m_qamRfAgcCfg.speed = 3;
+ state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
+ state->m_qam_rf_agc_cfg.output_level = 0;
+ state->m_qam_rf_agc_cfg.min_output_level = 6023;
+ state->m_qam_rf_agc_cfg.max_output_level = 27000;
+ state->m_qam_rf_agc_cfg.top = 0x2380;
+ state->m_qam_rf_agc_cfg.cut_off_current = 4000;
+ state->m_qam_rf_agc_cfg.speed = 3;
/* QAM IF */
- state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
- state->m_qamIfAgcCfg.outputLevel = 0;
- state->m_qamIfAgcCfg.minOutputLevel = 0;
- state->m_qamIfAgcCfg.maxOutputLevel = 9000;
- state->m_qamIfAgcCfg.top = 0x0511;
- state->m_qamIfAgcCfg.cutOffCurrent = 0;
- state->m_qamIfAgcCfg.speed = 3;
- state->m_qamIfAgcCfg.IngainTgtMax = 5119;
- state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
+ state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
+ state->m_qam_if_agc_cfg.output_level = 0;
+ state->m_qam_if_agc_cfg.min_output_level = 0;
+ state->m_qam_if_agc_cfg.max_output_level = 9000;
+ state->m_qam_if_agc_cfg.top = 0x0511;
+ state->m_qam_if_agc_cfg.cut_off_current = 0;
+ state->m_qam_if_agc_cfg.speed = 3;
+ state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
+ state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
- state->m_qamPgaCfg = 140;
- state->m_qamPreSawCfg.reference = 4;
- state->m_qamPreSawCfg.usePreSaw = false;
+ state->m_qam_pga_cfg = 140;
+ state->m_qam_pre_saw_cfg.reference = 4;
+ state->m_qam_pre_saw_cfg.use_pre_saw = false;
- state->m_OperationMode = OM_NONE;
- state->m_DrxkState = DRXK_UNINITIALIZED;
+ state->m_operation_mode = OM_NONE;
+ state->m_drxk_state = DRXK_UNINITIALIZED;
/* MPEG output configuration */
- state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
- state->m_insertRSByte = false; /* If TRUE; insert RS byte */
- state->m_invertDATA = false; /* If TRUE; invert DATA signals */
- state->m_invertERR = false; /* If TRUE; invert ERR signal */
- state->m_invertSTR = false; /* If TRUE; invert STR signals */
- state->m_invertVAL = false; /* If TRUE; invert VAL signals */
- state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
+ state->m_enable_mpeg_output = true; /* If TRUE; enable MPEG ouput */
+ state->m_insert_rs_byte = false; /* If TRUE; insert RS byte */
+ state->m_invert_data = false; /* If TRUE; invert DATA signals */
+ state->m_invert_err = false; /* If TRUE; invert ERR signal */
+ state->m_invert_str = false; /* If TRUE; invert STR signals */
+ state->m_invert_val = false; /* If TRUE; invert VAL signals */
+ state->m_invert_clk = (ul_invert_ts_clock != 0); /* If TRUE; invert CLK signals */
/* If TRUE; static MPEG clockrate will be used;
otherwise clockrate will adapt to the bitrate of the TS */
- state->m_DVBTBitrate = ulDVBTBitrate;
- state->m_DVBCBitrate = ulDVBCBitrate;
+ state->m_dvbt_bitrate = ul_dvbt_bitrate;
+ state->m_dvbc_bitrate = ul_dvbc_bitrate;
- state->m_TSDataStrength = (ulTSDataStrength & 0x07);
+ state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
/* Maximum bitrate in b/s in case static clockrate is selected */
- state->m_mpegTsStaticBitrate = 19392658;
- state->m_disableTEIhandling = false;
+ state->m_mpeg_ts_static_bitrate = 19392658;
+ state->m_disable_te_ihandling = false;
- if (ulInsertRSByte)
- state->m_insertRSByte = true;
+ if (ul_insert_rs_byte)
+ state->m_insert_rs_byte = true;
- state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
- if (ulMpegLockTimeOut < 10000)
- state->m_MpegLockTimeOut = ulMpegLockTimeOut;
- state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
- if (ulDemodLockTimeOut < 10000)
- state->m_DemodLockTimeOut = ulDemodLockTimeOut;
+ state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
+ if (ul_mpeg_lock_time_out < 10000)
+ state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
+ state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
+ if (ul_demod_lock_time_out < 10000)
+ state->m_demod_lock_time_out = ul_demod_lock_time_out;
/* QAM defaults */
- state->m_Constellation = DRX_CONSTELLATION_AUTO;
- state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
- state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
- state->m_fecRsPrescale = 1;
+ state->m_constellation = DRX_CONSTELLATION_AUTO;
+ state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
+ state->m_fec_rs_plen = 204 * 8; /* fecRsPlen annex A */
+ state->m_fec_rs_prescale = 1;
- state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
- state->m_agcFastClipCtrlDelay = 0;
+ state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
+ state->m_agcfast_clip_ctrl_delay = 0;
- state->m_GPIOCfg = (ulGPIOCfg);
+ state->m_gpio_cfg = ul_gpio_cfg;
- state->m_bPowerDown = false;
- state->m_currentPowerMode = DRX_POWER_DOWN;
+ state->m_b_power_down = false;
+ state->m_current_power_mode = DRX_POWER_DOWN;
- state->m_rfmirror = (ulRfMirror == 0);
- state->m_IfAgcPol = false;
+ state->m_rfmirror = (ul_rf_mirror == 0);
+ state->m_if_agc_pol = false;
return 0;
}
-static int DRXX_Open(struct drxk_state *state)
+static int drxx_open(struct drxk_state *state)
{
int status = 0;
u32 jtag = 0;
@@ -869,7 +785,8 @@
dprintk(1, "\n");
/* stop lock indicator process */
- status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+ status = write16(state, SCU_RAM_GPIO__A,
+ SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
if (status < 0)
goto error;
/* Check device id */
@@ -888,14 +805,14 @@
status = write16(state, SIO_TOP_COMM_KEY__A, key);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int GetDeviceCapabilities(struct drxk_state *state)
+static int get_device_capabilities(struct drxk_state *state)
{
- u16 sioPdrOhwCfg = 0;
- u32 sioTopJtagidLo = 0;
+ u16 sio_pdr_ohw_cfg = 0;
+ u32 sio_top_jtagid_lo = 0;
int status;
const char *spin = "";
@@ -903,197 +820,196 @@
/* driver 0.9.0 */
/* stop lock indicator process */
- status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+ status = write16(state, SCU_RAM_GPIO__A,
+ SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
if (status < 0)
goto error;
status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
if (status < 0)
goto error;
- status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
+ status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
if (status < 0)
goto error;
status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
if (status < 0)
goto error;
- switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
+ switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
case 0:
/* ignore (bypass ?) */
break;
case 1:
/* 27 MHz */
- state->m_oscClockFreq = 27000;
+ state->m_osc_clock_freq = 27000;
break;
case 2:
/* 20.25 MHz */
- state->m_oscClockFreq = 20250;
+ state->m_osc_clock_freq = 20250;
break;
case 3:
/* 4 MHz */
- state->m_oscClockFreq = 20250;
+ state->m_osc_clock_freq = 20250;
break;
default:
- printk(KERN_ERR "drxk: Clock Frequency is unknown\n");
+ pr_err("Clock Frequency is unknown\n");
return -EINVAL;
}
/*
Determine device capabilities
Based on pinning v14
*/
- status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
+ status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
if (status < 0)
goto error;
- printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
+ pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
/* driver 0.9.0 */
- switch ((sioTopJtagidLo >> 29) & 0xF) {
+ switch ((sio_top_jtagid_lo >> 29) & 0xF) {
case 0:
- state->m_deviceSpin = DRXK_SPIN_A1;
+ state->m_device_spin = DRXK_SPIN_A1;
spin = "A1";
break;
case 2:
- state->m_deviceSpin = DRXK_SPIN_A2;
+ state->m_device_spin = DRXK_SPIN_A2;
spin = "A2";
break;
case 3:
- state->m_deviceSpin = DRXK_SPIN_A3;
+ state->m_device_spin = DRXK_SPIN_A3;
spin = "A3";
break;
default:
- state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
+ state->m_device_spin = DRXK_SPIN_UNKNOWN;
status = -EINVAL;
- printk(KERN_ERR "drxk: Spin %d unknown\n",
- (sioTopJtagidLo >> 29) & 0xF);
+ pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
goto error2;
}
- switch ((sioTopJtagidLo >> 12) & 0xFF) {
+ switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
case 0x13:
/* typeId = DRX3913K_TYPE_ID */
- state->m_hasLNA = false;
- state->m_hasOOB = false;
- state->m_hasATV = false;
- state->m_hasAudio = false;
- state->m_hasDVBT = true;
- state->m_hasDVBC = true;
- state->m_hasSAWSW = true;
- state->m_hasGPIO2 = false;
- state->m_hasGPIO1 = false;
- state->m_hasIRQN = false;
+ state->m_has_lna = false;
+ state->m_has_oob = false;
+ state->m_has_atv = false;
+ state->m_has_audio = false;
+ state->m_has_dvbt = true;
+ state->m_has_dvbc = true;
+ state->m_has_sawsw = true;
+ state->m_has_gpio2 = false;
+ state->m_has_gpio1 = false;
+ state->m_has_irqn = false;
break;
case 0x15:
/* typeId = DRX3915K_TYPE_ID */
- state->m_hasLNA = false;
- state->m_hasOOB = false;
- state->m_hasATV = true;
- state->m_hasAudio = false;
- state->m_hasDVBT = true;
- state->m_hasDVBC = false;
- state->m_hasSAWSW = true;
- state->m_hasGPIO2 = true;
- state->m_hasGPIO1 = true;
- state->m_hasIRQN = false;
+ state->m_has_lna = false;
+ state->m_has_oob = false;
+ state->m_has_atv = true;
+ state->m_has_audio = false;
+ state->m_has_dvbt = true;
+ state->m_has_dvbc = false;
+ state->m_has_sawsw = true;
+ state->m_has_gpio2 = true;
+ state->m_has_gpio1 = true;
+ state->m_has_irqn = false;
break;
case 0x16:
/* typeId = DRX3916K_TYPE_ID */
- state->m_hasLNA = false;
- state->m_hasOOB = false;
- state->m_hasATV = true;
- state->m_hasAudio = false;
- state->m_hasDVBT = true;
- state->m_hasDVBC = false;
- state->m_hasSAWSW = true;
- state->m_hasGPIO2 = true;
- state->m_hasGPIO1 = true;
- state->m_hasIRQN = false;
+ state->m_has_lna = false;
+ state->m_has_oob = false;
+ state->m_has_atv = true;
+ state->m_has_audio = false;
+ state->m_has_dvbt = true;
+ state->m_has_dvbc = false;
+ state->m_has_sawsw = true;
+ state->m_has_gpio2 = true;
+ state->m_has_gpio1 = true;
+ state->m_has_irqn = false;
break;
case 0x18:
/* typeId = DRX3918K_TYPE_ID */
- state->m_hasLNA = false;
- state->m_hasOOB = false;
- state->m_hasATV = true;
- state->m_hasAudio = true;
- state->m_hasDVBT = true;
- state->m_hasDVBC = false;
- state->m_hasSAWSW = true;
- state->m_hasGPIO2 = true;
- state->m_hasGPIO1 = true;
- state->m_hasIRQN = false;
+ state->m_has_lna = false;
+ state->m_has_oob = false;
+ state->m_has_atv = true;
+ state->m_has_audio = true;
+ state->m_has_dvbt = true;
+ state->m_has_dvbc = false;
+ state->m_has_sawsw = true;
+ state->m_has_gpio2 = true;
+ state->m_has_gpio1 = true;
+ state->m_has_irqn = false;
break;
case 0x21:
/* typeId = DRX3921K_TYPE_ID */
- state->m_hasLNA = false;
- state->m_hasOOB = false;
- state->m_hasATV = true;
- state->m_hasAudio = true;
- state->m_hasDVBT = true;
- state->m_hasDVBC = true;
- state->m_hasSAWSW = true;
- state->m_hasGPIO2 = true;
- state->m_hasGPIO1 = true;
- state->m_hasIRQN = false;
+ state->m_has_lna = false;
+ state->m_has_oob = false;
+ state->m_has_atv = true;
+ state->m_has_audio = true;
+ state->m_has_dvbt = true;
+ state->m_has_dvbc = true;
+ state->m_has_sawsw = true;
+ state->m_has_gpio2 = true;
+ state->m_has_gpio1 = true;
+ state->m_has_irqn = false;
break;
case 0x23:
/* typeId = DRX3923K_TYPE_ID */
- state->m_hasLNA = false;
- state->m_hasOOB = false;
- state->m_hasATV = true;
- state->m_hasAudio = true;
- state->m_hasDVBT = true;
- state->m_hasDVBC = true;
- state->m_hasSAWSW = true;
- state->m_hasGPIO2 = true;
- state->m_hasGPIO1 = true;
- state->m_hasIRQN = false;
+ state->m_has_lna = false;
+ state->m_has_oob = false;
+ state->m_has_atv = true;
+ state->m_has_audio = true;
+ state->m_has_dvbt = true;
+ state->m_has_dvbc = true;
+ state->m_has_sawsw = true;
+ state->m_has_gpio2 = true;
+ state->m_has_gpio1 = true;
+ state->m_has_irqn = false;
break;
case 0x25:
/* typeId = DRX3925K_TYPE_ID */
- state->m_hasLNA = false;
- state->m_hasOOB = false;
- state->m_hasATV = true;
- state->m_hasAudio = true;
- state->m_hasDVBT = true;
- state->m_hasDVBC = true;
- state->m_hasSAWSW = true;
- state->m_hasGPIO2 = true;
- state->m_hasGPIO1 = true;
- state->m_hasIRQN = false;
+ state->m_has_lna = false;
+ state->m_has_oob = false;
+ state->m_has_atv = true;
+ state->m_has_audio = true;
+ state->m_has_dvbt = true;
+ state->m_has_dvbc = true;
+ state->m_has_sawsw = true;
+ state->m_has_gpio2 = true;
+ state->m_has_gpio1 = true;
+ state->m_has_irqn = false;
break;
case 0x26:
/* typeId = DRX3926K_TYPE_ID */
- state->m_hasLNA = false;
- state->m_hasOOB = false;
- state->m_hasATV = true;
- state->m_hasAudio = false;
- state->m_hasDVBT = true;
- state->m_hasDVBC = true;
- state->m_hasSAWSW = true;
- state->m_hasGPIO2 = true;
- state->m_hasGPIO1 = true;
- state->m_hasIRQN = false;
+ state->m_has_lna = false;
+ state->m_has_oob = false;
+ state->m_has_atv = true;
+ state->m_has_audio = false;
+ state->m_has_dvbt = true;
+ state->m_has_dvbc = true;
+ state->m_has_sawsw = true;
+ state->m_has_gpio2 = true;
+ state->m_has_gpio1 = true;
+ state->m_has_irqn = false;
break;
default:
- printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
- ((sioTopJtagidLo >> 12) & 0xFF));
+ pr_err("DeviceID 0x%02x not supported\n",
+ ((sio_top_jtagid_lo >> 12) & 0xFF));
status = -EINVAL;
goto error2;
}
- printk(KERN_INFO
- "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
- ((sioTopJtagidLo >> 12) & 0xFF), spin,
- state->m_oscClockFreq / 1000,
- state->m_oscClockFreq % 1000);
+ pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
+ ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
+ state->m_osc_clock_freq / 1000,
+ state->m_osc_clock_freq % 1000);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
error2:
return status;
}
-static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
+static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
{
int status;
bool powerdown_cmd;
@@ -1105,37 +1021,37 @@
if (status < 0)
goto error;
if (cmd == SIO_HI_RA_RAM_CMD_RESET)
- msleep(1);
+ usleep_range(1000, 2000);
powerdown_cmd =
(bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
- ((state->m_HICfgCtrl) &
+ ((state->m_hi_cfg_ctrl) &
SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
if (powerdown_cmd == false) {
/* Wait until command rdy */
- u32 retryCount = 0;
- u16 waitCmd;
+ u32 retry_count = 0;
+ u16 wait_cmd;
do {
- msleep(1);
- retryCount += 1;
+ usleep_range(1000, 2000);
+ retry_count += 1;
status = read16(state, SIO_HI_RA_RAM_CMD__A,
- &waitCmd);
- } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
- && (waitCmd != 0));
+ &wait_cmd);
+ } while ((status < 0) && (retry_count < DRXK_MAX_RETRIES)
+ && (wait_cmd != 0));
if (status < 0)
goto error;
- status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
+ status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
}
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int HI_CfgCommand(struct drxk_state *state)
+static int hi_cfg_command(struct drxk_state *state)
{
int status;
@@ -1143,61 +1059,68 @@
mutex_lock(&state->mutex);
- status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
+ status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
+ state->m_hi_cfg_timeout);
if (status < 0)
goto error;
- status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
+ status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
+ state->m_hi_cfg_ctrl);
if (status < 0)
goto error;
- status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
+ status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
+ state->m_hi_cfg_wake_up_key);
if (status < 0)
goto error;
- status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
+ status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
+ state->m_hi_cfg_bridge_delay);
if (status < 0)
goto error;
- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
+ status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+ state->m_hi_cfg_timing_div);
if (status < 0)
goto error;
- status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
+ status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
+ SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
if (status < 0)
goto error;
- status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
+ status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
if (status < 0)
goto error;
- state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+ state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
error:
mutex_unlock(&state->mutex);
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int InitHI(struct drxk_state *state)
+static int init_hi(struct drxk_state *state)
{
dprintk(1, "\n");
- state->m_HICfgWakeUpKey = (state->demod_address << 1);
- state->m_HICfgTimeout = 0x96FF;
+ state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
+ state->m_hi_cfg_timeout = 0x96FF;
/* port/bridge/power down ctrl */
- state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
+ state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
- return HI_CfgCommand(state);
+ return hi_cfg_command(state);
}
-static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
+static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
{
int status = -1;
- u16 sioPdrMclkCfg = 0;
- u16 sioPdrMdxCfg = 0;
+ u16 sio_pdr_mclk_cfg = 0;
+ u16 sio_pdr_mdx_cfg = 0;
u16 err_cfg = 0;
dprintk(1, ": mpeg %s, %s mode\n",
- mpegEnable ? "enable" : "disable",
- state->m_enableParallel ? "parallel" : "serial");
+ mpeg_enable ? "enable" : "disable",
+ state->m_enable_parallel ? "parallel" : "serial");
/* stop lock indicator process */
- status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+ status = write16(state, SCU_RAM_GPIO__A,
+ SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
if (status < 0)
goto error;
@@ -1206,7 +1129,7 @@
if (status < 0)
goto error;
- if (mpegEnable == false) {
+ if (mpeg_enable == false) {
/* Set MPEG TS pads to inputmode */
status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
if (status < 0)
@@ -1246,19 +1169,19 @@
goto error;
} else {
/* Enable MPEG output */
- sioPdrMdxCfg =
- ((state->m_TSDataStrength <<
+ sio_pdr_mdx_cfg =
+ ((state->m_ts_data_strength <<
SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
- sioPdrMclkCfg = ((state->m_TSClockkStrength <<
+ sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
SIO_PDR_MCLK_CFG_DRIVE__B) |
0x0003);
- status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
if (status < 0)
goto error;
if (state->enable_merr_cfg)
- err_cfg = sioPdrMdxCfg;
+ err_cfg = sio_pdr_mdx_cfg;
status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
if (status < 0)
@@ -1267,31 +1190,38 @@
if (status < 0)
goto error;
- if (state->m_enableParallel == true) {
+ if (state->m_enable_parallel == true) {
/* paralel -> enable MD1 to MD7 */
- status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MD1_CFG__A,
+ sio_pdr_mdx_cfg);
if (status < 0)
goto error;
- status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MD2_CFG__A,
+ sio_pdr_mdx_cfg);
if (status < 0)
goto error;
- status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MD3_CFG__A,
+ sio_pdr_mdx_cfg);
if (status < 0)
goto error;
- status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MD4_CFG__A,
+ sio_pdr_mdx_cfg);
if (status < 0)
goto error;
- status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MD5_CFG__A,
+ sio_pdr_mdx_cfg);
if (status < 0)
goto error;
- status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MD6_CFG__A,
+ sio_pdr_mdx_cfg);
if (status < 0)
goto error;
- status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MD7_CFG__A,
+ sio_pdr_mdx_cfg);
if (status < 0)
goto error;
} else {
- sioPdrMdxCfg = ((state->m_TSDataStrength <<
+ sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
SIO_PDR_MD0_CFG_DRIVE__B)
| 0x0003);
/* serial -> disable MD1 to MD7 */
@@ -1317,10 +1247,10 @@
if (status < 0)
goto error;
}
- status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
+ status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
if (status < 0)
goto error;
- status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
+ status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
if (status < 0)
goto error;
}
@@ -1332,21 +1262,21 @@
status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int MPEGTSDisable(struct drxk_state *state)
+static int mpegts_disable(struct drxk_state *state)
{
dprintk(1, "\n");
- return MPEGTSConfigurePins(state, false);
+ return mpegts_configure_pins(state, false);
}
-static int BLChainCmd(struct drxk_state *state,
- u16 romOffset, u16 nrOfElements, u32 timeOut)
+static int bl_chain_cmd(struct drxk_state *state,
+ u16 rom_offset, u16 nr_of_elements, u32 time_out)
{
- u16 blStatus = 0;
+ u16 bl_status = 0;
int status;
unsigned long end;
@@ -1355,46 +1285,46 @@
status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
if (status < 0)
goto error;
- status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
+ status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
if (status < 0)
goto error;
- status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
+ status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
if (status < 0)
goto error;
status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
if (status < 0)
goto error;
- end = jiffies + msecs_to_jiffies(timeOut);
+ end = jiffies + msecs_to_jiffies(time_out);
do {
- msleep(1);
- status = read16(state, SIO_BL_STATUS__A, &blStatus);
+ usleep_range(1000, 2000);
+ status = read16(state, SIO_BL_STATUS__A, &bl_status);
if (status < 0)
goto error;
- } while ((blStatus == 0x1) &&
+ } while ((bl_status == 0x1) &&
((time_is_after_jiffies(end))));
- if (blStatus == 0x1) {
- printk(KERN_ERR "drxk: SIO not ready\n");
+ if (bl_status == 0x1) {
+ pr_err("SIO not ready\n");
status = -EINVAL;
goto error2;
}
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
error2:
mutex_unlock(&state->mutex);
return status;
}
-static int DownloadMicrocode(struct drxk_state *state,
- const u8 pMCImage[], u32 Length)
+static int download_microcode(struct drxk_state *state,
+ const u8 p_mc_image[], u32 length)
{
- const u8 *pSrc = pMCImage;
- u32 Address;
- u16 nBlocks;
- u16 BlockSize;
+ const u8 *p_src = p_mc_image;
+ u32 address;
+ u16 n_blocks;
+ u16 block_size;
u32 offset = 0;
u32 i;
int status = 0;
@@ -1404,130 +1334,131 @@
/* down the drain (we don't care about MAGIC_WORD) */
#if 0
/* For future reference */
- Drain = (pSrc[0] << 8) | pSrc[1];
+ drain = (p_src[0] << 8) | p_src[1];
#endif
- pSrc += sizeof(u16);
+ p_src += sizeof(u16);
offset += sizeof(u16);
- nBlocks = (pSrc[0] << 8) | pSrc[1];
- pSrc += sizeof(u16);
+ n_blocks = (p_src[0] << 8) | p_src[1];
+ p_src += sizeof(u16);
offset += sizeof(u16);
- for (i = 0; i < nBlocks; i += 1) {
- Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
- (pSrc[2] << 8) | pSrc[3];
- pSrc += sizeof(u32);
+ for (i = 0; i < n_blocks; i += 1) {
+ address = (p_src[0] << 24) | (p_src[1] << 16) |
+ (p_src[2] << 8) | p_src[3];
+ p_src += sizeof(u32);
offset += sizeof(u32);
- BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
- pSrc += sizeof(u16);
+ block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
+ p_src += sizeof(u16);
offset += sizeof(u16);
#if 0
/* For future reference */
- Flags = (pSrc[0] << 8) | pSrc[1];
+ flags = (p_src[0] << 8) | p_src[1];
#endif
- pSrc += sizeof(u16);
+ p_src += sizeof(u16);
offset += sizeof(u16);
#if 0
/* For future reference */
- BlockCRC = (pSrc[0] << 8) | pSrc[1];
+ block_crc = (p_src[0] << 8) | p_src[1];
#endif
- pSrc += sizeof(u16);
+ p_src += sizeof(u16);
offset += sizeof(u16);
- if (offset + BlockSize > Length) {
- printk(KERN_ERR "drxk: Firmware is corrupted.\n");
+ if (offset + block_size > length) {
+ pr_err("Firmware is corrupted.\n");
return -EINVAL;
}
- status = write_block(state, Address, BlockSize, pSrc);
+ status = write_block(state, address, block_size, p_src);
if (status < 0) {
- printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
+ pr_err("Error %d while loading firmware\n", status);
break;
}
- pSrc += BlockSize;
- offset += BlockSize;
+ p_src += block_size;
+ offset += block_size;
}
return status;
}
-static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
+static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
{
int status;
u16 data = 0;
- u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
- u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
+ u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
+ u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
unsigned long end;
dprintk(1, "\n");
if (enable == false) {
- desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
- desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
+ desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
+ desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
}
status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
- if (status >= 0 && data == desiredStatus) {
+ if (status >= 0 && data == desired_status) {
/* tokenring already has correct status */
return status;
}
/* Disable/enable dvbt tokenring bridge */
- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
+ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
do {
status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
- if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
+ if ((status >= 0 && data == desired_status)
+ || time_is_after_jiffies(end))
break;
- msleep(1);
+ usleep_range(1000, 2000);
} while (1);
- if (data != desiredStatus) {
- printk(KERN_ERR "drxk: SIO not ready\n");
+ if (data != desired_status) {
+ pr_err("SIO not ready\n");
return -EINVAL;
}
return status;
}
-static int MPEGTSStop(struct drxk_state *state)
+static int mpegts_stop(struct drxk_state *state)
{
int status = 0;
- u16 fecOcSncMode = 0;
- u16 fecOcIprMode = 0;
+ u16 fec_oc_snc_mode = 0;
+ u16 fec_oc_ipr_mode = 0;
dprintk(1, "\n");
/* Gracefull shutdown (byte boundaries) */
- status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
+ status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
if (status < 0)
goto error;
- fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
- status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
+ fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
+ status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
if (status < 0)
goto error;
/* Suppress MCLK during absence of data */
- status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
+ status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
if (status < 0)
goto error;
- fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
- status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
+ fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
+ status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
static int scu_command(struct drxk_state *state,
- u16 cmd, u8 parameterLen,
- u16 *parameter, u8 resultLen, u16 *result)
+ u16 cmd, u8 parameter_len,
+ u16 *parameter, u8 result_len, u16 *result)
{
#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
#error DRXK register mapping no longer compatible with this routine!
#endif
- u16 curCmd = 0;
+ u16 cur_cmd = 0;
int status = -EINVAL;
unsigned long end;
u8 buffer[34];
@@ -1537,9 +1468,9 @@
dprintk(1, "\n");
- if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
- ((resultLen > 0) && (result == NULL))) {
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
+ ((result_len > 0) && (result == NULL))) {
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -1547,7 +1478,7 @@
/* assume that the command register is ready
since it is checked afterwards */
- for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
+ for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
buffer[cnt++] = (parameter[ii] & 0xFF);
buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
}
@@ -1555,27 +1486,28 @@
buffer[cnt++] = ((cmd >> 8) & 0xFF);
write_block(state, SCU_RAM_PARAM_0__A -
- (parameterLen - 1), cnt, buffer);
+ (parameter_len - 1), cnt, buffer);
/* Wait until SCU has processed command */
end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
do {
- msleep(1);
- status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
+ usleep_range(1000, 2000);
+ status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
if (status < 0)
goto error;
- } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
- if (curCmd != DRX_SCU_READY) {
- printk(KERN_ERR "drxk: SCU not ready\n");
+ } while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
+ if (cur_cmd != DRX_SCU_READY) {
+ pr_err("SCU not ready\n");
status = -EIO;
goto error2;
}
/* read results */
- if ((resultLen > 0) && (result != NULL)) {
+ if ((result_len > 0) && (result != NULL)) {
s16 err;
int ii;
- for (ii = resultLen - 1; ii >= 0; ii -= 1) {
- status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
+ for (ii = result_len - 1; ii >= 0; ii -= 1) {
+ status = read16(state, SCU_RAM_PARAM_0__A - ii,
+ &result[ii]);
if (status < 0)
goto error;
}
@@ -1603,7 +1535,7 @@
sprintf(errname, "ERROR: %d\n", err);
p = errname;
}
- printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
+ pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
status = -EINVAL;
goto error2;
@@ -1611,13 +1543,13 @@
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
error2:
mutex_unlock(&state->mutex);
return status;
}
-static int SetIqmAf(struct drxk_state *state, bool active)
+static int set_iqm_af(struct drxk_state *state, bool active)
{
u16 data = 0;
int status;
@@ -1647,14 +1579,14 @@
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
+static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
{
int status = 0;
- u16 sioCcPwdMode = 0;
+ u16 sio_cc_pwd_mode = 0;
dprintk(1, "\n");
@@ -1664,19 +1596,19 @@
switch (*mode) {
case DRX_POWER_UP:
- sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
+ sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
break;
case DRXK_POWER_DOWN_OFDM:
- sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
+ sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
break;
case DRXK_POWER_DOWN_CORE:
- sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
+ sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
break;
case DRXK_POWER_DOWN_PLL:
- sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
+ sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
break;
case DRX_POWER_DOWN:
- sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
+ sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
break;
default:
/* Unknow sleep mode */
@@ -1684,15 +1616,15 @@
}
/* If already in requested power mode, do nothing */
- if (state->m_currentPowerMode == *mode)
+ if (state->m_current_power_mode == *mode)
return 0;
/* For next steps make sure to start from DRX_POWER_UP mode */
- if (state->m_currentPowerMode != DRX_POWER_UP) {
- status = PowerUpDevice(state);
+ if (state->m_current_power_mode != DRX_POWER_UP) {
+ status = power_up_device(state);
if (status < 0)
goto error;
- status = DVBTEnableOFDMTokenRing(state, true);
+ status = dvbt_enable_ofdm_token_ring(state, true);
if (status < 0)
goto error;
}
@@ -1709,31 +1641,31 @@
/* Power down device */
/* stop all comm_exec */
/* Stop and power down previous standard */
- switch (state->m_OperationMode) {
+ switch (state->m_operation_mode) {
case OM_DVBT:
- status = MPEGTSStop(state);
+ status = mpegts_stop(state);
if (status < 0)
goto error;
- status = PowerDownDVBT(state, false);
+ status = power_down_dvbt(state, false);
if (status < 0)
goto error;
break;
case OM_QAM_ITU_A:
case OM_QAM_ITU_C:
- status = MPEGTSStop(state);
+ status = mpegts_stop(state);
if (status < 0)
goto error;
- status = PowerDownQAM(state);
+ status = power_down_qam(state);
if (status < 0)
goto error;
break;
default:
break;
}
- status = DVBTEnableOFDMTokenRing(state, false);
+ status = dvbt_enable_ofdm_token_ring(state, false);
if (status < 0)
goto error;
- status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
+ status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
if (status < 0)
goto error;
status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
@@ -1741,26 +1673,26 @@
goto error;
if (*mode != DRXK_POWER_DOWN_OFDM) {
- state->m_HICfgCtrl |=
+ state->m_hi_cfg_ctrl |=
SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
- status = HI_CfgCommand(state);
+ status = hi_cfg_command(state);
if (status < 0)
goto error;
}
}
- state->m_currentPowerMode = *mode;
+ state->m_current_power_mode = *mode;
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
+static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
{
- enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
- u16 cmdResult = 0;
+ enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
+ u16 cmd_result = 0;
u16 data = 0;
int status;
@@ -1771,11 +1703,17 @@
goto error;
if (data == SCU_COMM_EXEC_ACTIVE) {
/* Send OFDM stop command */
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+ status = scu_command(state,
+ SCU_RAM_COMMAND_STANDARD_OFDM
+ | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+ 0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
/* Send OFDM reset command */
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+ status = scu_command(state,
+ SCU_RAM_COMMAND_STANDARD_OFDM
+ | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+ 0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
}
@@ -1792,24 +1730,24 @@
goto error;
/* powerdown AFE */
- status = SetIqmAf(state, false);
+ status = set_iqm_af(state, false);
if (status < 0)
goto error;
/* powerdown to OFDM mode */
- if (setPowerMode) {
- status = CtrlPowerMode(state, &powerMode);
+ if (set_power_mode) {
+ status = ctrl_power_mode(state, &power_mode);
if (status < 0)
goto error;
}
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int SetOperationMode(struct drxk_state *state,
- enum OperationMode oMode)
+static int setoperation_mode(struct drxk_state *state,
+ enum operation_mode o_mode)
{
int status = 0;
@@ -1821,36 +1759,37 @@
*/
/* disable HW lock indicator */
- status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+ status = write16(state, SCU_RAM_GPIO__A,
+ SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
if (status < 0)
goto error;
/* Device is already at the required mode */
- if (state->m_OperationMode == oMode)
+ if (state->m_operation_mode == o_mode)
return 0;
- switch (state->m_OperationMode) {
+ switch (state->m_operation_mode) {
/* OM_NONE was added for start up */
case OM_NONE:
break;
case OM_DVBT:
- status = MPEGTSStop(state);
+ status = mpegts_stop(state);
if (status < 0)
goto error;
- status = PowerDownDVBT(state, true);
+ status = power_down_dvbt(state, true);
if (status < 0)
goto error;
- state->m_OperationMode = OM_NONE;
+ state->m_operation_mode = OM_NONE;
break;
case OM_QAM_ITU_A: /* fallthrough */
case OM_QAM_ITU_C:
- status = MPEGTSStop(state);
+ status = mpegts_stop(state);
if (status < 0)
goto error;
- status = PowerDownQAM(state);
+ status = power_down_qam(state);
if (status < 0)
goto error;
- state->m_OperationMode = OM_NONE;
+ state->m_operation_mode = OM_NONE;
break;
case OM_QAM_ITU_B:
default:
@@ -1861,20 +1800,20 @@
/*
Power up new standard
*/
- switch (oMode) {
+ switch (o_mode) {
case OM_DVBT:
dprintk(1, ": DVB-T\n");
- state->m_OperationMode = oMode;
- status = SetDVBTStandard(state, oMode);
+ state->m_operation_mode = o_mode;
+ status = set_dvbt_standard(state, o_mode);
if (status < 0)
goto error;
break;
case OM_QAM_ITU_A: /* fallthrough */
case OM_QAM_ITU_C:
dprintk(1, ": DVB-C Annex %c\n",
- (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
- state->m_OperationMode = oMode;
- status = SetQAMStandard(state, oMode);
+ (state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
+ state->m_operation_mode = o_mode;
+ status = set_qam_standard(state, o_mode);
if (status < 0)
goto error;
break;
@@ -1884,121 +1823,121 @@
}
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int Start(struct drxk_state *state, s32 offsetFreq,
- s32 IntermediateFrequency)
+static int start(struct drxk_state *state, s32 offset_freq,
+ s32 intermediate_frequency)
{
int status = -EINVAL;
- u16 IFreqkHz;
- s32 OffsetkHz = offsetFreq / 1000;
+ u16 i_freqk_hz;
+ s32 offsetk_hz = offset_freq / 1000;
dprintk(1, "\n");
- if (state->m_DrxkState != DRXK_STOPPED &&
- state->m_DrxkState != DRXK_DTV_STARTED)
+ if (state->m_drxk_state != DRXK_STOPPED &&
+ state->m_drxk_state != DRXK_DTV_STARTED)
goto error;
- state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
+ state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
- if (IntermediateFrequency < 0) {
- state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
- IntermediateFrequency = -IntermediateFrequency;
+ if (intermediate_frequency < 0) {
+ state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
+ intermediate_frequency = -intermediate_frequency;
}
- switch (state->m_OperationMode) {
+ switch (state->m_operation_mode) {
case OM_QAM_ITU_A:
case OM_QAM_ITU_C:
- IFreqkHz = (IntermediateFrequency / 1000);
- status = SetQAM(state, IFreqkHz, OffsetkHz);
+ i_freqk_hz = (intermediate_frequency / 1000);
+ status = set_qam(state, i_freqk_hz, offsetk_hz);
if (status < 0)
goto error;
- state->m_DrxkState = DRXK_DTV_STARTED;
+ state->m_drxk_state = DRXK_DTV_STARTED;
break;
case OM_DVBT:
- IFreqkHz = (IntermediateFrequency / 1000);
- status = MPEGTSStop(state);
+ i_freqk_hz = (intermediate_frequency / 1000);
+ status = mpegts_stop(state);
if (status < 0)
goto error;
- status = SetDVBT(state, IFreqkHz, OffsetkHz);
+ status = set_dvbt(state, i_freqk_hz, offsetk_hz);
if (status < 0)
goto error;
- status = DVBTStart(state);
+ status = dvbt_start(state);
if (status < 0)
goto error;
- state->m_DrxkState = DRXK_DTV_STARTED;
+ state->m_drxk_state = DRXK_DTV_STARTED;
break;
default:
break;
}
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int ShutDown(struct drxk_state *state)
+static int shut_down(struct drxk_state *state)
{
dprintk(1, "\n");
- MPEGTSStop(state);
+ mpegts_stop(state);
return 0;
}
-static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
{
int status = -EINVAL;
dprintk(1, "\n");
- if (pLockStatus == NULL)
+ if (p_lock_status == NULL)
goto error;
- *pLockStatus = NOT_LOCKED;
+ *p_lock_status = NOT_LOCKED;
/* define the SCU command code */
- switch (state->m_OperationMode) {
+ switch (state->m_operation_mode) {
case OM_QAM_ITU_A:
case OM_QAM_ITU_B:
case OM_QAM_ITU_C:
- status = GetQAMLockStatus(state, pLockStatus);
+ status = get_qam_lock_status(state, p_lock_status);
break;
case OM_DVBT:
- status = GetDVBTLockStatus(state, pLockStatus);
+ status = get_dvbt_lock_status(state, p_lock_status);
break;
default:
break;
}
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int MPEGTSStart(struct drxk_state *state)
+static int mpegts_start(struct drxk_state *state)
{
int status;
- u16 fecOcSncMode = 0;
+ u16 fec_oc_snc_mode = 0;
/* Allow OC to sync again */
- status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
+ status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
if (status < 0)
goto error;
- fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
- status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
+ fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
+ status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
if (status < 0)
goto error;
status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int MPEGTSDtoInit(struct drxk_state *state)
+static int mpegts_dto_init(struct drxk_state *state)
{
int status;
@@ -2040,68 +1979,68 @@
status = write16(state, FEC_OC_SNC_HWM__A, 12);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int MPEGTSDtoSetup(struct drxk_state *state,
- enum OperationMode oMode)
+static int mpegts_dto_setup(struct drxk_state *state,
+ enum operation_mode o_mode)
{
int status;
- u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
- u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
- u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
- u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
- u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
- u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
- u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
- u16 fecOcTmdMode = 0;
- u16 fecOcTmdIntUpdRate = 0;
- u32 maxBitRate = 0;
- bool staticCLK = false;
+ u16 fec_oc_reg_mode = 0; /* FEC_OC_MODE register value */
+ u16 fec_oc_reg_ipr_mode = 0; /* FEC_OC_IPR_MODE register value */
+ u16 fec_oc_dto_mode = 0; /* FEC_OC_IPR_INVERT register value */
+ u16 fec_oc_fct_mode = 0; /* FEC_OC_IPR_INVERT register value */
+ u16 fec_oc_dto_period = 2; /* FEC_OC_IPR_INVERT register value */
+ u16 fec_oc_dto_burst_len = 188; /* FEC_OC_IPR_INVERT register value */
+ u32 fec_oc_rcn_ctl_rate = 0; /* FEC_OC_IPR_INVERT register value */
+ u16 fec_oc_tmd_mode = 0;
+ u16 fec_oc_tmd_int_upd_rate = 0;
+ u32 max_bit_rate = 0;
+ bool static_clk = false;
dprintk(1, "\n");
/* Check insertion of the Reed-Solomon parity bytes */
- status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
+ status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
if (status < 0)
goto error;
- status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
+ status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
if (status < 0)
goto error;
- fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
- fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
- if (state->m_insertRSByte == true) {
+ fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
+ fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
+ if (state->m_insert_rs_byte == true) {
/* enable parity symbol forward */
- fecOcRegMode |= FEC_OC_MODE_PARITY__M;
+ fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
/* MVAL disable during parity bytes */
- fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
+ fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
/* TS burst length to 204 */
- fecOcDtoBurstLen = 204;
+ fec_oc_dto_burst_len = 204;
}
/* Check serial or parrallel output */
- fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
- if (state->m_enableParallel == false) {
+ fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
+ if (state->m_enable_parallel == false) {
/* MPEG data output is serial -> set ipr_mode[0] */
- fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
+ fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
}
- switch (oMode) {
+ switch (o_mode) {
case OM_DVBT:
- maxBitRate = state->m_DVBTBitrate;
- fecOcTmdMode = 3;
- fecOcRcnCtlRate = 0xC00000;
- staticCLK = state->m_DVBTStaticCLK;
+ max_bit_rate = state->m_dvbt_bitrate;
+ fec_oc_tmd_mode = 3;
+ fec_oc_rcn_ctl_rate = 0xC00000;
+ static_clk = state->m_dvbt_static_clk;
break;
case OM_QAM_ITU_A: /* fallthrough */
case OM_QAM_ITU_C:
- fecOcTmdMode = 0x0004;
- fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
- maxBitRate = state->m_DVBCBitrate;
- staticCLK = state->m_DVBCStaticCLK;
+ fec_oc_tmd_mode = 0x0004;
+ fec_oc_rcn_ctl_rate = 0xD2B4EE; /* good for >63 Mb/s */
+ max_bit_rate = state->m_dvbc_bitrate;
+ static_clk = state->m_dvbc_static_clk;
break;
default:
status = -EINVAL;
@@ -2110,83 +2049,84 @@
goto error;
/* Configure DTO's */
- if (staticCLK) {
- u32 bitRate = 0;
+ if (static_clk) {
+ u32 bit_rate = 0;
/* Rational DTO for MCLK source (static MCLK rate),
Dynamic DTO for optimal grouping
(avoid intra-packet gaps),
DTO offset enable to sync TS burst with MSTRT */
- fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
+ fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
- fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
+ fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
FEC_OC_FCT_MODE_VIRT_ENA__M);
/* Check user defined bitrate */
- bitRate = maxBitRate;
- if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
- bitRate = 75900000UL;
+ bit_rate = max_bit_rate;
+ if (bit_rate > 75900000UL) { /* max is 75.9 Mb/s */
+ bit_rate = 75900000UL;
}
/* Rational DTO period:
dto_period = (Fsys / bitrate) - 2
- Result should be floored,
+ result should be floored,
to make sure >= requested bitrate
*/
- fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
- * 1000) / bitRate);
- if (fecOcDtoPeriod <= 2)
- fecOcDtoPeriod = 0;
+ fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
+ * 1000) / bit_rate);
+ if (fec_oc_dto_period <= 2)
+ fec_oc_dto_period = 0;
else
- fecOcDtoPeriod -= 2;
- fecOcTmdIntUpdRate = 8;
+ fec_oc_dto_period -= 2;
+ fec_oc_tmd_int_upd_rate = 8;
} else {
- /* (commonAttr->staticCLK == false) => dynamic mode */
- fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
- fecOcFctMode = FEC_OC_FCT_MODE__PRE;
- fecOcTmdIntUpdRate = 5;
+ /* (commonAttr->static_clk == false) => dynamic mode */
+ fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
+ fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
+ fec_oc_tmd_int_upd_rate = 5;
}
/* Write appropriate registers with requested configuration */
- status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
+ status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
if (status < 0)
goto error;
- status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
+ status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
if (status < 0)
goto error;
- status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
+ status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
if (status < 0)
goto error;
- status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
+ status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
if (status < 0)
goto error;
- status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
+ status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
if (status < 0)
goto error;
- status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
+ status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
if (status < 0)
goto error;
/* Rate integration settings */
- status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
+ status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
if (status < 0)
goto error;
- status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
+ status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
+ fec_oc_tmd_int_upd_rate);
if (status < 0)
goto error;
- status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
+ status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int MPEGTSConfigurePolarity(struct drxk_state *state)
+static int mpegts_configure_polarity(struct drxk_state *state)
{
- u16 fecOcRegIprInvert = 0;
+ u16 fec_oc_reg_ipr_invert = 0;
/* Data mask for the output data byte */
- u16 InvertDataMask =
+ u16 invert_data_mask =
FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
@@ -2195,40 +2135,40 @@
dprintk(1, "\n");
/* Control selective inversion of output bits */
- fecOcRegIprInvert &= (~(InvertDataMask));
- if (state->m_invertDATA == true)
- fecOcRegIprInvert |= InvertDataMask;
- fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
- if (state->m_invertERR == true)
- fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
- fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
- if (state->m_invertSTR == true)
- fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
- fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
- if (state->m_invertVAL == true)
- fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
- fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
- if (state->m_invertCLK == true)
- fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
+ fec_oc_reg_ipr_invert &= (~(invert_data_mask));
+ if (state->m_invert_data == true)
+ fec_oc_reg_ipr_invert |= invert_data_mask;
+ fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
+ if (state->m_invert_err == true)
+ fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
+ fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
+ if (state->m_invert_str == true)
+ fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
+ fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
+ if (state->m_invert_val == true)
+ fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
+ fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
+ if (state->m_invert_clk == true)
+ fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
- return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
+ return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
}
#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
-static int SetAgcRf(struct drxk_state *state,
- struct SCfgAgc *pAgcCfg, bool isDTV)
+static int set_agc_rf(struct drxk_state *state,
+ struct s_cfg_agc *p_agc_cfg, bool is_dtv)
{
int status = -EINVAL;
u16 data = 0;
- struct SCfgAgc *pIfAgcSettings;
+ struct s_cfg_agc *p_if_agc_settings;
dprintk(1, "\n");
- if (pAgcCfg == NULL)
+ if (p_agc_cfg == NULL)
goto error;
- switch (pAgcCfg->ctrlMode) {
+ switch (p_agc_cfg->ctrl_mode) {
case DRXK_AGC_CTRL_AUTO:
/* Enable RF AGC DAC */
status = read16(state, IQM_AF_STDBY__A, &data);
@@ -2246,7 +2186,7 @@
data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
/* Polarity */
- if (state->m_RfAgcPol)
+ if (state->m_rf_agc_pol)
data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
else
data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
@@ -2260,7 +2200,7 @@
goto error;
data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
- data |= (~(pAgcCfg->speed <<
+ data |= (~(p_agc_cfg->speed <<
SCU_RAM_AGC_KI_RED_RAGC_RED__B)
& SCU_RAM_AGC_KI_RED_RAGC_RED__M);
@@ -2268,30 +2208,34 @@
if (status < 0)
goto error;
- if (IsDVBT(state))
- pIfAgcSettings = &state->m_dvbtIfAgcCfg;
- else if (IsQAM(state))
- pIfAgcSettings = &state->m_qamIfAgcCfg;
+ if (is_dvbt(state))
+ p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
+ else if (is_qam(state))
+ p_if_agc_settings = &state->m_qam_if_agc_cfg;
else
- pIfAgcSettings = &state->m_atvIfAgcCfg;
- if (pIfAgcSettings == NULL) {
+ p_if_agc_settings = &state->m_atv_if_agc_cfg;
+ if (p_if_agc_settings == NULL) {
status = -EINVAL;
goto error;
}
/* Set TOP, only if IF-AGC is in AUTO mode */
- if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
+ if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
+ status = write16(state,
+ SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+ p_agc_cfg->top);
if (status < 0)
goto error;
/* Cut-Off current */
- status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
+ status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
+ p_agc_cfg->cut_off_current);
if (status < 0)
goto error;
/* Max. output level */
- status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
+ status = write16(state, SCU_RAM_AGC_RF_MAX__A,
+ p_agc_cfg->max_output_level);
if (status < 0)
goto error;
@@ -2312,7 +2256,7 @@
if (status < 0)
goto error;
data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
- if (state->m_RfAgcPol)
+ if (state->m_rf_agc_pol)
data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
else
data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
@@ -2326,7 +2270,8 @@
goto error;
/* Write value to output pin */
- status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
+ status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
+ p_agc_cfg->output_level);
if (status < 0)
goto error;
break;
@@ -2357,22 +2302,22 @@
}
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
-static int SetAgcIf(struct drxk_state *state,
- struct SCfgAgc *pAgcCfg, bool isDTV)
+static int set_agc_if(struct drxk_state *state,
+ struct s_cfg_agc *p_agc_cfg, bool is_dtv)
{
u16 data = 0;
int status = 0;
- struct SCfgAgc *pRfAgcSettings;
+ struct s_cfg_agc *p_rf_agc_settings;
dprintk(1, "\n");
- switch (pAgcCfg->ctrlMode) {
+ switch (p_agc_cfg->ctrl_mode) {
case DRXK_AGC_CTRL_AUTO:
/* Enable IF AGC DAC */
@@ -2392,7 +2337,7 @@
data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
/* Polarity */
- if (state->m_IfAgcPol)
+ if (state->m_if_agc_pol)
data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
else
data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
@@ -2405,7 +2350,7 @@
if (status < 0)
goto error;
data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
- data |= (~(pAgcCfg->speed <<
+ data |= (~(p_agc_cfg->speed <<
SCU_RAM_AGC_KI_RED_IAGC_RED__B)
& SCU_RAM_AGC_KI_RED_IAGC_RED__M);
@@ -2413,14 +2358,15 @@
if (status < 0)
goto error;
- if (IsQAM(state))
- pRfAgcSettings = &state->m_qamRfAgcCfg;
+ if (is_qam(state))
+ p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
else
- pRfAgcSettings = &state->m_atvRfAgcCfg;
- if (pRfAgcSettings == NULL)
+ p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
+ if (p_rf_agc_settings == NULL)
return -1;
/* Restore TOP */
- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
+ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+ p_rf_agc_settings->top);
if (status < 0)
goto error;
break;
@@ -2444,7 +2390,7 @@
data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
/* Polarity */
- if (state->m_IfAgcPol)
+ if (state->m_if_agc_pol)
data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
else
data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
@@ -2453,7 +2399,8 @@
goto error;
/* Write value to output pin */
- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
+ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+ p_agc_cfg->output_level);
if (status < 0)
goto error;
break;
@@ -2478,176 +2425,181 @@
if (status < 0)
goto error;
break;
- } /* switch (agcSettingsIf->ctrlMode) */
+ } /* switch (agcSettingsIf->ctrl_mode) */
/* always set the top to support
configurations without if-loop */
- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
+ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int GetQAMSignalToNoise(struct drxk_state *state,
- s32 *pSignalToNoise)
+static int get_qam_signal_to_noise(struct drxk_state *state,
+ s32 *p_signal_to_noise)
{
int status = 0;
- u16 qamSlErrPower = 0; /* accum. error between
+ u16 qam_sl_err_power = 0; /* accum. error between
raw and sliced symbols */
- u32 qamSlSigPower = 0; /* used for MER, depends of
+ u32 qam_sl_sig_power = 0; /* used for MER, depends of
QAM modulation */
- u32 qamSlMer = 0; /* QAM MER */
+ u32 qam_sl_mer = 0; /* QAM MER */
dprintk(1, "\n");
/* MER calculation */
/* get the register value needed for MER */
- status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
+ status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
if (status < 0) {
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return -EINVAL;
}
switch (state->props.modulation) {
case QAM_16:
- qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
+ qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
break;
case QAM_32:
- qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
+ qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
break;
case QAM_64:
- qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
+ qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
break;
case QAM_128:
- qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
+ qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
break;
default:
case QAM_256:
- qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
+ qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
break;
}
- if (qamSlErrPower > 0) {
- qamSlMer = Log10Times100(qamSlSigPower) -
- Log10Times100((u32) qamSlErrPower);
+ if (qam_sl_err_power > 0) {
+ qam_sl_mer = log10times100(qam_sl_sig_power) -
+ log10times100((u32) qam_sl_err_power);
}
- *pSignalToNoise = qamSlMer;
+ *p_signal_to_noise = qam_sl_mer;
return status;
}
-static int GetDVBTSignalToNoise(struct drxk_state *state,
- s32 *pSignalToNoise)
+static int get_dvbt_signal_to_noise(struct drxk_state *state,
+ s32 *p_signal_to_noise)
{
int status;
- u16 regData = 0;
- u32 EqRegTdSqrErrI = 0;
- u32 EqRegTdSqrErrQ = 0;
- u16 EqRegTdSqrErrExp = 0;
- u16 EqRegTdTpsPwrOfs = 0;
- u16 EqRegTdReqSmbCnt = 0;
- u32 tpsCnt = 0;
- u32 SqrErrIQ = 0;
+ u16 reg_data = 0;
+ u32 eq_reg_td_sqr_err_i = 0;
+ u32 eq_reg_td_sqr_err_q = 0;
+ u16 eq_reg_td_sqr_err_exp = 0;
+ u16 eq_reg_td_tps_pwr_ofs = 0;
+ u16 eq_reg_td_req_smb_cnt = 0;
+ u32 tps_cnt = 0;
+ u32 sqr_err_iq = 0;
u32 a = 0;
u32 b = 0;
u32 c = 0;
- u32 iMER = 0;
- u16 transmissionParams = 0;
+ u32 i_mer = 0;
+ u16 transmission_params = 0;
dprintk(1, "\n");
- status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
+ status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
+ &eq_reg_td_tps_pwr_ofs);
if (status < 0)
goto error;
- status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
+ status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
+ &eq_reg_td_req_smb_cnt);
if (status < 0)
goto error;
- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
+ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
+ &eq_reg_td_sqr_err_exp);
if (status < 0)
goto error;
- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, ®Data);
+ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
+ ®_data);
if (status < 0)
goto error;
/* Extend SQR_ERR_I operational range */
- EqRegTdSqrErrI = (u32) regData;
- if ((EqRegTdSqrErrExp > 11) &&
- (EqRegTdSqrErrI < 0x00000FFFUL)) {
- EqRegTdSqrErrI += 0x00010000UL;
+ eq_reg_td_sqr_err_i = (u32) reg_data;
+ if ((eq_reg_td_sqr_err_exp > 11) &&
+ (eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
+ eq_reg_td_sqr_err_i += 0x00010000UL;
}
- status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®Data);
+ status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, ®_data);
if (status < 0)
goto error;
/* Extend SQR_ERR_Q operational range */
- EqRegTdSqrErrQ = (u32) regData;
- if ((EqRegTdSqrErrExp > 11) &&
- (EqRegTdSqrErrQ < 0x00000FFFUL))
- EqRegTdSqrErrQ += 0x00010000UL;
+ eq_reg_td_sqr_err_q = (u32) reg_data;
+ if ((eq_reg_td_sqr_err_exp > 11) &&
+ (eq_reg_td_sqr_err_q < 0x00000FFFUL))
+ eq_reg_td_sqr_err_q += 0x00010000UL;
- status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
+ status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
+ &transmission_params);
if (status < 0)
goto error;
/* Check input data for MER */
/* MER calculation (in 0.1 dB) without math.h */
- if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
- iMER = 0;
- else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
+ if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
+ i_mer = 0;
+ else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
/* No error at all, this must be the HW reset value
* Apparently no first measurement yet
* Set MER to 0.0 */
- iMER = 0;
+ i_mer = 0;
} else {
- SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
- EqRegTdSqrErrExp;
- if ((transmissionParams &
+ sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
+ eq_reg_td_sqr_err_exp;
+ if ((transmission_params &
OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
== OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
- tpsCnt = 17;
+ tps_cnt = 17;
else
- tpsCnt = 68;
+ tps_cnt = 68;
/* IMER = 100 * log10 (x)
- where x = (EqRegTdTpsPwrOfs^2 *
- EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
+ where x = (eq_reg_td_tps_pwr_ofs^2 *
+ eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
=> IMER = a + b -c
- where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
- b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
- c = 100 * log10 (SqrErrIQ)
+ where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
+ b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
+ c = 100 * log10 (sqr_err_iq)
*/
/* log(x) x = 9bits * 9bits->18 bits */
- a = Log10Times100(EqRegTdTpsPwrOfs *
- EqRegTdTpsPwrOfs);
+ a = log10times100(eq_reg_td_tps_pwr_ofs *
+ eq_reg_td_tps_pwr_ofs);
/* log(x) x = 16bits * 7bits->23 bits */
- b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
+ b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
/* log(x) x = (16bits + 16bits) << 15 ->32 bits */
- c = Log10Times100(SqrErrIQ);
+ c = log10times100(sqr_err_iq);
- iMER = a + b - c;
+ i_mer = a + b - c;
}
- *pSignalToNoise = iMER;
+ *p_signal_to_noise = i_mer;
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
+static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
{
dprintk(1, "\n");
- *pSignalToNoise = 0;
- switch (state->m_OperationMode) {
+ *p_signal_to_noise = 0;
+ switch (state->m_operation_mode) {
case OM_DVBT:
- return GetDVBTSignalToNoise(state, pSignalToNoise);
+ return get_dvbt_signal_to_noise(state, p_signal_to_noise);
case OM_QAM_ITU_A:
case OM_QAM_ITU_C:
- return GetQAMSignalToNoise(state, pSignalToNoise);
+ return get_qam_signal_to_noise(state, p_signal_to_noise);
default:
break;
}
@@ -2655,7 +2607,7 @@
}
#if 0
-static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
+static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
{
/* SNR Values for quasi errorfree reception rom Nordig 2.2 */
int status = 0;
@@ -2680,102 +2632,104 @@
225, /* 64-QAM 7/8 */
};
- *pQuality = 0;
+ *p_quality = 0;
do {
- s32 SignalToNoise = 0;
- u16 Constellation = 0;
- u16 CodeRate = 0;
- u32 SignalToNoiseRel;
- u32 BERQuality;
+ s32 signal_to_noise = 0;
+ u16 constellation = 0;
+ u16 code_rate = 0;
+ u32 signal_to_noise_rel;
+ u32 ber_quality;
- status = GetDVBTSignalToNoise(state, &SignalToNoise);
+ status = get_dvbt_signal_to_noise(state, &signal_to_noise);
if (status < 0)
break;
- status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
+ status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
+ &constellation);
if (status < 0)
break;
- Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
+ constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
- status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
+ status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
+ &code_rate);
if (status < 0)
break;
- CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
+ code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
- if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
- CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
+ if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
+ code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
break;
- SignalToNoiseRel = SignalToNoise -
- QE_SN[Constellation * 5 + CodeRate];
- BERQuality = 100;
+ signal_to_noise_rel = signal_to_noise -
+ QE_SN[constellation * 5 + code_rate];
+ ber_quality = 100;
- if (SignalToNoiseRel < -70)
- *pQuality = 0;
- else if (SignalToNoiseRel < 30)
- *pQuality = ((SignalToNoiseRel + 70) *
- BERQuality) / 100;
+ if (signal_to_noise_rel < -70)
+ *p_quality = 0;
+ else if (signal_to_noise_rel < 30)
+ *p_quality = ((signal_to_noise_rel + 70) *
+ ber_quality) / 100;
else
- *pQuality = BERQuality;
+ *p_quality = ber_quality;
} while (0);
return 0;
};
-static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
+static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
{
int status = 0;
- *pQuality = 0;
+ *p_quality = 0;
dprintk(1, "\n");
do {
- u32 SignalToNoise = 0;
- u32 BERQuality = 100;
- u32 SignalToNoiseRel = 0;
+ u32 signal_to_noise = 0;
+ u32 ber_quality = 100;
+ u32 signal_to_noise_rel = 0;
- status = GetQAMSignalToNoise(state, &SignalToNoise);
+ status = get_qam_signal_to_noise(state, &signal_to_noise);
if (status < 0)
break;
switch (state->props.modulation) {
case QAM_16:
- SignalToNoiseRel = SignalToNoise - 200;
+ signal_to_noise_rel = signal_to_noise - 200;
break;
case QAM_32:
- SignalToNoiseRel = SignalToNoise - 230;
+ signal_to_noise_rel = signal_to_noise - 230;
break; /* Not in NorDig */
case QAM_64:
- SignalToNoiseRel = SignalToNoise - 260;
+ signal_to_noise_rel = signal_to_noise - 260;
break;
case QAM_128:
- SignalToNoiseRel = SignalToNoise - 290;
+ signal_to_noise_rel = signal_to_noise - 290;
break;
default:
case QAM_256:
- SignalToNoiseRel = SignalToNoise - 320;
+ signal_to_noise_rel = signal_to_noise - 320;
break;
}
- if (SignalToNoiseRel < -70)
- *pQuality = 0;
- else if (SignalToNoiseRel < 30)
- *pQuality = ((SignalToNoiseRel + 70) *
- BERQuality) / 100;
+ if (signal_to_noise_rel < -70)
+ *p_quality = 0;
+ else if (signal_to_noise_rel < 30)
+ *p_quality = ((signal_to_noise_rel + 70) *
+ ber_quality) / 100;
else
- *pQuality = BERQuality;
+ *p_quality = ber_quality;
} while (0);
return status;
}
-static int GetQuality(struct drxk_state *state, s32 *pQuality)
+static int get_quality(struct drxk_state *state, s32 *p_quality)
{
dprintk(1, "\n");
- switch (state->m_OperationMode) {
+ switch (state->m_operation_mode) {
case OM_DVBT:
- return GetDVBTQuality(state, pQuality);
+ return get_dvbt_quality(state, p_quality);
case OM_QAM_ITU_A:
- return GetDVBCQuality(state, pQuality);
+ return get_dvbc_quality(state, p_quality);
default:
break;
}
@@ -2797,65 +2751,68 @@
#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
-static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
+static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
{
int status = -EINVAL;
dprintk(1, "\n");
- if (state->m_DrxkState == DRXK_UNINITIALIZED)
+ if (state->m_drxk_state == DRXK_UNINITIALIZED)
return 0;
- if (state->m_DrxkState == DRXK_POWERED_DOWN)
+ if (state->m_drxk_state == DRXK_POWERED_DOWN)
goto error;
if (state->no_i2c_bridge)
return 0;
- status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
+ status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
+ SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
if (status < 0)
goto error;
- if (bEnableBridge) {
- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
+ if (b_enable_bridge) {
+ status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+ SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
if (status < 0)
goto error;
} else {
- status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
+ status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+ SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
if (status < 0)
goto error;
}
- status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
+ status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int SetPreSaw(struct drxk_state *state,
- struct SCfgPreSaw *pPreSawCfg)
+static int set_pre_saw(struct drxk_state *state,
+ struct s_cfg_pre_saw *p_pre_saw_cfg)
{
int status = -EINVAL;
dprintk(1, "\n");
- if ((pPreSawCfg == NULL)
- || (pPreSawCfg->reference > IQM_AF_PDREF__M))
+ if ((p_pre_saw_cfg == NULL)
+ || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
goto error;
- status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
+ status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
- u16 romOffset, u16 nrOfElements, u32 timeOut)
+static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
+ u16 rom_offset, u16 nr_of_elements, u32 time_out)
{
- u16 blStatus = 0;
- u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
- u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
+ u16 bl_status = 0;
+ u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
+ u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
int status;
unsigned long end;
@@ -2871,44 +2828,44 @@
status = write16(state, SIO_BL_TGT_ADDR__A, offset);
if (status < 0)
goto error;
- status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
+ status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
if (status < 0)
goto error;
- status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
+ status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
if (status < 0)
goto error;
status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
if (status < 0)
goto error;
- end = jiffies + msecs_to_jiffies(timeOut);
+ end = jiffies + msecs_to_jiffies(time_out);
do {
- status = read16(state, SIO_BL_STATUS__A, &blStatus);
+ status = read16(state, SIO_BL_STATUS__A, &bl_status);
if (status < 0)
goto error;
- } while ((blStatus == 0x1) && time_is_after_jiffies(end));
- if (blStatus == 0x1) {
- printk(KERN_ERR "drxk: SIO not ready\n");
+ } while ((bl_status == 0x1) && time_is_after_jiffies(end));
+ if (bl_status == 0x1) {
+ pr_err("SIO not ready\n");
status = -EINVAL;
goto error2;
}
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
error2:
mutex_unlock(&state->mutex);
return status;
}
-static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
+static int adc_sync_measurement(struct drxk_state *state, u16 *count)
{
u16 data = 0;
int status;
dprintk(1, "\n");
- /* Start measurement */
+ /* start measurement */
status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
if (status < 0)
goto error;
@@ -2935,42 +2892,42 @@
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int ADCSynchronization(struct drxk_state *state)
+static int adc_synchronization(struct drxk_state *state)
{
u16 count = 0;
int status;
dprintk(1, "\n");
- status = ADCSyncMeasurement(state, &count);
+ status = adc_sync_measurement(state, &count);
if (status < 0)
goto error;
if (count == 1) {
/* Try sampling on a diffrent edge */
- u16 clkNeg = 0;
+ u16 clk_neg = 0;
- status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
+ status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
if (status < 0)
goto error;
- if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
+ if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
- clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
- clkNeg |=
+ clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
+ clk_neg |=
IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
} else {
- clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
- clkNeg |=
+ clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
+ clk_neg |=
IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
}
- status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
+ status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
if (status < 0)
goto error;
- status = ADCSyncMeasurement(state, &count);
+ status = adc_sync_measurement(state, &count);
if (status < 0)
goto error;
}
@@ -2979,25 +2936,25 @@
status = -EINVAL;
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int SetFrequencyShifter(struct drxk_state *state,
- u16 intermediateFreqkHz,
- s32 tunerFreqOffset, bool isDTV)
+static int set_frequency_shifter(struct drxk_state *state,
+ u16 intermediate_freqk_hz,
+ s32 tuner_freq_offset, bool is_dtv)
{
- bool selectPosImage = false;
- u32 rfFreqResidual = tunerFreqOffset;
- u32 fmFrequencyShift = 0;
- bool tunerMirror = !state->m_bMirrorFreqSpect;
- u32 adcFreq;
- bool adcFlip;
+ bool select_pos_image = false;
+ u32 rf_freq_residual = tuner_freq_offset;
+ u32 fm_frequency_shift = 0;
+ bool tuner_mirror = !state->m_b_mirror_freq_spect;
+ u32 adc_freq;
+ bool adc_flip;
int status;
- u32 ifFreqActual;
- u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
- u32 frequencyShift;
- bool imageToSelect;
+ u32 if_freq_actual;
+ u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
+ u32 frequency_shift;
+ bool image_to_select;
dprintk(1, "\n");
@@ -3005,121 +2962,125 @@
Program frequency shifter
No need to account for mirroring on RF
*/
- if (isDTV) {
- if ((state->m_OperationMode == OM_QAM_ITU_A) ||
- (state->m_OperationMode == OM_QAM_ITU_C) ||
- (state->m_OperationMode == OM_DVBT))
- selectPosImage = true;
+ if (is_dtv) {
+ if ((state->m_operation_mode == OM_QAM_ITU_A) ||
+ (state->m_operation_mode == OM_QAM_ITU_C) ||
+ (state->m_operation_mode == OM_DVBT))
+ select_pos_image = true;
else
- selectPosImage = false;
+ select_pos_image = false;
}
- if (tunerMirror)
+ if (tuner_mirror)
/* tuner doesn't mirror */
- ifFreqActual = intermediateFreqkHz +
- rfFreqResidual + fmFrequencyShift;
+ if_freq_actual = intermediate_freqk_hz +
+ rf_freq_residual + fm_frequency_shift;
else
/* tuner mirrors */
- ifFreqActual = intermediateFreqkHz -
- rfFreqResidual - fmFrequencyShift;
- if (ifFreqActual > samplingFrequency / 2) {
+ if_freq_actual = intermediate_freqk_hz -
+ rf_freq_residual - fm_frequency_shift;
+ if (if_freq_actual > sampling_frequency / 2) {
/* adc mirrors */
- adcFreq = samplingFrequency - ifFreqActual;
- adcFlip = true;
+ adc_freq = sampling_frequency - if_freq_actual;
+ adc_flip = true;
} else {
/* adc doesn't mirror */
- adcFreq = ifFreqActual;
- adcFlip = false;
+ adc_freq = if_freq_actual;
+ adc_flip = false;
}
- frequencyShift = adcFreq;
- imageToSelect = state->m_rfmirror ^ tunerMirror ^
- adcFlip ^ selectPosImage;
- state->m_IqmFsRateOfs =
- Frac28a((frequencyShift), samplingFrequency);
+ frequency_shift = adc_freq;
+ image_to_select = state->m_rfmirror ^ tuner_mirror ^
+ adc_flip ^ select_pos_image;
+ state->m_iqm_fs_rate_ofs =
+ Frac28a((frequency_shift), sampling_frequency);
- if (imageToSelect)
- state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
+ if (image_to_select)
+ state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
/* Program frequency shifter with tuner offset compensation */
- /* frequencyShift += tunerFreqOffset; TODO */
+ /* frequency_shift += tuner_freq_offset; TODO */
status = write32(state, IQM_FS_RATE_OFS_LO__A,
- state->m_IqmFsRateOfs);
+ state->m_iqm_fs_rate_ofs);
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int InitAGC(struct drxk_state *state, bool isDTV)
+static int init_agc(struct drxk_state *state, bool is_dtv)
{
- u16 ingainTgt = 0;
- u16 ingainTgtMin = 0;
- u16 ingainTgtMax = 0;
- u16 clpCyclen = 0;
- u16 clpSumMin = 0;
- u16 clpDirTo = 0;
- u16 snsSumMin = 0;
- u16 snsSumMax = 0;
- u16 clpSumMax = 0;
- u16 snsDirTo = 0;
- u16 kiInnergainMin = 0;
- u16 ifIaccuHiTgt = 0;
- u16 ifIaccuHiTgtMin = 0;
- u16 ifIaccuHiTgtMax = 0;
+ u16 ingain_tgt = 0;
+ u16 ingain_tgt_min = 0;
+ u16 ingain_tgt_max = 0;
+ u16 clp_cyclen = 0;
+ u16 clp_sum_min = 0;
+ u16 clp_dir_to = 0;
+ u16 sns_sum_min = 0;
+ u16 sns_sum_max = 0;
+ u16 clp_sum_max = 0;
+ u16 sns_dir_to = 0;
+ u16 ki_innergain_min = 0;
+ u16 if_iaccu_hi_tgt = 0;
+ u16 if_iaccu_hi_tgt_min = 0;
+ u16 if_iaccu_hi_tgt_max = 0;
u16 data = 0;
- u16 fastClpCtrlDelay = 0;
- u16 clpCtrlMode = 0;
+ u16 fast_clp_ctrl_delay = 0;
+ u16 clp_ctrl_mode = 0;
int status = 0;
dprintk(1, "\n");
/* Common settings */
- snsSumMax = 1023;
- ifIaccuHiTgtMin = 2047;
- clpCyclen = 500;
- clpSumMax = 1023;
+ sns_sum_max = 1023;
+ if_iaccu_hi_tgt_min = 2047;
+ clp_cyclen = 500;
+ clp_sum_max = 1023;
/* AGCInit() not available for DVBT; init done in microcode */
- if (!IsQAM(state)) {
- printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
+ if (!is_qam(state)) {
+ pr_err("%s: mode %d is not DVB-C\n",
+ __func__, state->m_operation_mode);
return -EINVAL;
}
/* FIXME: Analog TV AGC require different settings */
/* Standard specific settings */
- clpSumMin = 8;
- clpDirTo = (u16) -9;
- clpCtrlMode = 0;
- snsSumMin = 8;
- snsDirTo = (u16) -9;
- kiInnergainMin = (u16) -1030;
- ifIaccuHiTgtMax = 0x2380;
- ifIaccuHiTgt = 0x2380;
- ingainTgtMin = 0x0511;
- ingainTgt = 0x0511;
- ingainTgtMax = 5119;
- fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
+ clp_sum_min = 8;
+ clp_dir_to = (u16) -9;
+ clp_ctrl_mode = 0;
+ sns_sum_min = 8;
+ sns_dir_to = (u16) -9;
+ ki_innergain_min = (u16) -1030;
+ if_iaccu_hi_tgt_max = 0x2380;
+ if_iaccu_hi_tgt = 0x2380;
+ ingain_tgt_min = 0x0511;
+ ingain_tgt = 0x0511;
+ ingain_tgt_max = 5119;
+ fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
- status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
+ status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
+ fast_clp_ctrl_delay);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
+ status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
+ status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
+ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
+ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
+ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
+ if_iaccu_hi_tgt_min);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
+ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+ if_iaccu_hi_tgt_max);
if (status < 0)
goto error;
status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
@@ -3134,20 +3095,22 @@
status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
+ status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
+ status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
+ status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
+ ki_innergain_min);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
+ status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
+ if_iaccu_hi_tgt);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
+ status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
if (status < 0)
goto error;
@@ -3164,16 +3127,16 @@
status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
+ status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
+ status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
+ status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
+ status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
if (status < 0)
goto error;
status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
@@ -3233,38 +3196,39 @@
status = write16(state, SCU_RAM_AGC_KI__A, data);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
+static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
{
int status;
dprintk(1, "\n");
- if (packetErr == NULL)
+ if (packet_err == NULL)
status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
else
- status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
+ status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
+ packet_err);
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int DVBTScCommand(struct drxk_state *state,
+static int dvbt_sc_command(struct drxk_state *state,
u16 cmd, u16 subcmd,
u16 param0, u16 param1, u16 param2,
u16 param3, u16 param4)
{
- u16 curCmd = 0;
- u16 errCode = 0;
- u16 retryCnt = 0;
- u16 scExec = 0;
+ u16 cur_cmd = 0;
+ u16 err_code = 0;
+ u16 retry_cnt = 0;
+ u16 sc_exec = 0;
int status;
dprintk(1, "\n");
- status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
- if (scExec != 1) {
+ status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
+ if (sc_exec != 1) {
/* SC is not running */
status = -EINVAL;
}
@@ -3272,13 +3236,13 @@
goto error;
/* Wait until sc is ready to receive command */
- retryCnt = 0;
+ retry_cnt = 0;
do {
- msleep(1);
- status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
- retryCnt++;
- } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
- if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
+ usleep_range(1000, 2000);
+ status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
+ retry_cnt++;
+ } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
+ if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
goto error;
/* Write sub-command */
@@ -3324,18 +3288,18 @@
goto error;
/* Wait until sc is ready processing command */
- retryCnt = 0;
+ retry_cnt = 0;
do {
- msleep(1);
- status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
- retryCnt++;
- } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
- if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
+ usleep_range(1000, 2000);
+ status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
+ retry_cnt++;
+ } while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
+ if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
goto error;
/* Check for illegal cmd */
- status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
- if (errCode == 0xFFFF) {
+ status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
+ if (err_code == 0xFFFF) {
/* illegal command */
status = -EINVAL;
}
@@ -3367,23 +3331,23 @@
} /* switch (cmd->cmd) */
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int PowerUpDVBT(struct drxk_state *state)
+static int power_up_dvbt(struct drxk_state *state)
{
- enum DRXPowerMode powerMode = DRX_POWER_UP;
+ enum drx_power_mode power_mode = DRX_POWER_UP;
int status;
dprintk(1, "\n");
- status = CtrlPowerMode(state, &powerMode);
+ status = ctrl_power_mode(state, &power_mode);
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
+static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
{
int status;
@@ -3393,12 +3357,12 @@
else
status = write16(state, IQM_CF_BYPASSDET__A, 1);
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
#define DEFAULT_FR_THRES_8K 4000
-static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
+static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
{
int status;
@@ -3413,13 +3377,13 @@
status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
}
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
- struct DRXKCfgDvbtEchoThres_t *echoThres)
+static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
+ struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
{
u16 data = 0;
int status;
@@ -3429,16 +3393,16 @@
if (status < 0)
goto error;
- switch (echoThres->fftMode) {
+ switch (echo_thres->fft_mode) {
case DRX_FFTMODE_2K:
data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
- data |= ((echoThres->threshold <<
+ data |= ((echo_thres->threshold <<
OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
& (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
break;
case DRX_FFTMODE_8K:
data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
- data |= ((echoThres->threshold <<
+ data |= ((echo_thres->threshold <<
OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
& (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
break;
@@ -3449,12 +3413,12 @@
status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
- enum DRXKCfgDvbtSqiSpeed *speed)
+static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
+ enum drxk_cfg_dvbt_sqi_speed *speed)
{
int status = -EINVAL;
@@ -3472,7 +3436,7 @@
(u16) *speed);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -3486,32 +3450,33 @@
* Called in DVBTSetStandard
*
*/
-static int DVBTActivatePresets(struct drxk_state *state)
+static int dvbt_activate_presets(struct drxk_state *state)
{
int status;
bool setincenable = false;
bool setfrenable = true;
- struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
- struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
+ struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
+ struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
dprintk(1, "\n");
- status = DVBTCtrlSetIncEnable(state, &setincenable);
+ status = dvbt_ctrl_set_inc_enable(state, &setincenable);
if (status < 0)
goto error;
- status = DVBTCtrlSetFrEnable(state, &setfrenable);
+ status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
if (status < 0)
goto error;
- status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
+ status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
if (status < 0)
goto error;
- status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
+ status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
if (status < 0)
goto error;
- status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
+ status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
+ state->m_dvbt_if_agc_cfg.ingain_tgt_max);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -3525,25 +3490,30 @@
* For ROM code channel filter taps are loaded from the bootloader. For microcode
* the DVB-T taps from the drxk_filters.h are used.
*/
-static int SetDVBTStandard(struct drxk_state *state,
- enum OperationMode oMode)
+static int set_dvbt_standard(struct drxk_state *state,
+ enum operation_mode o_mode)
{
- u16 cmdResult = 0;
+ u16 cmd_result = 0;
u16 data = 0;
int status;
dprintk(1, "\n");
- PowerUpDVBT(state);
+ power_up_dvbt(state);
/* added antenna switch */
- SwitchAntennaToDVBT(state);
+ switch_antenna_to_dvbt(state);
/* send OFDM reset command */
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+ status = scu_command(state,
+ SCU_RAM_COMMAND_STANDARD_OFDM
+ | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+ 0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
/* send OFDM setenv command */
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
+ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+ | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
+ 0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
@@ -3575,7 +3545,7 @@
status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
if (status < 0)
goto error;
- status = SetIqmAf(state, true);
+ status = set_iqm_af(state, true);
if (status < 0)
goto error;
@@ -3597,7 +3567,7 @@
status = write16(state, IQM_RC_STRETCH__A, 16);
if (status < 0)
goto error;
- status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
+ status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
if (status < 0)
goto error;
status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
@@ -3618,7 +3588,8 @@
if (status < 0)
goto error;
- status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+ status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
+ DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
if (status < 0)
goto error;
@@ -3637,10 +3608,10 @@
goto error;
/* IQM will not be reset from here, sync ADC and update/init AGC */
- status = ADCSynchronization(state);
+ status = adc_synchronization(state);
if (status < 0)
goto error;
- status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
+ status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
if (status < 0)
goto error;
@@ -3649,10 +3620,10 @@
if (status < 0)
goto error;
- status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
+ status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
if (status < 0)
goto error;
- status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
+ status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
if (status < 0)
goto error;
@@ -3670,9 +3641,10 @@
if (status < 0)
goto error;
- if (!state->m_DRXK_A3_ROM_CODE) {
- /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
- status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
+ if (!state->m_drxk_a3_rom_code) {
+ /* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay */
+ status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
+ state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
if (status < 0)
goto error;
}
@@ -3707,41 +3679,43 @@
goto error;
/* Setup MPEG bus */
- status = MPEGTSDtoSetup(state, OM_DVBT);
+ status = mpegts_dto_setup(state, OM_DVBT);
if (status < 0)
goto error;
/* Set DVBT Presets */
- status = DVBTActivatePresets(state);
+ status = dvbt_activate_presets(state);
if (status < 0)
goto error;
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
/*============================================================================*/
/**
-* \brief Start dvbt demodulating for channel.
+* \brief start dvbt demodulating for channel.
* \param demod instance of demodulator.
* \return DRXStatus_t.
*/
-static int DVBTStart(struct drxk_state *state)
+static int dvbt_start(struct drxk_state *state)
{
u16 param1;
int status;
- /* DRXKOfdmScCmd_t scCmd; */
+ /* drxk_ofdm_sc_cmd_t scCmd; */
dprintk(1, "\n");
- /* Start correct processes to get in lock */
+ /* start correct processes to get in lock */
/* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
- status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
+ status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
+ OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
+ 0, 0, 0);
if (status < 0)
goto error;
- /* Start FEC OC */
- status = MPEGTSStart(state);
+ /* start FEC OC */
+ status = mpegts_start(state);
if (status < 0)
goto error;
status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
@@ -3749,7 +3723,7 @@
goto error;
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -3762,20 +3736,23 @@
* \return DRXStatus_t.
* // original DVBTSetChannel()
*/
-static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
- s32 tunerFreqOffset)
+static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
+ s32 tuner_freq_offset)
{
- u16 cmdResult = 0;
- u16 transmissionParams = 0;
- u16 operationMode = 0;
- u32 iqmRcRateOfs = 0;
+ u16 cmd_result = 0;
+ u16 transmission_params = 0;
+ u16 operation_mode = 0;
+ u32 iqm_rc_rate_ofs = 0;
u32 bandwidth = 0;
u16 param1;
int status;
- dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
+ dprintk(1, "IF =%d, TFO = %d\n",
+ intermediate_freqk_hz, tuner_freq_offset);
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+ | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+ 0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
@@ -3798,19 +3775,19 @@
if (status < 0)
goto error;
- /*== Write channel settings to device =====================================*/
+ /*== Write channel settings to device ================================*/
/* mode */
switch (state->props.transmission_mode) {
case TRANSMISSION_MODE_AUTO:
default:
- operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
+ operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
/* fall through , try first guess DRX_FFTMODE_8K */
case TRANSMISSION_MODE_8K:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
break;
case TRANSMISSION_MODE_2K:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
break;
}
@@ -3818,19 +3795,19 @@
switch (state->props.guard_interval) {
default:
case GUARD_INTERVAL_AUTO:
- operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
+ operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
/* fall through , try first guess DRX_GUARD_1DIV4 */
case GUARD_INTERVAL_1_4:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
break;
case GUARD_INTERVAL_1_32:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
break;
case GUARD_INTERVAL_1_16:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
break;
case GUARD_INTERVAL_1_8:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
break;
}
@@ -3839,18 +3816,18 @@
case HIERARCHY_AUTO:
case HIERARCHY_NONE:
default:
- operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
+ operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
/* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
- /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
+ /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
/* break; */
case HIERARCHY_1:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
break;
case HIERARCHY_2:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
break;
case HIERARCHY_4:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
break;
}
@@ -3859,16 +3836,16 @@
switch (state->props.modulation) {
case QAM_AUTO:
default:
- operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
+ operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
/* fall through , try first guess DRX_CONSTELLATION_QAM64 */
case QAM_64:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
break;
case QPSK:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
break;
case QAM_16:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
break;
}
#if 0
@@ -3876,13 +3853,13 @@
/* Priority (only for hierarchical channels) */
switch (channel->priority) {
case DRX_PRIORITY_LOW:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
- WR16(devAddr, OFDM_EC_SB_PRIOR__A,
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
+ WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
OFDM_EC_SB_PRIOR_LO);
break;
case DRX_PRIORITY_HIGH:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
- WR16(devAddr, OFDM_EC_SB_PRIOR__A,
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
+ WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
OFDM_EC_SB_PRIOR_HI));
break;
case DRX_PRIORITY_UNKNOWN: /* fall through */
@@ -3892,7 +3869,7 @@
}
#else
/* Set Priorty high */
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
if (status < 0)
goto error;
@@ -3902,90 +3879,111 @@
switch (state->props.code_rate_HP) {
case FEC_AUTO:
default:
- operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
+ operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
/* fall through , try first guess DRX_CODERATE_2DIV3 */
case FEC_2_3:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
break;
case FEC_1_2:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
break;
case FEC_3_4:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
break;
case FEC_5_6:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
break;
case FEC_7_8:
- transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
+ transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
break;
}
- /* SAW filter selection: normaly not necesarry, but if wanted
- the application can select a SAW filter via the driver by using UIOs */
+ /*
+ * SAW filter selection: normaly not necesarry, but if wanted
+ * the application can select a SAW filter via the driver by
+ * using UIOs
+ */
+
/* First determine real bandwidth (Hz) */
/* Also set delay for impulse noise cruncher */
- /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
- by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
- functions */
+ /*
+ * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
+ * changed by SC for fix for some 8K,1/8 guard but is restored by
+ * InitEC and ResetEC functions
+ */
switch (state->props.bandwidth_hz) {
case 0:
state->props.bandwidth_hz = 8000000;
/* fall though */
case 8000000:
bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
+ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+ 3052);
if (status < 0)
goto error;
/* cochannel protection for PAL 8 MHz */
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+ 7);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+ 7);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+ 7);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+ 1);
if (status < 0)
goto error;
break;
case 7000000:
bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
+ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+ 3491);
if (status < 0)
goto error;
/* cochannel protection for PAL 7 MHz */
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+ 8);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+ 8);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+ 4);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+ 1);
if (status < 0)
goto error;
break;
case 6000000:
bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
- status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
+ status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+ 4073);
if (status < 0)
goto error;
/* cochannel protection for NTSC 6 MHz */
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+ 19);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+ 19);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+ 14);
if (status < 0)
goto error;
- status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+ status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+ 1);
if (status < 0)
goto error;
break;
@@ -3994,46 +3992,50 @@
goto error;
}
- if (iqmRcRateOfs == 0) {
+ if (iqm_rc_rate_ofs == 0) {
/* Now compute IQM_RC_RATE_OFS
(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
=>
((SysFreq / BandWidth) * (2^21)) - (2^23)
*/
/* (SysFreq / BandWidth) * (2^28) */
- /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
- => assert(MAX(sysClk) < 16*MIN(bandwidth))
- => assert(109714272 > 48000000) = true so Frac 28 can be used */
- iqmRcRateOfs = Frac28a((u32)
- ((state->m_sysClockFreq *
+ /*
+ * assert (MAX(sysClk)/MIN(bandwidth) < 16)
+ * => assert(MAX(sysClk) < 16*MIN(bandwidth))
+ * => assert(109714272 > 48000000) = true
+ * so Frac 28 can be used
+ */
+ iqm_rc_rate_ofs = Frac28a((u32)
+ ((state->m_sys_clock_freq *
1000) / 3), bandwidth);
- /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
- if ((iqmRcRateOfs & 0x7fL) >= 0x40)
- iqmRcRateOfs += 0x80L;
- iqmRcRateOfs = iqmRcRateOfs >> 7;
+ /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
+ if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
+ iqm_rc_rate_ofs += 0x80L;
+ iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
/* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
- iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
+ iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
}
- iqmRcRateOfs &=
+ iqm_rc_rate_ofs &=
((((u32) IQM_RC_RATE_OFS_HI__M) <<
IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
- status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
+ status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
if (status < 0)
goto error;
/* Bandwidth setting done */
#if 0
- status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
+ status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
if (status < 0)
goto error;
#endif
- status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
+ status = set_frequency_shifter(state, intermediate_freqk_hz,
+ tuner_freq_offset, true);
if (status < 0)
goto error;
- /*== Start SC, write channel settings to SC ===============================*/
+ /*== start SC, write channel settings to SC ==========================*/
/* Activate SCU to enable SCU commands */
status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
@@ -4049,7 +4051,9 @@
goto error;
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
+ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+ | SCU_RAM_COMMAND_CMD_DEMOD_START,
+ 0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
@@ -4059,16 +4063,16 @@
OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
- status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
- 0, transmissionParams, param1, 0, 0, 0);
+ status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
+ 0, transmission_params, param1, 0, 0, 0);
if (status < 0)
goto error;
- if (!state->m_DRXK_A3_ROM_CODE)
- status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
+ if (!state->m_drxk_a3_rom_code)
+ status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -4083,7 +4087,7 @@
* \return DRXStatus_t.
*
*/
-static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
{
int status;
const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
@@ -4091,58 +4095,58 @@
const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
- u16 ScRaRamLock = 0;
- u16 ScCommExec = 0;
+ u16 sc_ra_ram_lock = 0;
+ u16 sc_comm_exec = 0;
dprintk(1, "\n");
- *pLockStatus = NOT_LOCKED;
+ *p_lock_status = NOT_LOCKED;
/* driver 0.9.0 */
/* Check if SC is running */
- status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
+ status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
if (status < 0)
goto end;
- if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
+ if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
goto end;
- status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
+ status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
if (status < 0)
goto end;
- if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
- *pLockStatus = MPEG_LOCK;
- else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
- *pLockStatus = FEC_LOCK;
- else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
- *pLockStatus = DEMOD_LOCK;
- else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
- *pLockStatus = NEVER_LOCK;
+ if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
+ *p_lock_status = MPEG_LOCK;
+ else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
+ *p_lock_status = FEC_LOCK;
+ else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
+ *p_lock_status = DEMOD_LOCK;
+ else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
+ *p_lock_status = NEVER_LOCK;
end:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int PowerUpQAM(struct drxk_state *state)
+static int power_up_qam(struct drxk_state *state)
{
- enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
+ enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
int status;
dprintk(1, "\n");
- status = CtrlPowerMode(state, &powerMode);
+ status = ctrl_power_mode(state, &power_mode);
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
/** Power Down QAM */
-static int PowerDownQAM(struct drxk_state *state)
+static int power_down_qam(struct drxk_state *state)
{
u16 data = 0;
- u16 cmdResult;
+ u16 cmd_result;
int status = 0;
dprintk(1, "\n");
@@ -4158,16 +4162,18 @@
status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
if (status < 0)
goto error;
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+ | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+ 0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
}
/* powerdown AFE */
- status = SetIqmAf(state, false);
+ status = set_iqm_af(state, false);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -4185,20 +4191,20 @@
* The implementation does not check this.
*
*/
-static int SetQAMMeasurement(struct drxk_state *state,
- enum EDrxkConstellation modulation,
- u32 symbolRate)
+static int set_qam_measurement(struct drxk_state *state,
+ enum e_drxk_constellation modulation,
+ u32 symbol_rate)
{
- u32 fecBitsDesired = 0; /* BER accounting period */
- u32 fecRsPeriodTotal = 0; /* Total period */
- u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
- u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
+ u32 fec_bits_desired = 0; /* BER accounting period */
+ u32 fec_rs_period_total = 0; /* Total period */
+ u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
+ u16 fec_rs_period = 0; /* Value for corresponding I2C register */
int status = 0;
dprintk(1, "\n");
- fecRsPrescale = 1;
- /* fecBitsDesired = symbolRate [kHz] *
+ fec_rs_prescale = 1;
+ /* fec_bits_desired = symbol_rate [kHz] *
FrameLenght [ms] *
(modulation + 1) *
SyncLoss (== 1) *
@@ -4206,19 +4212,19 @@
*/
switch (modulation) {
case DRX_CONSTELLATION_QAM16:
- fecBitsDesired = 4 * symbolRate;
+ fec_bits_desired = 4 * symbol_rate;
break;
case DRX_CONSTELLATION_QAM32:
- fecBitsDesired = 5 * symbolRate;
+ fec_bits_desired = 5 * symbol_rate;
break;
case DRX_CONSTELLATION_QAM64:
- fecBitsDesired = 6 * symbolRate;
+ fec_bits_desired = 6 * symbol_rate;
break;
case DRX_CONSTELLATION_QAM128:
- fecBitsDesired = 7 * symbolRate;
+ fec_bits_desired = 7 * symbol_rate;
break;
case DRX_CONSTELLATION_QAM256:
- fecBitsDesired = 8 * symbolRate;
+ fec_bits_desired = 8 * symbol_rate;
break;
default:
status = -EINVAL;
@@ -4226,40 +4232,41 @@
if (status < 0)
goto error;
- fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
- fecBitsDesired *= 500; /* meas. period [ms] */
+ fec_bits_desired /= 1000; /* symbol_rate [Hz] -> symbol_rate [kHz] */
+ fec_bits_desired *= 500; /* meas. period [ms] */
/* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
- /* fecRsPeriodTotal = fecBitsDesired / 1632 */
- fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
+ /* fec_rs_period_total = fec_bits_desired / 1632 */
+ fec_rs_period_total = (fec_bits_desired / 1632UL) + 1; /* roughly ceil */
- /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
- fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
- if (fecRsPrescale == 0) {
+ /* fec_rs_period_total = fec_rs_prescale * fec_rs_period */
+ fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
+ if (fec_rs_prescale == 0) {
/* Divide by zero (though impossible) */
status = -EINVAL;
if (status < 0)
goto error;
}
- fecRsPeriod =
- ((u16) fecRsPeriodTotal +
- (fecRsPrescale >> 1)) / fecRsPrescale;
+ fec_rs_period =
+ ((u16) fec_rs_period_total +
+ (fec_rs_prescale >> 1)) / fec_rs_prescale;
/* write corresponding registers */
- status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
+ status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
if (status < 0)
goto error;
- status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
+ status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
+ fec_rs_prescale);
if (status < 0)
goto error;
- status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
+ status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int SetQAM16(struct drxk_state *state)
+static int set_qam16(struct drxk_state *state)
{
int status = 0;
@@ -4315,7 +4322,8 @@
goto error;
/* QAM Slicer Settings */
- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
+ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+ DRXK_QAM_SL_SIG_POWER_QAM16);
if (status < 0)
goto error;
@@ -4441,7 +4449,7 @@
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -4452,7 +4460,7 @@
* \param demod instance of demod.
* \return DRXStatus_t.
*/
-static int SetQAM32(struct drxk_state *state)
+static int set_qam32(struct drxk_state *state)
{
int status = 0;
@@ -4511,7 +4519,8 @@
/* QAM Slicer Settings */
- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
+ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+ DRXK_QAM_SL_SIG_POWER_QAM32);
if (status < 0)
goto error;
@@ -4636,7 +4645,7 @@
status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -4647,7 +4656,7 @@
* \param demod instance of demod.
* \return DRXStatus_t.
*/
-static int SetQAM64(struct drxk_state *state)
+static int set_qam64(struct drxk_state *state)
{
int status = 0;
@@ -4704,7 +4713,8 @@
goto error;
/* QAM Slicer Settings */
- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
+ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+ DRXK_QAM_SL_SIG_POWER_QAM64);
if (status < 0)
goto error;
@@ -4829,7 +4839,7 @@
status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -4841,7 +4851,7 @@
* \param demod: instance of demod.
* \return DRXStatus_t.
*/
-static int SetQAM128(struct drxk_state *state)
+static int set_qam128(struct drxk_state *state)
{
int status = 0;
@@ -4900,7 +4910,8 @@
/* QAM Slicer Settings */
- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
+ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+ DRXK_QAM_SL_SIG_POWER_QAM128);
if (status < 0)
goto error;
@@ -5025,7 +5036,7 @@
status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -5037,7 +5048,7 @@
* \param demod: instance of demod.
* \return DRXStatus_t.
*/
-static int SetQAM256(struct drxk_state *state)
+static int set_qam256(struct drxk_state *state)
{
int status = 0;
@@ -5095,7 +5106,8 @@
/* QAM Slicer Settings */
- status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
+ status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+ DRXK_QAM_SL_SIG_POWER_QAM256);
if (status < 0)
goto error;
@@ -5220,7 +5232,7 @@
status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -5232,10 +5244,10 @@
* \param channel: pointer to channel data.
* \return DRXStatus_t.
*/
-static int QAMResetQAM(struct drxk_state *state)
+static int qam_reset_qam(struct drxk_state *state)
{
int status;
- u16 cmdResult;
+ u16 cmd_result;
dprintk(1, "\n");
/* Stop QAM comstate->m_exec */
@@ -5243,10 +5255,12 @@
if (status < 0)
goto error;
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+ | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+ 0, NULL, 1, &cmd_result);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -5258,18 +5272,18 @@
* \param channel: pointer to channel data.
* \return DRXStatus_t.
*/
-static int QAMSetSymbolrate(struct drxk_state *state)
+static int qam_set_symbolrate(struct drxk_state *state)
{
- u32 adcFrequency = 0;
- u32 symbFreq = 0;
- u32 iqmRcRate = 0;
+ u32 adc_frequency = 0;
+ u32 symb_freq = 0;
+ u32 iqm_rc_rate = 0;
u16 ratesel = 0;
- u32 lcSymbRate = 0;
+ u32 lc_symb_rate = 0;
int status;
dprintk(1, "\n");
/* Select & calculate correct IQM rate */
- adcFrequency = (state->m_sysClockFreq * 1000) / 3;
+ adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
ratesel = 0;
/* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
if (state->props.symbol_rate <= 1188750)
@@ -5285,38 +5299,38 @@
/*
IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
*/
- symbFreq = state->props.symbol_rate * (1 << ratesel);
- if (symbFreq == 0) {
+ symb_freq = state->props.symbol_rate * (1 << ratesel);
+ if (symb_freq == 0) {
/* Divide by zero */
status = -EINVAL;
goto error;
}
- iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
- (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
+ iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
+ (Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
(1 << 23);
- status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
+ status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
if (status < 0)
goto error;
- state->m_iqmRcRate = iqmRcRate;
+ state->m_iqm_rc_rate = iqm_rc_rate;
/*
- LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
+ LcSymbFreq = round (.125 * symbolrate / adc_freq * (1<<15))
*/
- symbFreq = state->props.symbol_rate;
- if (adcFrequency == 0) {
+ symb_freq = state->props.symbol_rate;
+ if (adc_frequency == 0) {
/* Divide by zero */
status = -EINVAL;
goto error;
}
- lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
- (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
+ lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
+ (Frac28a((symb_freq % adc_frequency), adc_frequency) >>
16);
- if (lcSymbRate > 511)
- lcSymbRate = 511;
- status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
+ if (lc_symb_rate > 511)
+ lc_symb_rate = 511;
+ status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -5329,34 +5343,36 @@
* \return DRXStatus_t.
*/
-static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
{
int status;
- u16 Result[2] = { 0, 0 };
+ u16 result[2] = { 0, 0 };
dprintk(1, "\n");
- *pLockStatus = NOT_LOCKED;
+ *p_lock_status = NOT_LOCKED;
status = scu_command(state,
SCU_RAM_COMMAND_STANDARD_QAM |
SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
- Result);
+ result);
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
- if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
+ if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
/* 0x0000 NOT LOCKED */
- } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
+ } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
/* 0x4000 DEMOD LOCKED */
- *pLockStatus = DEMOD_LOCK;
- } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
+ *p_lock_status = DEMOD_LOCK;
+ } else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
/* 0x8000 DEMOD + FEC LOCKED (system lock) */
- *pLockStatus = MPEG_LOCK;
+ *p_lock_status = MPEG_LOCK;
} else {
/* 0xC000 NEVER LOCKED */
/* (system will never be able to lock to the signal) */
- /* TODO: check this, intermediate & standard specific lock states are not
- taken into account here */
- *pLockStatus = NEVER_LOCK;
+ /*
+ * TODO: check this, intermediate & standard specific lock
+ * states are not taken into account here
+ */
+ *p_lock_status = NEVER_LOCK;
}
return status;
}
@@ -5368,68 +5384,70 @@
#define QAM_LOCKRANGE__M 0x10
#define QAM_LOCKRANGE_NORMAL 0x10
-static int QAMDemodulatorCommand(struct drxk_state *state,
- int numberOfParameters)
+static int qam_demodulator_command(struct drxk_state *state,
+ int number_of_parameters)
{
int status;
- u16 cmdResult;
- u16 setParamParameters[4] = { 0, 0, 0, 0 };
+ u16 cmd_result;
+ u16 set_param_parameters[4] = { 0, 0, 0, 0 };
- setParamParameters[0] = state->m_Constellation; /* modulation */
- setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
+ set_param_parameters[0] = state->m_constellation; /* modulation */
+ set_param_parameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
- if (numberOfParameters == 2) {
- u16 setEnvParameters[1] = { 0 };
+ if (number_of_parameters == 2) {
+ u16 set_env_parameters[1] = { 0 };
- if (state->m_OperationMode == OM_QAM_ITU_C)
- setEnvParameters[0] = QAM_TOP_ANNEX_C;
+ if (state->m_operation_mode == OM_QAM_ITU_C)
+ set_env_parameters[0] = QAM_TOP_ANNEX_C;
else
- setEnvParameters[0] = QAM_TOP_ANNEX_A;
+ set_env_parameters[0] = QAM_TOP_ANNEX_A;
status = scu_command(state,
- SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
- 1, setEnvParameters, 1, &cmdResult);
+ SCU_RAM_COMMAND_STANDARD_QAM
+ | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
+ 1, set_env_parameters, 1, &cmd_result);
if (status < 0)
goto error;
status = scu_command(state,
- SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
- numberOfParameters, setParamParameters,
- 1, &cmdResult);
- } else if (numberOfParameters == 4) {
- if (state->m_OperationMode == OM_QAM_ITU_C)
- setParamParameters[2] = QAM_TOP_ANNEX_C;
+ SCU_RAM_COMMAND_STANDARD_QAM
+ | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
+ number_of_parameters, set_param_parameters,
+ 1, &cmd_result);
+ } else if (number_of_parameters == 4) {
+ if (state->m_operation_mode == OM_QAM_ITU_C)
+ set_param_parameters[2] = QAM_TOP_ANNEX_C;
else
- setParamParameters[2] = QAM_TOP_ANNEX_A;
+ set_param_parameters[2] = QAM_TOP_ANNEX_A;
- setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
+ set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
/* Env parameters */
/* check for LOCKRANGE Extented */
- /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
+ /* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
status = scu_command(state,
- SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
- numberOfParameters, setParamParameters,
- 1, &cmdResult);
+ SCU_RAM_COMMAND_STANDARD_QAM
+ | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
+ number_of_parameters, set_param_parameters,
+ 1, &cmd_result);
} else {
- printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
- "count %d\n", numberOfParameters);
+ pr_warn("Unknown QAM demodulator parameter count %d\n",
+ number_of_parameters);
status = -EINVAL;
}
error:
if (status < 0)
- printk(KERN_WARNING "drxk: Warning %d on %s\n",
- status, __func__);
+ pr_warn("Warning %d on %s\n", status, __func__);
return status;
}
-static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
- s32 tunerFreqOffset)
+static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
+ s32 tuner_freq_offset)
{
int status;
- u16 cmdResult;
- int qamDemodParamCount = state->qam_demod_parameter_count;
+ u16 cmd_result;
+ int qam_demod_param_count = state->qam_demod_parameter_count;
dprintk(1, "\n");
/*
@@ -5444,7 +5462,7 @@
status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
if (status < 0)
goto error;
- status = QAMResetQAM(state);
+ status = qam_reset_qam(state);
if (status < 0)
goto error;
@@ -5453,27 +5471,27 @@
* -set params; resets IQM,QAM,FEC HW; initializes some
* SCU variables
*/
- status = QAMSetSymbolrate(state);
+ status = qam_set_symbolrate(state);
if (status < 0)
goto error;
/* Set params */
switch (state->props.modulation) {
case QAM_256:
- state->m_Constellation = DRX_CONSTELLATION_QAM256;
+ state->m_constellation = DRX_CONSTELLATION_QAM256;
break;
case QAM_AUTO:
case QAM_64:
- state->m_Constellation = DRX_CONSTELLATION_QAM64;
+ state->m_constellation = DRX_CONSTELLATION_QAM64;
break;
case QAM_16:
- state->m_Constellation = DRX_CONSTELLATION_QAM16;
+ state->m_constellation = DRX_CONSTELLATION_QAM16;
break;
case QAM_32:
- state->m_Constellation = DRX_CONSTELLATION_QAM32;
+ state->m_constellation = DRX_CONSTELLATION_QAM32;
break;
case QAM_128:
- state->m_Constellation = DRX_CONSTELLATION_QAM128;
+ state->m_constellation = DRX_CONSTELLATION_QAM128;
break;
default:
status = -EINVAL;
@@ -5486,8 +5504,8 @@
* the correct command. */
if (state->qam_demod_parameter_count == 4
|| !state->qam_demod_parameter_count) {
- qamDemodParamCount = 4;
- status = QAMDemodulatorCommand(state, qamDemodParamCount);
+ qam_demod_param_count = 4;
+ status = qam_demodulator_command(state, qam_demod_param_count);
}
/* Use the 2-parameter command if it was requested or if we're
@@ -5495,27 +5513,27 @@
* failed. */
if (state->qam_demod_parameter_count == 2
|| (!state->qam_demod_parameter_count && status < 0)) {
- qamDemodParamCount = 2;
- status = QAMDemodulatorCommand(state, qamDemodParamCount);
+ qam_demod_param_count = 2;
+ status = qam_demodulator_command(state, qam_demod_param_count);
}
if (status < 0) {
- dprintk(1, "Could not set demodulator parameters. Make "
- "sure qam_demod_parameter_count (%d) is correct for "
- "your firmware (%s).\n",
+ dprintk(1, "Could not set demodulator parameters.\n");
+ dprintk(1,
+ "Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
state->qam_demod_parameter_count,
state->microcode_name);
goto error;
} else if (!state->qam_demod_parameter_count) {
- dprintk(1, "Auto-probing the correct QAM demodulator command "
- "parameters was successful - using %d parameters.\n",
- qamDemodParamCount);
+ dprintk(1,
+ "Auto-probing the QAM command parameters was successful - using %d parameters.\n",
+ qam_demod_param_count);
/*
* One of our commands was successful. We don't need to
* auto-probe anymore, now that we got the correct command.
*/
- state->qam_demod_parameter_count = qamDemodParamCount;
+ state->qam_demod_parameter_count = qam_demod_param_count;
}
/*
@@ -5523,16 +5541,18 @@
* signal setup modulation independent registers
*/
#if 0
- status = SetFrequency(channel, tunerFreqOffset));
+ status = set_frequency(channel, tuner_freq_offset));
if (status < 0)
goto error;
#endif
- status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
+ status = set_frequency_shifter(state, intermediate_freqk_hz,
+ tuner_freq_offset, true);
if (status < 0)
goto error;
/* Setup BER measurement */
- status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
+ status = set_qam_measurement(state, state->m_constellation,
+ state->props.symbol_rate);
if (status < 0)
goto error;
@@ -5605,7 +5625,8 @@
goto error;
/* Mirroring, QAM-block starting point not inverted */
- status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
+ status = write16(state, QAM_SY_SP_INV__A,
+ QAM_SY_SP_INV_SPECTRUM_INV_DIS);
if (status < 0)
goto error;
@@ -5617,20 +5638,20 @@
/* STEP 4: modulation specific setup */
switch (state->props.modulation) {
case QAM_16:
- status = SetQAM16(state);
+ status = set_qam16(state);
break;
case QAM_32:
- status = SetQAM32(state);
+ status = set_qam32(state);
break;
case QAM_AUTO:
case QAM_64:
- status = SetQAM64(state);
+ status = set_qam64(state);
break;
case QAM_128:
- status = SetQAM128(state);
+ status = set_qam128(state);
break;
case QAM_256:
- status = SetQAM256(state);
+ status = set_qam256(state);
break;
default:
status = -EINVAL;
@@ -5647,12 +5668,12 @@
/* Re-configure MPEG output, requires knowledge of channel bitrate */
/* extAttr->currentChannel.modulation = channel->modulation; */
/* extAttr->currentChannel.symbolrate = channel->symbolrate; */
- status = MPEGTSDtoSetup(state, state->m_OperationMode);
+ status = mpegts_dto_setup(state, state->m_operation_mode);
if (status < 0)
goto error;
- /* Start processes */
- status = MPEGTSStart(state);
+ /* start processes */
+ status = mpegts_start(state);
if (status < 0)
goto error;
status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
@@ -5666,7 +5687,9 @@
goto error;
/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
- status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
+ status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+ | SCU_RAM_COMMAND_CMD_DEMOD_START,
+ 0, NULL, 1, &cmd_result);
if (status < 0)
goto error;
@@ -5675,12 +5698,12 @@
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int SetQAMStandard(struct drxk_state *state,
- enum OperationMode oMode)
+static int set_qam_standard(struct drxk_state *state,
+ enum operation_mode o_mode)
{
int status;
#ifdef DRXK_QAM_TAPS
@@ -5692,14 +5715,14 @@
dprintk(1, "\n");
/* added antenna switch */
- SwitchAntennaToQAM(state);
+ switch_antenna_to_qam(state);
/* Ensure correct power-up mode */
- status = PowerUpQAM(state);
+ status = power_up_qam(state);
if (status < 0)
goto error;
/* Reset QAM block */
- status = QAMResetQAM(state);
+ status = qam_reset_qam(state);
if (status < 0)
goto error;
@@ -5714,15 +5737,24 @@
/* Upload IQM Channel Filter settings by
boot loader from ROM table */
- switch (oMode) {
+ switch (o_mode) {
case OM_QAM_ITU_A:
- status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+ status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
+ DRXK_BLCC_NR_ELEMENTS_TAPS,
+ DRXK_BLC_TIMEOUT);
break;
case OM_QAM_ITU_C:
- status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+ status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
+ DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
+ DRXK_BLDC_NR_ELEMENTS_TAPS,
+ DRXK_BLC_TIMEOUT);
if (status < 0)
goto error;
- status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+ status = bl_direct_cmd(state,
+ IQM_CF_TAP_IM0__A,
+ DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
+ DRXK_BLDC_NR_ELEMENTS_TAPS,
+ DRXK_BLC_TIMEOUT);
break;
default:
status = -EINVAL;
@@ -5730,13 +5762,14 @@
if (status < 0)
goto error;
- status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
+ status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
if (status < 0)
goto error;
status = write16(state, IQM_CF_SYMMETRIC__A, 0);
if (status < 0)
goto error;
- status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
+ status = write16(state, IQM_CF_MIDTAP__A,
+ ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
if (status < 0)
goto error;
@@ -5793,7 +5826,7 @@
goto error;
/* turn on IQMAF. Must be done before setAgc**() */
- status = SetIqmAf(state, true);
+ status = set_iqm_af(state, true);
if (status < 0)
goto error;
status = write16(state, IQM_AF_START_LOCK__A, 0x01);
@@ -5801,7 +5834,7 @@
goto error;
/* IQM will not be reset from here, sync ADC and update/init AGC */
- status = ADCSynchronization(state);
+ status = adc_synchronization(state);
if (status < 0)
goto error;
@@ -5818,18 +5851,18 @@
/* No more resets of the IQM, current standard correctly set =>
now AGCs can be configured. */
- status = InitAGC(state, true);
+ status = init_agc(state, true);
if (status < 0)
goto error;
- status = SetPreSaw(state, &(state->m_qamPreSawCfg));
+ status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
if (status < 0)
goto error;
/* Configure AGC's */
- status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
+ status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
if (status < 0)
goto error;
- status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
+ status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
if (status < 0)
goto error;
@@ -5837,18 +5870,19 @@
status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int WriteGPIO(struct drxk_state *state)
+static int write_gpio(struct drxk_state *state)
{
int status;
u16 value = 0;
dprintk(1, "\n");
/* stop lock indicator process */
- status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+ status = write16(state, SCU_RAM_GPIO__A,
+ SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
if (status < 0)
goto error;
@@ -5857,10 +5891,11 @@
if (status < 0)
goto error;
- if (state->m_hasSAWSW) {
- if (state->UIO_mask & 0x0001) { /* UIO-1 */
+ if (state->m_has_sawsw) {
+ if (state->uio_mask & 0x0001) { /* UIO-1 */
/* write to io pad configuration register - output mode */
- status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
+ status = write16(state, SIO_PDR_SMA_TX_CFG__A,
+ state->m_gpio_cfg);
if (status < 0)
goto error;
@@ -5868,7 +5903,7 @@
status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
if (status < 0)
goto error;
- if ((state->m_GPIO & 0x0001) == 0)
+ if ((state->m_gpio & 0x0001) == 0)
value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
else
value |= 0x8000; /* write one to 15th bit - 1st UIO */
@@ -5877,9 +5912,10 @@
if (status < 0)
goto error;
}
- if (state->UIO_mask & 0x0002) { /* UIO-2 */
+ if (state->uio_mask & 0x0002) { /* UIO-2 */
/* write to io pad configuration register - output mode */
- status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
+ status = write16(state, SIO_PDR_SMA_RX_CFG__A,
+ state->m_gpio_cfg);
if (status < 0)
goto error;
@@ -5887,7 +5923,7 @@
status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
if (status < 0)
goto error;
- if ((state->m_GPIO & 0x0002) == 0)
+ if ((state->m_gpio & 0x0002) == 0)
value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
else
value |= 0x4000; /* write one to 14th bit - 2st UIO */
@@ -5896,9 +5932,10 @@
if (status < 0)
goto error;
}
- if (state->UIO_mask & 0x0004) { /* UIO-3 */
+ if (state->uio_mask & 0x0004) { /* UIO-3 */
/* write to io pad configuration register - output mode */
- status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
+ status = write16(state, SIO_PDR_GPIO_CFG__A,
+ state->m_gpio_cfg);
if (status < 0)
goto error;
@@ -5906,7 +5943,7 @@
status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
if (status < 0)
goto error;
- if ((state->m_GPIO & 0x0004) == 0)
+ if ((state->m_gpio & 0x0004) == 0)
value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
else
value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
@@ -5920,11 +5957,11 @@
status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int SwitchAntennaToQAM(struct drxk_state *state)
+static int switch_antenna_to_qam(struct drxk_state *state)
{
int status = 0;
bool gpio_state;
@@ -5934,22 +5971,22 @@
if (!state->antenna_gpio)
return 0;
- gpio_state = state->m_GPIO & state->antenna_gpio;
+ gpio_state = state->m_gpio & state->antenna_gpio;
if (state->antenna_dvbt ^ gpio_state) {
/* Antenna is on DVB-T mode. Switch */
if (state->antenna_dvbt)
- state->m_GPIO &= ~state->antenna_gpio;
+ state->m_gpio &= ~state->antenna_gpio;
else
- state->m_GPIO |= state->antenna_gpio;
- status = WriteGPIO(state);
+ state->m_gpio |= state->antenna_gpio;
+ status = write_gpio(state);
}
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int SwitchAntennaToDVBT(struct drxk_state *state)
+static int switch_antenna_to_dvbt(struct drxk_state *state)
{
int status = 0;
bool gpio_state;
@@ -5959,23 +5996,23 @@
if (!state->antenna_gpio)
return 0;
- gpio_state = state->m_GPIO & state->antenna_gpio;
+ gpio_state = state->m_gpio & state->antenna_gpio;
if (!(state->antenna_dvbt ^ gpio_state)) {
/* Antenna is on DVB-C mode. Switch */
if (state->antenna_dvbt)
- state->m_GPIO |= state->antenna_gpio;
+ state->m_gpio |= state->antenna_gpio;
else
- state->m_GPIO &= ~state->antenna_gpio;
- status = WriteGPIO(state);
+ state->m_gpio &= ~state->antenna_gpio;
+ status = write_gpio(state);
}
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
-static int PowerDownDevice(struct drxk_state *state)
+static int power_down_device(struct drxk_state *state)
{
/* Power down to requested mode */
/* Backup some register settings */
@@ -5986,28 +6023,29 @@
int status;
dprintk(1, "\n");
- if (state->m_bPDownOpenBridge) {
+ if (state->m_b_p_down_open_bridge) {
/* Open I2C bridge before power down of DRXK */
status = ConfigureI2CBridge(state, true);
if (status < 0)
goto error;
}
/* driver 0.9.0 */
- status = DVBTEnableOFDMTokenRing(state, false);
+ status = dvbt_enable_ofdm_token_ring(state, false);
if (status < 0)
goto error;
- status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
+ status = write16(state, SIO_CC_PWD_MODE__A,
+ SIO_CC_PWD_MODE_LEVEL_CLOCK);
if (status < 0)
goto error;
status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
if (status < 0)
goto error;
- state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
- status = HI_CfgCommand(state);
+ state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+ status = hi_cfg_command(state);
error:
if (status < 0)
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
return status;
}
@@ -6015,50 +6053,56 @@
static int init_drxk(struct drxk_state *state)
{
int status = 0, n = 0;
- enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
- u16 driverVersion;
+ enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
+ u16 driver_version;
dprintk(1, "\n");
- if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
+ if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
drxk_i2c_lock(state);
- status = PowerUpDevice(state);
+ status = power_up_device(state);
if (status < 0)
goto error;
- status = DRXX_Open(state);
+ status = drxx_open(state);
if (status < 0)
goto error;
/* Soft reset of OFDM-, sys- and osc-clockdomain */
- status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
+ status = write16(state, SIO_CC_SOFT_RST__A,
+ SIO_CC_SOFT_RST_OFDM__M
+ | SIO_CC_SOFT_RST_SYS__M
+ | SIO_CC_SOFT_RST_OSC__M);
if (status < 0)
goto error;
status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
if (status < 0)
goto error;
- /* TODO is this needed, if yes how much delay in worst case scenario */
- msleep(1);
- state->m_DRXK_A3_PATCH_CODE = true;
- status = GetDeviceCapabilities(state);
+ /*
+ * TODO is this needed? If yes, how much delay in
+ * worst case scenario
+ */
+ usleep_range(1000, 2000);
+ state->m_drxk_a3_patch_code = true;
+ status = get_device_capabilities(state);
if (status < 0)
goto error;
/* Bridge delay, uses oscilator clock */
/* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
/* SDA brdige delay */
- state->m_HICfgBridgeDelay =
- (u16) ((state->m_oscClockFreq / 1000) *
+ state->m_hi_cfg_bridge_delay =
+ (u16) ((state->m_osc_clock_freq / 1000) *
HI_I2C_BRIDGE_DELAY) / 1000;
/* Clipping */
- if (state->m_HICfgBridgeDelay >
+ if (state->m_hi_cfg_bridge_delay >
SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
- state->m_HICfgBridgeDelay =
+ state->m_hi_cfg_bridge_delay =
SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
}
/* SCL bridge delay, same as SDA for now */
- state->m_HICfgBridgeDelay +=
- state->m_HICfgBridgeDelay <<
+ state->m_hi_cfg_bridge_delay +=
+ state->m_hi_cfg_bridge_delay <<
SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
- status = InitHI(state);
+ status = init_hi(state);
if (status < 0)
goto error;
/* disable various processes */
@@ -6067,13 +6111,14 @@
&& !(state->m_DRXK_A2_ROM_CODE))
#endif
{
- status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+ status = write16(state, SCU_RAM_GPIO__A,
+ SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
if (status < 0)
goto error;
}
/* disable MPEG port */
- status = MPEGTSDisable(state);
+ status = mpegts_disable(state);
if (status < 0)
goto error;
@@ -6086,27 +6131,30 @@
goto error;
/* enable token-ring bus through OFDM block for possible ucode upload */
- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
+ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
+ SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
if (status < 0)
goto error;
/* include boot loader section */
- status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
+ status = write16(state, SIO_BL_COMM_EXEC__A,
+ SIO_BL_COMM_EXEC_ACTIVE);
if (status < 0)
goto error;
- status = BLChainCmd(state, 0, 6, 100);
+ status = bl_chain_cmd(state, 0, 6, 100);
if (status < 0)
goto error;
if (state->fw) {
- status = DownloadMicrocode(state, state->fw->data,
+ status = download_microcode(state, state->fw->data,
state->fw->size);
if (status < 0)
goto error;
}
/* disable token-ring bus through OFDM block for possible ucode upload */
- status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
+ status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
+ SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
if (status < 0)
goto error;
@@ -6114,14 +6162,14 @@
status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
if (status < 0)
goto error;
- status = DRXX_Open(state);
+ status = drxx_open(state);
if (status < 0)
goto error;
/* added for test */
msleep(30);
- powerMode = DRXK_POWER_DOWN_OFDM;
- status = CtrlPowerMode(state, &powerMode);
+ power_mode = DRXK_POWER_DOWN_OFDM;
+ status = ctrl_power_mode(state, &power_mode);
if (status < 0)
goto error;
@@ -6131,33 +6179,38 @@
Not using SCU command interface for SCU register access since no
microcode may be present.
*/
- driverVersion =
+ driver_version =
(((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
(((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
((DRXK_VERSION_MAJOR % 10) << 4) +
(DRXK_VERSION_MINOR % 10);
- status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
+ status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
+ driver_version);
if (status < 0)
goto error;
- driverVersion =
+ driver_version =
(((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
(((DRXK_VERSION_PATCH / 100) % 10) << 8) +
(((DRXK_VERSION_PATCH / 10) % 10) << 4) +
(DRXK_VERSION_PATCH % 10);
- status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
+ status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
+ driver_version);
if (status < 0)
goto error;
- printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
+ pr_info("DRXK driver version %d.%d.%d\n",
DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
DRXK_VERSION_PATCH);
- /* Dirty fix of default values for ROM/PATCH microcode
- Dirty because this fix makes it impossible to setup suitable values
- before calling DRX_Open. This solution requires changes to RF AGC speed
- to be done via the CTRL function after calling DRX_Open */
+ /*
+ * Dirty fix of default values for ROM/PATCH microcode
+ * Dirty because this fix makes it impossible to setup
+ * suitable values before calling DRX_Open. This solution
+ * requires changes to RF AGC speed to be done via the CTRL
+ * function after calling DRX_Open
+ */
- /* m_dvbtRfAgcCfg.speed = 3; */
+ /* m_dvbt_rf_agc_cfg.speed = 3; */
/* Reset driver debug flags to 0 */
status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
@@ -6170,42 +6223,42 @@
if (status < 0)
goto error;
/* MPEGTS functions are still the same */
- status = MPEGTSDtoInit(state);
+ status = mpegts_dto_init(state);
if (status < 0)
goto error;
- status = MPEGTSStop(state);
+ status = mpegts_stop(state);
if (status < 0)
goto error;
- status = MPEGTSConfigurePolarity(state);
+ status = mpegts_configure_polarity(state);
if (status < 0)
goto error;
- status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
+ status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
if (status < 0)
goto error;
/* added: configure GPIO */
- status = WriteGPIO(state);
+ status = write_gpio(state);
if (status < 0)
goto error;
- state->m_DrxkState = DRXK_STOPPED;
+ state->m_drxk_state = DRXK_STOPPED;
- if (state->m_bPowerDown) {
- status = PowerDownDevice(state);
+ if (state->m_b_power_down) {
+ status = power_down_device(state);
if (status < 0)
goto error;
- state->m_DrxkState = DRXK_POWERED_DOWN;
+ state->m_drxk_state = DRXK_POWERED_DOWN;
} else
- state->m_DrxkState = DRXK_STOPPED;
+ state->m_drxk_state = DRXK_STOPPED;
/* Initialize the supported delivery systems */
n = 0;
- if (state->m_hasDVBC) {
+ if (state->m_has_dvbc) {
state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
strlcat(state->frontend.ops.info.name, " DVB-C",
sizeof(state->frontend.ops.info.name));
}
- if (state->m_hasDVBT) {
+ if (state->m_has_dvbt) {
state->frontend.ops.delsys[n++] = SYS_DVBT;
strlcat(state->frontend.ops.info.name, " DVB-T",
sizeof(state->frontend.ops.info.name));
@@ -6214,9 +6267,9 @@
}
error:
if (status < 0) {
- state->m_DrxkState = DRXK_NO_DEV;
+ state->m_drxk_state = DRXK_NO_DEV;
drxk_i2c_unlock(state);
- printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+ pr_err("Error %d on %s\n", status, __func__);
}
return status;
@@ -6229,11 +6282,9 @@
dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
if (!fw) {
- printk(KERN_ERR
- "drxk: Could not load firmware file %s.\n",
+ pr_err("Could not load firmware file %s.\n",
state->microcode_name);
- printk(KERN_INFO
- "drxk: Copy %s to your hotplug directory!\n",
+ pr_info("Copy %s to your hotplug directory!\n",
state->microcode_name);
state->microcode_name = NULL;
@@ -6270,12 +6321,12 @@
dprintk(1, "\n");
- if (state->m_DrxkState == DRXK_NO_DEV)
+ if (state->m_drxk_state == DRXK_NO_DEV)
return -ENODEV;
- if (state->m_DrxkState == DRXK_UNINITIALIZED)
+ if (state->m_drxk_state == DRXK_UNINITIALIZED)
return 0;
- ShutDown(state);
+ shut_down(state);
return 0;
}
@@ -6285,7 +6336,7 @@
dprintk(1, ": %s\n", enable ? "enable" : "disable");
- if (state->m_DrxkState == DRXK_NO_DEV)
+ if (state->m_drxk_state == DRXK_NO_DEV)
return -ENODEV;
return ConfigureI2CBridge(state, enable ? true : false);
@@ -6300,15 +6351,14 @@
dprintk(1, "\n");
- if (state->m_DrxkState == DRXK_NO_DEV)
+ if (state->m_drxk_state == DRXK_NO_DEV)
return -ENODEV;
- if (state->m_DrxkState == DRXK_UNINITIALIZED)
+ if (state->m_drxk_state == DRXK_UNINITIALIZED)
return -EAGAIN;
if (!fe->ops.tuner_ops.get_if_frequency) {
- printk(KERN_ERR
- "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
+ pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
return -EINVAL;
}
@@ -6323,22 +6373,23 @@
state->props = *p;
if (old_delsys != delsys) {
- ShutDown(state);
+ shut_down(state);
switch (delsys) {
case SYS_DVBC_ANNEX_A:
case SYS_DVBC_ANNEX_C:
- if (!state->m_hasDVBC)
+ if (!state->m_has_dvbc)
return -EINVAL;
- state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
+ state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
+ true : false;
if (state->m_itut_annex_c)
- SetOperationMode(state, OM_QAM_ITU_C);
+ setoperation_mode(state, OM_QAM_ITU_C);
else
- SetOperationMode(state, OM_QAM_ITU_A);
+ setoperation_mode(state, OM_QAM_ITU_A);
break;
case SYS_DVBT:
- if (!state->m_hasDVBT)
+ if (!state->m_has_dvbt)
return -EINVAL;
- SetOperationMode(state, OM_DVBT);
+ setoperation_mode(state, OM_DVBT);
break;
default:
return -EINVAL;
@@ -6346,7 +6397,7 @@
}
fe->ops.tuner_ops.get_if_frequency(fe, &IF);
- Start(state, 0, IF);
+ start(state, 0, IF);
/* After set_frontend, stats aren't avaliable */
p->strength.stat[0].scale = FE_SCALE_RELATIVE;
@@ -6366,31 +6417,31 @@
static int get_strength(struct drxk_state *state, u64 *strength)
{
int status;
- struct SCfgAgc rfAgc, ifAgc;
- u32 totalGain = 0;
+ struct s_cfg_agc rf_agc, if_agc;
+ u32 total_gain = 0;
u32 atten = 0;
- u32 agcRange = 0;
+ u32 agc_range = 0;
u16 scu_lvl = 0;
u16 scu_coc = 0;
/* FIXME: those are part of the tuner presets */
- u16 tunerRfGain = 50; /* Default value on az6007 driver */
- u16 tunerIfGain = 40; /* Default value on az6007 driver */
+ u16 tuner_rf_gain = 50; /* Default value on az6007 driver */
+ u16 tuner_if_gain = 40; /* Default value on az6007 driver */
*strength = 0;
- if (IsDVBT(state)) {
- rfAgc = state->m_dvbtRfAgcCfg;
- ifAgc = state->m_dvbtIfAgcCfg;
- } else if (IsQAM(state)) {
- rfAgc = state->m_qamRfAgcCfg;
- ifAgc = state->m_qamIfAgcCfg;
+ if (is_dvbt(state)) {
+ rf_agc = state->m_dvbt_rf_agc_cfg;
+ if_agc = state->m_dvbt_if_agc_cfg;
+ } else if (is_qam(state)) {
+ rf_agc = state->m_qam_rf_agc_cfg;
+ if_agc = state->m_qam_if_agc_cfg;
} else {
- rfAgc = state->m_atvRfAgcCfg;
- ifAgc = state->m_atvIfAgcCfg;
+ rf_agc = state->m_atv_rf_agc_cfg;
+ if_agc = state->m_atv_if_agc_cfg;
}
- if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
- /* SCU outputLevel */
+ if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
+ /* SCU output_level */
status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
if (status < 0)
return status;
@@ -6401,54 +6452,54 @@
return status;
if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
- rfAgc.outputLevel = scu_lvl + scu_coc;
+ rf_agc.output_level = scu_lvl + scu_coc;
else
- rfAgc.outputLevel = 0xffff;
+ rf_agc.output_level = 0xffff;
/* Take RF gain into account */
- totalGain += tunerRfGain;
+ total_gain += tuner_rf_gain;
/* clip output value */
- if (rfAgc.outputLevel < rfAgc.minOutputLevel)
- rfAgc.outputLevel = rfAgc.minOutputLevel;
- if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
- rfAgc.outputLevel = rfAgc.maxOutputLevel;
+ if (rf_agc.output_level < rf_agc.min_output_level)
+ rf_agc.output_level = rf_agc.min_output_level;
+ if (rf_agc.output_level > rf_agc.max_output_level)
+ rf_agc.output_level = rf_agc.max_output_level;
- agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
- if (agcRange > 0) {
+ agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
+ if (agc_range > 0) {
atten += 100UL *
- ((u32)(tunerRfGain)) *
- ((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
- / agcRange;
+ ((u32)(tuner_rf_gain)) *
+ ((u32)(rf_agc.output_level - rf_agc.min_output_level))
+ / agc_range;
}
}
- if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
+ if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
- &ifAgc.outputLevel);
+ &if_agc.output_level);
if (status < 0)
return status;
status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
- &ifAgc.top);
+ &if_agc.top);
if (status < 0)
return status;
/* Take IF gain into account */
- totalGain += (u32) tunerIfGain;
+ total_gain += (u32) tuner_if_gain;
/* clip output value */
- if (ifAgc.outputLevel < ifAgc.minOutputLevel)
- ifAgc.outputLevel = ifAgc.minOutputLevel;
- if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
- ifAgc.outputLevel = ifAgc.maxOutputLevel;
+ if (if_agc.output_level < if_agc.min_output_level)
+ if_agc.output_level = if_agc.min_output_level;
+ if (if_agc.output_level > if_agc.max_output_level)
+ if_agc.output_level = if_agc.max_output_level;
- agcRange = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
- if (agcRange > 0) {
+ agc_range = (u32)(if_agc.max_output_level - if_agc.min_output_level);
+ if (agc_range > 0) {
atten += 100UL *
- ((u32)(tunerIfGain)) *
- ((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
- / agcRange;
+ ((u32)(tuner_if_gain)) *
+ ((u32)(if_agc.output_level - if_agc.min_output_level))
+ / agc_range;
}
}
@@ -6456,8 +6507,8 @@
* Convert to 0..65535 scale.
* If it can't be measured (AGC is disabled), just show 100%.
*/
- if (totalGain > 0)
- *strength = (65535UL * atten / totalGain / 100);
+ if (total_gain > 0)
+ *strength = (65535UL * atten / total_gain / 100);
else
*strength = 65535;
@@ -6480,14 +6531,14 @@
u32 pkt_error_count;
s32 cnr;
- if (state->m_DrxkState == DRXK_NO_DEV)
+ if (state->m_drxk_state == DRXK_NO_DEV)
return -ENODEV;
- if (state->m_DrxkState == DRXK_UNINITIALIZED)
+ if (state->m_drxk_state == DRXK_UNINITIALIZED)
return -EAGAIN;
/* get status */
state->fe_status = 0;
- GetLockStatus(state, &stat);
+ get_lock_status(state, &stat);
if (stat == MPEG_LOCK)
state->fe_status |= 0x1f;
if (stat == FEC_LOCK)
@@ -6503,7 +6554,7 @@
if (stat >= DEMOD_LOCK) {
- GetSignalToNoise(state, &cnr);
+ get_signal_to_noise(state, &cnr);
c->cnr.stat[0].svalue = cnr * 100;
c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
} else {
@@ -6524,9 +6575,11 @@
/* BER measurement is valid if at least FEC lock is achieved */
- /* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
- to set nr of symbols or bits over which
- to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
+ /*
+ * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
+ * written to set nr of symbols or bits over which to measure
+ * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
+ */
/* Read registers for post/preViterbi BER calculation */
status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, ®16);
@@ -6610,9 +6663,9 @@
dprintk(1, "\n");
- if (state->m_DrxkState == DRXK_NO_DEV)
+ if (state->m_drxk_state == DRXK_NO_DEV)
return -ENODEV;
- if (state->m_DrxkState == DRXK_UNINITIALIZED)
+ if (state->m_drxk_state == DRXK_UNINITIALIZED)
return -EAGAIN;
*strength = c->strength.stat[0].uvalue;
@@ -6626,12 +6679,12 @@
dprintk(1, "\n");
- if (state->m_DrxkState == DRXK_NO_DEV)
+ if (state->m_drxk_state == DRXK_NO_DEV)
return -ENODEV;
- if (state->m_DrxkState == DRXK_UNINITIALIZED)
+ if (state->m_drxk_state == DRXK_UNINITIALIZED)
return -EAGAIN;
- GetSignalToNoise(state, &snr2);
+ get_signal_to_noise(state, &snr2);
/* No negative SNR, clip to zero */
if (snr2 < 0)
@@ -6647,27 +6700,27 @@
dprintk(1, "\n");
- if (state->m_DrxkState == DRXK_NO_DEV)
+ if (state->m_drxk_state == DRXK_NO_DEV)
return -ENODEV;
- if (state->m_DrxkState == DRXK_UNINITIALIZED)
+ if (state->m_drxk_state == DRXK_UNINITIALIZED)
return -EAGAIN;
- DVBTQAMGetAccPktErr(state, &err);
+ dvbtqam_get_acc_pkt_err(state, &err);
*ucblocks = (u32) err;
return 0;
}
-static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
- *sets)
+static int drxk_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *sets)
{
struct drxk_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
dprintk(1, "\n");
- if (state->m_DrxkState == DRXK_NO_DEV)
+ if (state->m_drxk_state == DRXK_NO_DEV)
return -ENODEV;
- if (state->m_DrxkState == DRXK_UNINITIALIZED)
+ if (state->m_drxk_state == DRXK_UNINITIALIZED)
return -EAGAIN;
switch (p->delivery_system) {
@@ -6737,36 +6790,36 @@
state->no_i2c_bridge = config->no_i2c_bridge;
state->antenna_gpio = config->antenna_gpio;
state->antenna_dvbt = config->antenna_dvbt;
- state->m_ChunkSize = config->chunk_size;
+ state->m_chunk_size = config->chunk_size;
state->enable_merr_cfg = config->enable_merr_cfg;
if (config->dynamic_clk) {
- state->m_DVBTStaticCLK = 0;
- state->m_DVBCStaticCLK = 0;
+ state->m_dvbt_static_clk = 0;
+ state->m_dvbc_static_clk = 0;
} else {
- state->m_DVBTStaticCLK = 1;
- state->m_DVBCStaticCLK = 1;
+ state->m_dvbt_static_clk = 1;
+ state->m_dvbc_static_clk = 1;
}
if (config->mpeg_out_clk_strength)
- state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
+ state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
else
- state->m_TSClockkStrength = 0x06;
+ state->m_ts_clockk_strength = 0x06;
if (config->parallel_ts)
- state->m_enableParallel = true;
+ state->m_enable_parallel = true;
else
- state->m_enableParallel = false;
+ state->m_enable_parallel = false;
/* NOTE: as more UIO bits will be used, add them to the mask */
- state->UIO_mask = config->antenna_gpio;
+ state->uio_mask = config->antenna_gpio;
/* Default gpio to DVB-C */
if (!state->antenna_dvbt && state->antenna_gpio)
- state->m_GPIO |= state->antenna_gpio;
+ state->m_gpio |= state->antenna_gpio;
else
- state->m_GPIO &= ~state->antenna_gpio;
+ state->m_gpio &= ~state->antenna_gpio;
mutex_init(&state->mutex);
@@ -6792,8 +6845,7 @@
GFP_KERNEL,
state, load_firmware_cb);
if (status < 0) {
- printk(KERN_ERR
- "drxk: failed to request a firmware\n");
+ pr_err("failed to request a firmware\n");
return NULL;
}
}
@@ -6821,11 +6873,11 @@
p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
- printk(KERN_INFO "drxk: frontend initialized.\n");
+ pr_info("frontend initialized.\n");
return &state->frontend;
error:
- printk(KERN_ERR "drxk: not found\n");
+ pr_err("not found\n");
kfree(state);
return NULL;
}
diff --git a/drivers/media/dvb-frontends/drxk_hard.h b/drivers/media/dvb-frontends/drxk_hard.h
index b8424f1..bae9c71 100644
--- a/drivers/media/dvb-frontends/drxk_hard.h
+++ b/drivers/media/dvb-frontends/drxk_hard.h
@@ -46,7 +46,7 @@
#define IQM_RC_ADJ_SEL_B_QAM 0x1
#define IQM_RC_ADJ_SEL_B_VSB 0x2
-enum OperationMode {
+enum operation_mode {
OM_NONE,
OM_QAM_ITU_A,
OM_QAM_ITU_B,
@@ -54,7 +54,7 @@
OM_DVBT
};
-enum DRXPowerMode {
+enum drx_power_mode {
DRX_POWER_UP = 0,
DRX_POWER_MODE_1,
DRX_POWER_MODE_2,
@@ -77,24 +77,29 @@
};
-/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
+/* Intermediate power mode for DRXK, power down OFDM clock domain */
#ifndef DRXK_POWER_DOWN_OFDM
#define DRXK_POWER_DOWN_OFDM DRX_POWER_MODE_1
#endif
-/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
+/* Intermediate power mode for DRXK, power down core (sysclk) */
#ifndef DRXK_POWER_DOWN_CORE
#define DRXK_POWER_DOWN_CORE DRX_POWER_MODE_9
#endif
-/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
+/* Intermediate power mode for DRXK, power down pll (only osc runs) */
#ifndef DRXK_POWER_DOWN_PLL
#define DRXK_POWER_DOWN_PLL DRX_POWER_MODE_10
#endif
-enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
-enum EDrxkState {
+enum agc_ctrl_mode {
+ DRXK_AGC_CTRL_AUTO = 0,
+ DRXK_AGC_CTRL_USER,
+ DRXK_AGC_CTRL_OFF
+};
+
+enum e_drxk_state {
DRXK_UNINITIALIZED = 0,
DRXK_STOPPED,
DRXK_DTV_STARTED,
@@ -103,7 +108,7 @@
DRXK_NO_DEV /* If drxk init failed */
};
-enum EDrxkCoefArrayIndex {
+enum e_drxk_coef_array_index {
DRXK_COEF_IDX_MN = 0,
DRXK_COEF_IDX_FM ,
DRXK_COEF_IDX_L ,
@@ -113,13 +118,13 @@
DRXK_COEF_IDX_I ,
DRXK_COEF_IDX_MAX
};
-enum EDrxkSifAttenuation {
+enum e_drxk_sif_attenuation {
DRXK_SIF_ATTENUATION_0DB,
DRXK_SIF_ATTENUATION_3DB,
DRXK_SIF_ATTENUATION_6DB,
DRXK_SIF_ATTENUATION_9DB
};
-enum EDrxkConstellation {
+enum e_drxk_constellation {
DRX_CONSTELLATION_BPSK = 0,
DRX_CONSTELLATION_QPSK,
DRX_CONSTELLATION_PSK8,
@@ -133,7 +138,7 @@
DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
DRX_CONSTELLATION_AUTO = DRX_AUTO
};
-enum EDrxkInterleaveMode {
+enum e_drxk_interleave_mode {
DRXK_QAM_I12_J17 = 16,
DRXK_QAM_I_UNKNOWN = DRX_UNKNOWN
};
@@ -144,14 +149,14 @@
DRXK_SPIN_UNKNOWN
};
-enum DRXKCfgDvbtSqiSpeed {
+enum drxk_cfg_dvbt_sqi_speed {
DRXK_DVBT_SQI_SPEED_FAST = 0,
DRXK_DVBT_SQI_SPEED_MEDIUM,
DRXK_DVBT_SQI_SPEED_SLOW,
DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
} ;
-enum DRXFftmode_t {
+enum drx_fftmode_t {
DRX_FFTMODE_2K = 0,
DRX_FFTMODE_4K,
DRX_FFTMODE_8K,
@@ -159,47 +164,47 @@
DRX_FFTMODE_AUTO = DRX_AUTO
};
-enum DRXMPEGStrWidth_t {
+enum drxmpeg_str_width_t {
DRX_MPEG_STR_WIDTH_1,
DRX_MPEG_STR_WIDTH_8
};
-enum DRXQamLockRange_t {
+enum drx_qam_lock_range_t {
DRX_QAM_LOCKRANGE_NORMAL,
DRX_QAM_LOCKRANGE_EXTENDED
};
-struct DRXKCfgDvbtEchoThres_t {
+struct drxk_cfg_dvbt_echo_thres_t {
u16 threshold;
- enum DRXFftmode_t fftMode;
+ enum drx_fftmode_t fft_mode;
} ;
-struct SCfgAgc {
- enum AGC_CTRL_MODE ctrlMode; /* off, user, auto */
- u16 outputLevel; /* range dependent on AGC */
- u16 minOutputLevel; /* range dependent on AGC */
- u16 maxOutputLevel; /* range dependent on AGC */
+struct s_cfg_agc {
+ enum agc_ctrl_mode ctrl_mode; /* off, user, auto */
+ u16 output_level; /* range dependent on AGC */
+ u16 min_output_level; /* range dependent on AGC */
+ u16 max_output_level; /* range dependent on AGC */
u16 speed; /* range dependent on AGC */
u16 top; /* rf-agc take over point */
- u16 cutOffCurrent; /* rf-agc is accelerated if output current
+ u16 cut_off_current; /* rf-agc is accelerated if output current
is below cut-off current */
- u16 IngainTgtMax;
- u16 FastClipCtrlDelay;
+ u16 ingain_tgt_max;
+ u16 fast_clip_ctrl_delay;
};
-struct SCfgPreSaw {
+struct s_cfg_pre_saw {
u16 reference; /* pre SAW reference value, range 0 .. 31 */
- bool usePreSaw; /* TRUE algorithms must use pre SAW sense */
+ bool use_pre_saw; /* TRUE algorithms must use pre SAW sense */
};
-struct DRXKOfdmScCmd_t {
- u16 cmd; /**< Command number */
- u16 subcmd; /**< Sub-command parameter*/
- u16 param0; /**< General purpous param */
- u16 param1; /**< General purpous param */
- u16 param2; /**< General purpous param */
- u16 param3; /**< General purpous param */
- u16 param4; /**< General purpous param */
+struct drxk_ofdm_sc_cmd_t {
+ u16 cmd; /* Command number */
+ u16 subcmd; /* Sub-command parameter*/
+ u16 param0; /* General purpous param */
+ u16 param1; /* General purpous param */
+ u16 param2; /* General purpous param */
+ u16 param3; /* General purpous param */
+ u16 param4; /* General purpous param */
};
struct drxk_state {
@@ -213,121 +218,121 @@
struct mutex mutex;
- u32 m_Instance; /**< Channel 1,2,3 or 4 */
+ u32 m_instance; /* Channel 1,2,3 or 4 */
- int m_ChunkSize;
- u8 Chunk[256];
+ int m_chunk_size;
+ u8 chunk[256];
- bool m_hasLNA;
- bool m_hasDVBT;
- bool m_hasDVBC;
- bool m_hasAudio;
- bool m_hasATV;
- bool m_hasOOB;
- bool m_hasSAWSW; /**< TRUE if mat_tx is available */
- bool m_hasGPIO1; /**< TRUE if mat_rx is available */
- bool m_hasGPIO2; /**< TRUE if GPIO is available */
- bool m_hasIRQN; /**< TRUE if IRQN is available */
- u16 m_oscClockFreq;
- u16 m_HICfgTimingDiv;
- u16 m_HICfgBridgeDelay;
- u16 m_HICfgWakeUpKey;
- u16 m_HICfgTimeout;
- u16 m_HICfgCtrl;
- s32 m_sysClockFreq; /**< system clock frequency in kHz */
+ bool m_has_lna;
+ bool m_has_dvbt;
+ bool m_has_dvbc;
+ bool m_has_audio;
+ bool m_has_atv;
+ bool m_has_oob;
+ bool m_has_sawsw; /* TRUE if mat_tx is available */
+ bool m_has_gpio1; /* TRUE if mat_rx is available */
+ bool m_has_gpio2; /* TRUE if GPIO is available */
+ bool m_has_irqn; /* TRUE if IRQN is available */
+ u16 m_osc_clock_freq;
+ u16 m_hi_cfg_timing_div;
+ u16 m_hi_cfg_bridge_delay;
+ u16 m_hi_cfg_wake_up_key;
+ u16 m_hi_cfg_timeout;
+ u16 m_hi_cfg_ctrl;
+ s32 m_sys_clock_freq; /* system clock frequency in kHz */
- enum EDrxkState m_DrxkState; /**< State of Drxk (init,stopped,started) */
- enum OperationMode m_OperationMode; /**< digital standards */
- struct SCfgAgc m_vsbRfAgcCfg; /**< settings for VSB RF-AGC */
- struct SCfgAgc m_vsbIfAgcCfg; /**< settings for VSB IF-AGC */
- u16 m_vsbPgaCfg; /**< settings for VSB PGA */
- struct SCfgPreSaw m_vsbPreSawCfg; /**< settings for pre SAW sense */
- s32 m_Quality83percent; /**< MER level (*0.1 dB) for 83% quality indication */
- s32 m_Quality93percent; /**< MER level (*0.1 dB) for 93% quality indication */
- bool m_smartAntInverted;
- bool m_bDebugEnableBridge;
- bool m_bPDownOpenBridge; /**< only open DRXK bridge before power-down once it has been accessed */
- bool m_bPowerDown; /**< Power down when not used */
+ enum e_drxk_state m_drxk_state; /* State of Drxk (init,stopped,started) */
+ enum operation_mode m_operation_mode; /* digital standards */
+ struct s_cfg_agc m_vsb_rf_agc_cfg; /* settings for VSB RF-AGC */
+ struct s_cfg_agc m_vsb_if_agc_cfg; /* settings for VSB IF-AGC */
+ u16 m_vsb_pga_cfg; /* settings for VSB PGA */
+ struct s_cfg_pre_saw m_vsb_pre_saw_cfg; /* settings for pre SAW sense */
+ s32 m_Quality83percent; /* MER level (*0.1 dB) for 83% quality indication */
+ s32 m_Quality93percent; /* MER level (*0.1 dB) for 93% quality indication */
+ bool m_smart_ant_inverted;
+ bool m_b_debug_enable_bridge;
+ bool m_b_p_down_open_bridge; /* only open DRXK bridge before power-down once it has been accessed */
+ bool m_b_power_down; /* Power down when not used */
- u32 m_IqmFsRateOfs; /**< frequency shift as written to DRXK register (28bit fixpoint) */
+ u32 m_iqm_fs_rate_ofs; /* frequency shift as written to DRXK register (28bit fixpoint) */
- bool m_enableMPEGOutput; /**< If TRUE, enable MPEG output */
- bool m_insertRSByte; /**< If TRUE, insert RS byte */
- bool m_enableParallel; /**< If TRUE, parallel out otherwise serial */
- bool m_invertDATA; /**< If TRUE, invert DATA signals */
- bool m_invertERR; /**< If TRUE, invert ERR signal */
- bool m_invertSTR; /**< If TRUE, invert STR signals */
- bool m_invertVAL; /**< If TRUE, invert VAL signals */
- bool m_invertCLK; /**< If TRUE, invert CLK signals */
- bool m_DVBCStaticCLK;
- bool m_DVBTStaticCLK; /**< If TRUE, static MPEG clockrate will
+ bool m_enable_mpeg_output; /* If TRUE, enable MPEG output */
+ bool m_insert_rs_byte; /* If TRUE, insert RS byte */
+ bool m_enable_parallel; /* If TRUE, parallel out otherwise serial */
+ bool m_invert_data; /* If TRUE, invert DATA signals */
+ bool m_invert_err; /* If TRUE, invert ERR signal */
+ bool m_invert_str; /* If TRUE, invert STR signals */
+ bool m_invert_val; /* If TRUE, invert VAL signals */
+ bool m_invert_clk; /* If TRUE, invert CLK signals */
+ bool m_dvbc_static_clk;
+ bool m_dvbt_static_clk; /* If TRUE, static MPEG clockrate will
be used, otherwise clockrate will
adapt to the bitrate of the TS */
- u32 m_DVBTBitrate;
- u32 m_DVBCBitrate;
+ u32 m_dvbt_bitrate;
+ u32 m_dvbc_bitrate;
- u8 m_TSDataStrength;
- u8 m_TSClockkStrength;
+ u8 m_ts_data_strength;
+ u8 m_ts_clockk_strength;
bool m_itut_annex_c; /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */
- enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width */
- u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case
+ enum drxmpeg_str_width_t m_width_str; /* MPEG start width */
+ u32 m_mpeg_ts_static_bitrate; /* Maximum bitrate in b/s in case
static clockrate is selected */
- /* LARGE_INTEGER m_StartTime; */ /**< Contains the time of the last demod start */
- s32 m_MpegLockTimeOut; /**< WaitForLockStatus Timeout (counts from start time) */
- s32 m_DemodLockTimeOut; /**< WaitForLockStatus Timeout (counts from start time) */
+ /* LARGE_INTEGER m_startTime; */ /* Contains the time of the last demod start */
+ s32 m_mpeg_lock_time_out; /* WaitForLockStatus Timeout (counts from start time) */
+ s32 m_demod_lock_time_out; /* WaitForLockStatus Timeout (counts from start time) */
- bool m_disableTEIhandling;
+ bool m_disable_te_ihandling;
- bool m_RfAgcPol;
- bool m_IfAgcPol;
+ bool m_rf_agc_pol;
+ bool m_if_agc_pol;
- struct SCfgAgc m_atvRfAgcCfg; /**< settings for ATV RF-AGC */
- struct SCfgAgc m_atvIfAgcCfg; /**< settings for ATV IF-AGC */
- struct SCfgPreSaw m_atvPreSawCfg; /**< settings for ATV pre SAW sense */
- bool m_phaseCorrectionBypass;
- s16 m_atvTopVidPeak;
- u16 m_atvTopNoiseTh;
- enum EDrxkSifAttenuation m_sifAttenuation;
- bool m_enableCVBSOutput;
- bool m_enableSIFOutput;
- bool m_bMirrorFreqSpect;
- enum EDrxkConstellation m_Constellation; /**< Constellation type of the channel */
- u32 m_CurrSymbolRate; /**< Current QAM symbol rate */
- struct SCfgAgc m_qamRfAgcCfg; /**< settings for QAM RF-AGC */
- struct SCfgAgc m_qamIfAgcCfg; /**< settings for QAM IF-AGC */
- u16 m_qamPgaCfg; /**< settings for QAM PGA */
- struct SCfgPreSaw m_qamPreSawCfg; /**< settings for QAM pre SAW sense */
- enum EDrxkInterleaveMode m_qamInterleaveMode; /**< QAM Interleave mode */
- u16 m_fecRsPlen;
- u16 m_fecRsPrescale;
+ struct s_cfg_agc m_atv_rf_agc_cfg; /* settings for ATV RF-AGC */
+ struct s_cfg_agc m_atv_if_agc_cfg; /* settings for ATV IF-AGC */
+ struct s_cfg_pre_saw m_atv_pre_saw_cfg; /* settings for ATV pre SAW sense */
+ bool m_phase_correction_bypass;
+ s16 m_atv_top_vid_peak;
+ u16 m_atv_top_noise_th;
+ enum e_drxk_sif_attenuation m_sif_attenuation;
+ bool m_enable_cvbs_output;
+ bool m_enable_sif_output;
+ bool m_b_mirror_freq_spect;
+ enum e_drxk_constellation m_constellation; /* constellation type of the channel */
+ u32 m_curr_symbol_rate; /* Current QAM symbol rate */
+ struct s_cfg_agc m_qam_rf_agc_cfg; /* settings for QAM RF-AGC */
+ struct s_cfg_agc m_qam_if_agc_cfg; /* settings for QAM IF-AGC */
+ u16 m_qam_pga_cfg; /* settings for QAM PGA */
+ struct s_cfg_pre_saw m_qam_pre_saw_cfg; /* settings for QAM pre SAW sense */
+ enum e_drxk_interleave_mode m_qam_interleave_mode; /* QAM Interleave mode */
+ u16 m_fec_rs_plen;
+ u16 m_fec_rs_prescale;
- enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
+ enum drxk_cfg_dvbt_sqi_speed m_sqi_speed;
- u16 m_GPIO;
- u16 m_GPIOCfg;
+ u16 m_gpio;
+ u16 m_gpio_cfg;
- struct SCfgAgc m_dvbtRfAgcCfg; /**< settings for QAM RF-AGC */
- struct SCfgAgc m_dvbtIfAgcCfg; /**< settings for QAM IF-AGC */
- struct SCfgPreSaw m_dvbtPreSawCfg; /**< settings for QAM pre SAW sense */
+ struct s_cfg_agc m_dvbt_rf_agc_cfg; /* settings for QAM RF-AGC */
+ struct s_cfg_agc m_dvbt_if_agc_cfg; /* settings for QAM IF-AGC */
+ struct s_cfg_pre_saw m_dvbt_pre_saw_cfg; /* settings for QAM pre SAW sense */
- u16 m_agcFastClipCtrlDelay;
- bool m_adcCompPassed;
+ u16 m_agcfast_clip_ctrl_delay;
+ bool m_adc_comp_passed;
u16 m_adcCompCoef[64];
- u16 m_adcState;
+ u16 m_adc_state;
u8 *m_microcode;
int m_microcode_length;
- bool m_DRXK_A3_ROM_CODE;
- bool m_DRXK_A3_PATCH_CODE;
+ bool m_drxk_a3_rom_code;
+ bool m_drxk_a3_patch_code;
bool m_rfmirror;
- u8 m_deviceSpin;
- u32 m_iqmRcRate;
+ u8 m_device_spin;
+ u32 m_iqm_rc_rate;
- enum DRXPowerMode m_currentPowerMode;
+ enum drx_power_mode m_current_power_mode;
/* when true, avoids other devices to use the I2C bus */
bool drxk_i2c_exclusive_lock;
@@ -337,7 +342,7 @@
* at struct drxk_config.
*/
- u16 UIO_mask; /* Bits used by UIO */
+ u16 uio_mask; /* Bits used by UIO */
bool enable_merr_cfg;
bool single_master;
diff --git a/drivers/media/dvb-frontends/stb0899_algo.c b/drivers/media/dvb-frontends/stb0899_algo.c
index 117a569..93596e0 100644
--- a/drivers/media/dvb-frontends/stb0899_algo.c
+++ b/drivers/media/dvb-frontends/stb0899_algo.c
@@ -226,8 +226,8 @@
next_loop--;
if (next_loop) {
- STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
- STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
}
internal->direction = -internal->direction; /* Change zigzag direction */
@@ -235,7 +235,7 @@
if (internal->status == TIMINGOK) {
stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
- internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+ internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
}
@@ -306,8 +306,8 @@
STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
stb0899_write_reg(state, STB0899_CFD, reg);
- STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
- STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
}
}
@@ -317,7 +317,7 @@
if (internal->status == CARRIEROK) {
stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
- internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+ internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
} else {
internal->derot_freq = last_derot_freq;
@@ -412,8 +412,8 @@
STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
stb0899_write_reg(state, STB0899_CFD, reg);
- STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
- STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+ STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
stb0899_check_carrier(state);
@@ -425,7 +425,15 @@
if (internal->status == DATAOK) {
stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
- internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+
+ /* store autodetected IQ swapping as default for DVB-S2 tuning */
+ reg = stb0899_read_reg(state, STB0899_IQSWAP);
+ if (STB0899_GETFIELD(SYM, reg))
+ internal->inversion = IQ_SWAP_ON;
+ else
+ internal->inversion = IQ_SWAP_OFF;
+
+ internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
}
@@ -444,7 +452,7 @@
int range_offst, tp_freq;
range_offst = internal->srch_range / 2000;
- tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
+ tp_freq = internal->freq - (internal->derot_freq * internal->mclk) / 1000;
if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
internal->status = RANGEOK;
@@ -638,7 +646,7 @@
"RANGE OK ! derot freq=%d, mclk=%d",
internal->derot_freq, internal->mclk);
- internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
+ internal->freq = params->freq - ((internal->derot_freq * internal->mclk) / 1000);
reg = stb0899_read_reg(state, STB0899_PLPARM);
internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
dprintk(state->verbose, FE_DEBUG, 1,
@@ -1373,9 +1381,6 @@
case IQ_SWAP_ON:
STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
break;
- case IQ_SWAP_AUTO: /* use last successful search first */
- STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
- break;
}
stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
stb0899_dvbs2_reacquire(state);
@@ -1405,41 +1410,39 @@
}
if (internal->status != DVBS2_FEC_LOCK) {
- if (internal->inversion == IQ_SWAP_AUTO) {
- reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
- iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
- /* IQ Spectrum Inversion */
- STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
- stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
- /* start acquistion process */
- stb0899_dvbs2_reacquire(state);
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+ iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
+ /* IQ Spectrum Inversion */
+ STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+ /* start acquistion process */
+ stb0899_dvbs2_reacquire(state);
- /* Wait for demod lock (UWP and CSM) */
- internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
- if (internal->status == DVBS2_DEMOD_LOCK) {
- i = 0;
- /* Demod Locked, check FEC */
- internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
- /*try thrice for false locks, (UWP and CSM Locked but no FEC) */
- while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
- /* Read the frequency offset*/
- offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+ /* Wait for demod lock (UWP and CSM) */
+ internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+ if (internal->status == DVBS2_DEMOD_LOCK) {
+ i = 0;
+ /* Demod Locked, check FEC */
+ internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+ /*try thrice for false locks, (UWP and CSM Locked but no FEC) */
+ while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+ /* Read the frequency offset*/
+ offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
- /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
- reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
- STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
- stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+ /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+ reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+ STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+ stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
- stb0899_dvbs2_reacquire(state);
- internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
- i++;
- }
+ stb0899_dvbs2_reacquire(state);
+ internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+ i++;
}
-/*
- if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
- pParams->IQLocked = !iqSpectrum;
-*/
}
+/*
+ if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
+ pParams->IQLocked = !iqSpectrum;
+*/
}
if (internal->status == DVBS2_FEC_LOCK) {
dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
@@ -1487,13 +1490,21 @@
/* Store signal parameters */
offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+ /* sign extend 30 bit value before using it in calculations */
+ if (offsetfreq & (1 << 29))
+ offsetfreq |= -1 << 30;
+
offsetfreq = offsetfreq / ((1 << 30) / 1000);
offsetfreq *= (internal->master_clk / 1000000);
+
+ /* store current inversion for next run */
reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
- offsetfreq *= -1;
+ internal->inversion = IQ_SWAP_ON;
+ else
+ internal->inversion = IQ_SWAP_OFF;
- internal->freq = internal->freq - offsetfreq;
+ internal->freq = internal->freq + offsetfreq;
internal->srate = stb0899_dvbs2_get_srate(state);
reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
index cc278b3..3dd5714 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.c
+++ b/drivers/media/dvb-frontends/stb0899_drv.c
@@ -1618,19 +1618,18 @@
struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
{
struct stb0899_state *state = NULL;
- enum stb0899_inversion inversion;
state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
if (state == NULL)
goto error;
- inversion = config->inversion;
state->verbose = &verbose;
state->config = config;
state->i2c = i2c;
state->frontend.ops = stb0899_ops;
state->frontend.demodulator_priv = state;
- state->internal.inversion = inversion;
+ /* use configured inversion as default -- we'll later autodetect inversion */
+ state->internal.inversion = config->inversion;
stb0899_wakeup(&state->frontend);
if (stb0899_get_dev_id(state) == -ENODEV) {
diff --git a/drivers/media/dvb-frontends/stb0899_drv.h b/drivers/media/dvb-frontends/stb0899_drv.h
index 8d26ff6..139264d 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.h
+++ b/drivers/media/dvb-frontends/stb0899_drv.h
@@ -45,9 +45,8 @@
};
enum stb0899_inversion {
- IQ_SWAP_OFF = 0,
- IQ_SWAP_ON,
- IQ_SWAP_AUTO
+ IQ_SWAP_OFF = +1, /* inversion affects the sign of e. g. */
+ IQ_SWAP_ON = -1, /* the derotator frequency register */
};
#define STB0899_GPIO00 0xf140
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index f981d50..b2cd8ca 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -245,6 +245,15 @@
To compile this driver as a module, choose M here: the
module will be called ks0127.
+config VIDEO_ML86V7667
+ tristate "OKI ML86V7667 video decoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the OKI Semiconductor ML86V7667 video decoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ml86v7667.
+
config VIDEO_SAA7110
tristate "Philips SAA7110 video decoder"
depends on VIDEO_V4L2 && I2C
@@ -425,6 +434,15 @@
help
Video output driver for AKM AK8813 and AK8814 TV encoders
+config VIDEO_THS8200
+ tristate "Texas Instruments THS8200 video encoder"
+ depends on VIDEO_V4L2 && I2C
+ ---help---
+ Support for the Texas Instruments THS8200 video encoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ths8200.
+
comment "Camera sensor devices"
config VIDEO_APTINA_PLL
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 720f42d..dc20653 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -34,6 +34,7 @@
obj-$(CONFIG_VIDEO_BT866) += bt866.o
obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
+obj-$(CONFIG_VIDEO_THS8200) += ths8200.o
obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
@@ -70,3 +71,4 @@
obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
+obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index 58344b6..ba4364d 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -32,7 +32,6 @@
#include <linux/workqueue.h>
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/ad9389b.h>
@@ -343,12 +342,6 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int ad9389b_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = ad9389b_rd(sd, reg->reg & 0xff);
reg->size = 1;
return 0;
@@ -356,24 +349,11 @@
static int ad9389b_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
ad9389b_wr(sd, reg->reg & 0xff, reg->val & 0xff);
return 0;
}
#endif
-static int ad9389b_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_AD9389B, 0);
-}
-
static int ad9389b_log_status(struct v4l2_subdev *sd)
{
struct ad9389b_state *state = get_ad9389b_state(sd);
@@ -600,7 +580,6 @@
static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
.log_status = ad9389b_log_status,
- .g_chip_ident = ad9389b_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ad9389b_g_register,
.s_register = ad9389b_s_register,
@@ -1188,15 +1167,14 @@
v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n",
client->addr << 1);
- state = kzalloc(sizeof(struct ad9389b_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
/* Platform data */
if (pdata == NULL) {
v4l_err(client, "No platform data!\n");
- err = -ENODEV;
- goto err_free;
+ return -ENODEV;
}
memcpy(&state->pdata, pdata, sizeof(state->pdata));
@@ -1251,12 +1229,14 @@
state->edid_i2c_client = i2c_new_dummy(client->adapter, (0x7e>>1));
if (state->edid_i2c_client == NULL) {
v4l2_err(sd, "failed to register edid i2c client\n");
+ err = -ENOMEM;
goto err_entity;
}
state->work_queue = create_singlethread_workqueue(sd->name);
if (state->work_queue == NULL) {
v4l2_err(sd, "could not create workqueue\n");
+ err = -ENOMEM;
goto err_unreg;
}
@@ -1276,8 +1256,6 @@
media_entity_cleanup(&sd->entity);
err_hdl:
v4l2_ctrl_handler_free(&state->hdl);
-err_free:
- kfree(state);
return err;
}
@@ -1302,15 +1280,14 @@
v4l2_device_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- kfree(get_ad9389b_state(sd));
return 0;
}
/* ----------------------------------------------------------------------- */
static struct i2c_device_id ad9389b_id[] = {
- { "ad9389b", V4L2_IDENT_AD9389B },
- { "ad9889b", V4L2_IDENT_AD9389B },
+ { "ad9389b", 0 },
+ { "ad9889b", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad9389b_id);
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c
index ef75abe..873fe19 100644
--- a/drivers/media/i2c/adp1653.c
+++ b/drivers/media/i2c/adp1653.c
@@ -417,7 +417,7 @@
if (client->dev.platform_data == NULL)
return -ENODEV;
- flash = kzalloc(sizeof(*flash), GFP_KERNEL);
+ flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
if (flash == NULL)
return -ENOMEM;
@@ -443,7 +443,6 @@
free_and_quit:
v4l2_ctrl_handler_free(&flash->ctrls);
- kfree(flash);
return ret;
}
@@ -455,7 +454,7 @@
v4l2_device_unregister_subdev(&flash->subdev);
v4l2_ctrl_handler_free(&flash->ctrls);
media_entity_cleanup(&flash->subdev.entity);
- kfree(flash);
+
return 0;
}
diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c
index 6bc01fb..04bb297 100644
--- a/drivers/media/i2c/adv7170.c
+++ b/drivers/media/i2c/adv7170.c
@@ -36,7 +36,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
MODULE_AUTHOR("Maxim Yevtyushkin");
@@ -317,19 +316,8 @@
return ret;
}
-static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7170, 0);
-}
-
/* ----------------------------------------------------------------------- */
-static const struct v4l2_subdev_core_ops adv7170_core_ops = {
- .g_chip_ident = adv7170_g_chip_ident,
-};
-
static const struct v4l2_subdev_video_ops adv7170_video_ops = {
.s_std_output = adv7170_s_std_output,
.s_routing = adv7170_s_routing,
@@ -339,7 +327,6 @@
};
static const struct v4l2_subdev_ops adv7170_ops = {
- .core = &adv7170_core_ops,
.video = &adv7170_video_ops,
};
@@ -359,7 +346,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
+ encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
sd = &encoder->sd;
@@ -384,7 +371,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_adv7170(sd));
return 0;
}
diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c
index c7640fa..b88f3b3 100644
--- a/drivers/media/i2c/adv7175.c
+++ b/drivers/media/i2c/adv7175.c
@@ -32,7 +32,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
MODULE_AUTHOR("Dave Perks");
@@ -355,13 +354,6 @@
return ret;
}
-static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
-}
-
static int adv7175_s_power(struct v4l2_subdev *sd, int on)
{
if (on)
@@ -375,7 +367,6 @@
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops adv7175_core_ops = {
- .g_chip_ident = adv7175_g_chip_ident,
.init = adv7175_init,
.s_power = adv7175_s_power,
};
@@ -409,7 +400,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
+ encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
sd = &encoder->sd;
@@ -434,7 +425,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_adv7175(sd));
return 0;
}
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index afd561a..d7d99f1 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1,6 +1,8 @@
/*
* adv7180.c Analog Devices ADV7180 video decoder driver
* Copyright (c) 2009 Intel Corporation
+ * Copyright (C) 2013 Cogent Embedded, Inc.
+ * Copyright (C) 2013 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -27,7 +29,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
#include <linux/mutex.h>
#define ADV7180_INPUT_CONTROL_REG 0x00
@@ -272,14 +273,6 @@
return ret;
}
-static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
-}
-
static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{
struct adv7180_state *state = to_state(sd);
@@ -397,14 +390,57 @@
v4l2_ctrl_handler_free(&state->ctrl_hdl);
}
+static int adv7180_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+ enum v4l2_mbus_pixelcode *code)
+{
+ if (index > 0)
+ return -EINVAL;
+
+ *code = V4L2_MBUS_FMT_YUYV8_2X8;
+
+ return 0;
+}
+
+static int adv7180_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ struct adv7180_state *state = to_state(sd);
+
+ fmt->code = V4L2_MBUS_FMT_YUYV8_2X8;
+ fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ fmt->field = V4L2_FIELD_INTERLACED;
+ fmt->width = 720;
+ fmt->height = state->curr_norm & V4L2_STD_525_60 ? 480 : 576;
+
+ return 0;
+}
+
+static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
+ struct v4l2_mbus_config *cfg)
+{
+ /*
+ * The ADV7180 sensor supports BT.601/656 output modes.
+ * The BT.656 is default and not yet configurable by s/w.
+ */
+ cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+ V4L2_MBUS_DATA_ACTIVE_HIGH;
+ cfg->type = V4L2_MBUS_BT656;
+
+ return 0;
+}
+
static const struct v4l2_subdev_video_ops adv7180_video_ops = {
.querystd = adv7180_querystd,
.g_input_status = adv7180_g_input_status,
.s_routing = adv7180_s_routing,
+ .enum_mbus_fmt = adv7180_enum_mbus_fmt,
+ .try_mbus_fmt = adv7180_mbus_fmt,
+ .g_mbus_fmt = adv7180_mbus_fmt,
+ .s_mbus_fmt = adv7180_mbus_fmt,
+ .g_mbus_config = adv7180_g_mbus_config,
};
static const struct v4l2_subdev_core_ops adv7180_core_ops = {
- .g_chip_ident = adv7180_g_chip_ident,
.s_std = adv7180_s_std,
};
@@ -555,7 +591,7 @@
v4l_info(client, "chip found @ 0x%02x (%s)\n",
client->addr, client->adapter->name);
- state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL) {
ret = -ENOMEM;
goto err;
@@ -582,7 +618,6 @@
err_unreg_subdev:
mutex_destroy(&state->mutex);
v4l2_device_unregister_subdev(sd);
- kfree(state);
err:
printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret);
return ret;
@@ -607,7 +642,6 @@
mutex_destroy(&state->mutex);
v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
return 0;
}
@@ -616,9 +650,10 @@
{},
};
-#ifdef CONFIG_PM
-static int adv7180_suspend(struct i2c_client *client, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int adv7180_suspend(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
int ret;
ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
@@ -628,8 +663,9 @@
return 0;
}
-static int adv7180_resume(struct i2c_client *client)
+static int adv7180_resume(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct adv7180_state *state = to_state(sd);
int ret;
@@ -643,6 +679,12 @@
return ret;
return 0;
}
+
+static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
+#define ADV7180_PM_OPS (&adv7180_pm_ops)
+
+#else
+#define ADV7180_PM_OPS NULL
#endif
MODULE_DEVICE_TABLE(i2c, adv7180_id);
@@ -651,13 +693,10 @@
.driver = {
.owner = THIS_MODULE,
.name = KBUILD_MODNAME,
+ .pm = ADV7180_PM_OPS,
},
.probe = adv7180_probe,
.remove = adv7180_remove,
-#ifdef CONFIG_PM
- .suspend = adv7180_suspend,
- .resume = adv7180_resume,
-#endif
.id_table = adv7180_id,
};
diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c
index 56a1fa4..6f738d8 100644
--- a/drivers/media/i2c/adv7183.c
+++ b/drivers/media/i2c/adv7183.c
@@ -28,7 +28,6 @@
#include <linux/videodev2.h>
#include <media/adv7183.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -375,28 +374,28 @@
reg = adv7183_read(sd, ADV7183_STATUS_1);
switch ((reg >> 0x4) & 0x7) {
case 0:
- *std = V4L2_STD_NTSC;
+ *std &= V4L2_STD_NTSC;
break;
case 1:
- *std = V4L2_STD_NTSC_443;
+ *std &= V4L2_STD_NTSC_443;
break;
case 2:
- *std = V4L2_STD_PAL_M;
+ *std &= V4L2_STD_PAL_M;
break;
case 3:
- *std = V4L2_STD_PAL_60;
+ *std &= V4L2_STD_PAL_60;
break;
case 4:
- *std = V4L2_STD_PAL;
+ *std &= V4L2_STD_PAL;
break;
case 5:
- *std = V4L2_STD_SECAM;
+ *std &= V4L2_STD_SECAM;
break;
case 6:
- *std = V4L2_STD_PAL_Nc;
+ *std &= V4L2_STD_PAL_Nc;
break;
case 7:
- *std = V4L2_STD_SECAM;
+ *std &= V4L2_STD_SECAM;
break;
default:
*std = V4L2_STD_UNKNOWN;
@@ -474,34 +473,16 @@
struct adv7183 *decoder = to_adv7183(sd);
if (enable)
- gpio_direction_output(decoder->oe_pin, 0);
+ gpio_set_value(decoder->oe_pin, 0);
else
- gpio_direction_output(decoder->oe_pin, 1);
+ gpio_set_value(decoder->oe_pin, 1);
udelay(1);
return 0;
}
-static int adv7183_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- int rev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- /* 0x11 for adv7183, 0x13 for adv7183b */
- rev = adv7183_read(sd, ADV7183_IDENT);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7183, rev);
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int adv7183_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = adv7183_read(sd, reg->reg & 0xff);
reg->size = 1;
return 0;
@@ -509,12 +490,6 @@
static int adv7183_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
adv7183_write(sd, reg->reg & 0xff, reg->val & 0xff);
return 0;
}
@@ -529,7 +504,6 @@
.g_std = adv7183_g_std,
.s_std = adv7183_s_std,
.reset = adv7183_reset,
- .g_chip_ident = adv7183_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = adv7183_g_register,
.s_register = adv7183_s_register,
@@ -573,23 +547,24 @@
if (pin_array == NULL)
return -EINVAL;
- decoder = kzalloc(sizeof(struct adv7183), GFP_KERNEL);
+ decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
decoder->reset_pin = pin_array[0];
decoder->oe_pin = pin_array[1];
- if (gpio_request(decoder->reset_pin, "ADV7183 Reset")) {
+ if (devm_gpio_request_one(&client->dev, decoder->reset_pin,
+ GPIOF_OUT_INIT_LOW, "ADV7183 Reset")) {
v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
- ret = -EBUSY;
- goto err_free_decoder;
+ return -EBUSY;
}
- if (gpio_request(decoder->oe_pin, "ADV7183 Output Enable")) {
+ if (devm_gpio_request_one(&client->dev, decoder->oe_pin,
+ GPIOF_OUT_INIT_HIGH,
+ "ADV7183 Output Enable")) {
v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin);
- ret = -EBUSY;
- goto err_free_reset;
+ return -EBUSY;
}
sd = &decoder->sd;
@@ -611,7 +586,7 @@
ret = hdl->error;
v4l2_ctrl_handler_free(hdl);
- goto err_free_oe;
+ return ret;
}
/* v4l2 doesn't support an autodetect standard, pick PAL as default */
@@ -619,12 +594,10 @@
decoder->input = ADV7183_COMPOSITE4;
decoder->output = ADV7183_8BIT_OUT;
- gpio_direction_output(decoder->oe_pin, 1);
/* reset chip */
- gpio_direction_output(decoder->reset_pin, 0);
/* reset pulse width at least 5ms */
mdelay(10);
- gpio_direction_output(decoder->reset_pin, 1);
+ gpio_set_value(decoder->reset_pin, 1);
/* wait 5ms before any further i2c writes are performed */
mdelay(5);
@@ -638,29 +611,18 @@
ret = v4l2_ctrl_handler_setup(hdl);
if (ret) {
v4l2_ctrl_handler_free(hdl);
- goto err_free_oe;
+ return ret;
}
return 0;
-err_free_oe:
- gpio_free(decoder->oe_pin);
-err_free_reset:
- gpio_free(decoder->reset_pin);
-err_free_decoder:
- kfree(decoder);
- return ret;
}
static int adv7183_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct adv7183 *decoder = to_adv7183(sd);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- gpio_free(decoder->oe_pin);
- gpio_free(decoder->reset_pin);
- kfree(decoder);
return 0;
}
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index 9fc2b98..7606218 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -28,7 +28,6 @@
#include <media/adv7343.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include "adv7343_regs.h"
@@ -311,21 +310,12 @@
return -EINVAL;
}
-static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
-}
-
static const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
.s_ctrl = adv7343_s_ctrl,
};
static const struct v4l2_subdev_core_ops adv7343_core_ops = {
.log_status = adv7343_log_status,
- .g_chip_ident = adv7343_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
diff --git a/drivers/media/i2c/adv7393.c b/drivers/media/i2c/adv7393.c
index 3dc6098..558f191 100644
--- a/drivers/media/i2c/adv7393.c
+++ b/drivers/media/i2c/adv7393.c
@@ -33,7 +33,6 @@
#include <media/adv7393.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include "adv7393_regs.h"
@@ -301,21 +300,12 @@
return -EINVAL;
}
-static int adv7393_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7393, 0);
-}
-
static const struct v4l2_ctrl_ops adv7393_ctrl_ops = {
.s_ctrl = adv7393_s_ctrl,
};
static const struct v4l2_subdev_core_ops adv7393_core_ops = {
.log_status = adv7393_log_status,
- .g_chip_ident = adv7393_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -410,7 +400,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct adv7393_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
@@ -444,16 +434,13 @@
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return err;
}
v4l2_ctrl_handler_setup(&state->hdl);
err = adv7393_initialize(&state->sd);
- if (err) {
+ if (err)
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
- }
return err;
}
@@ -464,7 +451,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return 0;
}
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 31a63c9..1d675b5 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -38,7 +38,6 @@
#include <linux/v4l2-dv-timings.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
#include <media/adv7604.h>
static int debug;
@@ -643,12 +642,6 @@
static int adv7604_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->size = 1;
switch (reg->reg >> 8) {
case 0:
@@ -701,12 +694,6 @@
static int adv7604_s_register(struct v4l2_subdev *sd,
const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
switch (reg->reg >> 8) {
case 0:
io_write(sd, reg->reg & 0xff, reg->val & 0xff);
@@ -984,14 +971,6 @@
return -EINVAL;
}
-static int adv7604_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7604, 0);
-}
-
/* ----------------------------------------------------------------------- */
static inline bool no_power(struct v4l2_subdev *sd)
@@ -1787,7 +1766,6 @@
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
- .g_chip_ident = adv7604_g_chip_ident,
.interrupt_service_routine = adv7604_isr,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = adv7604_g_register,
@@ -1968,7 +1946,7 @@
v4l_dbg(1, debug, client, "detecting adv7604 client on address 0x%x\n",
client->addr << 1);
- state = kzalloc(sizeof(struct adv7604_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (!state) {
v4l_err(client, "Could not allocate adv7604_state memory!\n");
return -ENOMEM;
@@ -1977,8 +1955,7 @@
/* platform data */
if (!pdata) {
v4l_err(client, "No platform data!\n");
- err = -ENODEV;
- goto err_state;
+ return -ENODEV;
}
memcpy(&state->pdata, pdata, sizeof(state->pdata));
@@ -1991,8 +1968,7 @@
if (adv_smbus_read_byte_data_check(client, 0xfb, false) != 0x68) {
v4l2_info(sd, "not an adv7604 on address 0x%x\n",
client->addr << 1);
- err = -ENODEV;
- goto err_state;
+ return -ENODEV;
}
/* control handlers */
@@ -2093,8 +2069,6 @@
adv7604_unregister_clients(state);
err_hdl:
v4l2_ctrl_handler_free(hdl);
-err_state:
- kfree(state);
return err;
}
@@ -2111,7 +2085,6 @@
media_entity_cleanup(&sd->entity);
adv7604_unregister_clients(to_state(sd));
v4l2_ctrl_handler_free(sd->ctrl_handler);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c
index fd47465..c14e667 100644
--- a/drivers/media/i2c/ak881x.c
+++ b/drivers/media/i2c/ak881x.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <media/ak881x.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
@@ -33,7 +32,6 @@
struct v4l2_subdev subdev;
struct ak881x_pdata *pdata;
unsigned int lines;
- int id; /* DEVICE_ID code V4L2_IDENT_AK881X code from v4l2-chip-ident.h */
char revision; /* DEVICE_REVISION content */
};
@@ -62,36 +60,16 @@
return container_of(i2c_get_clientdata(client), struct ak881x, subdev);
}
-static int ak881x_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ak881x *ak881x = to_ak881x(client);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = ak881x->id;
- id->revision = ak881x->revision;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int ak881x_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
+ if (reg->reg > 0x26)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
+ reg->size = 1;
reg->val = reg_read(client, reg->reg);
if (reg->val > 0xffff)
@@ -105,12 +83,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
+ if (reg->reg > 0x26)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
if (reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
@@ -229,7 +204,6 @@
}
static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
- .g_chip_ident = ak881x_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ak881x_g_register,
.s_register = ak881x_s_register,
@@ -264,7 +238,7 @@
return -EIO;
}
- ak881x = kzalloc(sizeof(struct ak881x), GFP_KERNEL);
+ ak881x = devm_kzalloc(&client->dev, sizeof(*ak881x), GFP_KERNEL);
if (!ak881x)
return -ENOMEM;
@@ -274,15 +248,11 @@
switch (data) {
case 0x13:
- ak881x->id = V4L2_IDENT_AK8813;
- break;
case 0x14:
- ak881x->id = V4L2_IDENT_AK8814;
break;
default:
dev_err(&client->dev,
"No ak881x chip detected, register read %x\n", data);
- kfree(ak881x);
return -ENODEV;
}
@@ -331,7 +301,6 @@
struct ak881x *ak881x = to_ak881x(client);
v4l2_device_unregister_subdev(&ak881x->subdev);
- kfree(ak881x);
return 0;
}
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
index 58d523f..301084b 100644
--- a/drivers/media/i2c/as3645a.c
+++ b/drivers/media/i2c/as3645a.c
@@ -813,7 +813,7 @@
if (client->dev.platform_data == NULL)
return -ENODEV;
- flash = kzalloc(sizeof(*flash), GFP_KERNEL);
+ flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
if (flash == NULL)
return -ENOMEM;
@@ -838,10 +838,8 @@
flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
done:
- if (ret < 0) {
+ if (ret < 0)
v4l2_ctrl_handler_free(&flash->ctrls);
- kfree(flash);
- }
return ret;
}
@@ -855,7 +853,6 @@
v4l2_ctrl_handler_free(&flash->ctrls);
media_entity_cleanup(&flash->subdev.entity);
mutex_destroy(&flash->power_lock);
- kfree(flash);
return 0;
}
diff --git a/drivers/media/i2c/bt819.c b/drivers/media/i2c/bt819.c
index 377bf05..369cf6f 100644
--- a/drivers/media/i2c/bt819.c
+++ b/drivers/media/i2c/bt819.c
@@ -36,7 +36,6 @@
#include <linux/videodev2.h>
#include <linux/slab.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/bt819.h>
@@ -57,7 +56,6 @@
unsigned char reg[32];
v4l2_std_id norm;
- int ident;
int input;
int enable;
};
@@ -217,15 +215,17 @@
struct bt819 *decoder = to_bt819(sd);
int status = bt819_read(decoder, 0x00);
int res = V4L2_IN_ST_NO_SIGNAL;
- v4l2_std_id std;
+ v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
if ((status & 0x80))
res = 0;
+ else
+ std = V4L2_STD_UNKNOWN;
if ((status & 0x10))
- std = V4L2_STD_PAL;
+ std &= V4L2_STD_PAL;
else
- std = V4L2_STD_NTSC;
+ std &= V4L2_STD_NTSC;
if (pstd)
*pstd = std;
if (pstatus)
@@ -373,14 +373,6 @@
return 0;
}
-static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct bt819 *decoder = to_bt819(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
@@ -388,7 +380,6 @@
};
static const struct v4l2_subdev_core_ops bt819_core_ops = {
- .g_chip_ident = bt819_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -425,7 +416,7 @@
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
- decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
+ decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
sd = &decoder->sd;
@@ -435,15 +426,12 @@
switch (ver & 0xf0) {
case 0x70:
name = "bt819a";
- decoder->ident = V4L2_IDENT_BT819A;
break;
case 0x60:
name = "bt817a";
- decoder->ident = V4L2_IDENT_BT817A;
break;
case 0x20:
name = "bt815a";
- decoder->ident = V4L2_IDENT_BT815A;
break;
default:
v4l2_dbg(1, debug, sd,
@@ -476,7 +464,6 @@
int err = decoder->hdl.error;
v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
return err;
}
v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -490,7 +477,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
return 0;
}
diff --git a/drivers/media/i2c/bt856.c b/drivers/media/i2c/bt856.c
index 7e5bd36..7fc163d 100644
--- a/drivers/media/i2c/bt856.c
+++ b/drivers/media/i2c/bt856.c
@@ -36,7 +36,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -177,17 +176,9 @@
return 0;
}
-static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops bt856_core_ops = {
- .g_chip_ident = bt856_g_chip_ident,
.init = bt856_init,
};
@@ -216,7 +207,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
+ encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
sd = &encoder->sd;
@@ -250,7 +241,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_bt856(sd));
return 0;
}
diff --git a/drivers/media/i2c/bt866.c b/drivers/media/i2c/bt866.c
index 905320b..a8bf10f 100644
--- a/drivers/media/i2c/bt866.c
+++ b/drivers/media/i2c/bt866.c
@@ -36,7 +36,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -175,26 +174,14 @@
bt866_write(client, 0xdc, val);
#endif
-static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
-}
-
/* ----------------------------------------------------------------------- */
-static const struct v4l2_subdev_core_ops bt866_core_ops = {
- .g_chip_ident = bt866_g_chip_ident,
-};
-
static const struct v4l2_subdev_video_ops bt866_video_ops = {
.s_std_output = bt866_s_std_output,
.s_routing = bt866_s_routing,
};
static const struct v4l2_subdev_ops bt866_ops = {
- .core = &bt866_core_ops,
.video = &bt866_video_ops,
};
@@ -207,7 +194,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
+ encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
sd = &encoder->sd;
@@ -220,7 +207,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_bt866(sd));
return 0;
}
diff --git a/drivers/media/i2c/cs5345.c b/drivers/media/i2c/cs5345.c
index 1d2f7c8..34b76a9 100644
--- a/drivers/media/i2c/cs5345.c
+++ b/drivers/media/i2c/cs5345.c
@@ -24,7 +24,6 @@
#include <linux/videodev2.h>
#include <linux/slab.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
@@ -99,12 +98,6 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->size = 1;
reg->val = cs5345_read(sd, reg->reg & 0x1f);
return 0;
@@ -112,24 +105,11 @@
static int cs5345_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
cs5345_write(sd, reg->reg & 0x1f, reg->val & 0xff);
return 0;
}
#endif
-static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_CS5345, 0);
-}
-
static int cs5345_log_status(struct v4l2_subdev *sd)
{
u8 v = cs5345_read(sd, 0x09) & 7;
@@ -152,7 +132,6 @@
static const struct v4l2_subdev_core_ops cs5345_core_ops = {
.log_status = cs5345_log_status,
- .g_chip_ident = cs5345_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -190,7 +169,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct cs5345_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -206,7 +185,6 @@
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return err;
}
/* set volume/mute */
@@ -227,7 +205,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return 0;
}
diff --git a/drivers/media/i2c/cs53l32a.c b/drivers/media/i2c/cs53l32a.c
index b293912..27400c1 100644
--- a/drivers/media/i2c/cs53l32a.c
+++ b/drivers/media/i2c/cs53l32a.c
@@ -28,7 +28,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
@@ -104,14 +103,6 @@
return -EINVAL;
}
-static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client,
- chip, V4L2_IDENT_CS53l32A, 0);
-}
-
static int cs53l32a_log_status(struct v4l2_subdev *sd)
{
struct cs53l32a_state *state = to_state(sd);
@@ -130,7 +121,6 @@
static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
.log_status = cs53l32a_log_status,
- .g_chip_ident = cs53l32a_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -175,7 +165,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct cs53l32a_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -197,7 +187,6 @@
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return err;
}
@@ -228,7 +217,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return 0;
}
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index 12fb9b2..2e3771d 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -45,7 +45,6 @@
#include <linux/delay.h>
#include <linux/math64.h>
#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
#include <media/cx25840.h>
#include "cx25840-core.h"
@@ -498,7 +497,7 @@
/* Sys PLL */
switch (state->id) {
- case V4L2_IDENT_CX23888_AV:
+ case CX23888_AV:
/*
* 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
* 572.73 MHz before post divide
@@ -511,7 +510,7 @@
cx25840_write4(client, 0x42c, 0x42600000);
cx25840_write4(client, 0x44c, 0x161f1000);
break;
- case V4L2_IDENT_CX23887_AV:
+ case CX23887_AV:
/*
* 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
* 572.73 MHz before post divide
@@ -519,7 +518,7 @@
cx25840_write4(client, 0x11c, 0x01d1744c);
cx25840_write4(client, 0x118, 0x00000416);
break;
- case V4L2_IDENT_CX23885_AV:
+ case CX23885_AV:
default:
/*
* 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
@@ -546,7 +545,7 @@
/* HVR1850 */
switch (state->id) {
- case V4L2_IDENT_CX23888_AV:
+ case CX23888_AV:
/* 888/HVR1250 specific */
cx25840_write4(client, 0x10c, 0x13333333);
cx25840_write4(client, 0x108, 0x00000515);
@@ -570,7 +569,7 @@
* 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
*/
switch (state->id) {
- case V4L2_IDENT_CX23888_AV:
+ case CX23888_AV:
/*
* 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
* 368.64 MHz before post divide
@@ -580,7 +579,7 @@
cx25840_write4(client, 0x114, 0x017dbf48);
cx25840_write4(client, 0x110, 0x000a030e);
break;
- case V4L2_IDENT_CX23887_AV:
+ case CX23887_AV:
/*
* 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
* 368.64 MHz before post divide
@@ -589,7 +588,7 @@
cx25840_write4(client, 0x114, 0x017dbf48);
cx25840_write4(client, 0x110, 0x000a030e);
break;
- case V4L2_IDENT_CX23885_AV:
+ case CX23885_AV:
default:
/*
* 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
@@ -1662,10 +1661,6 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->size = 1;
reg->val = cx25840_read(client, reg->reg & 0x0fff);
return 0;
@@ -1675,10 +1670,6 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
return 0;
}
@@ -1938,14 +1929,6 @@
return 0;
}
-static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct cx25840_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
-}
-
static int cx25840_log_status(struct v4l2_subdev *sd)
{
struct cx25840_state *state = to_state(sd);
@@ -5051,7 +5034,6 @@
static const struct v4l2_subdev_core_ops cx25840_core_ops = {
.log_status = cx25840_log_status,
- .g_chip_ident = cx25840_g_chip_ident,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -5128,18 +5110,18 @@
ret = cx25840_read4(client, 0x300);
if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
/* No DIF */
- ret = V4L2_IDENT_CX23885_AV;
+ ret = CX23885_AV;
} else {
/* CX23887 has a broken DIF, but the registers
* appear valid (but unused), good enough to detect. */
- ret = V4L2_IDENT_CX23887_AV;
+ ret = CX23887_AV;
}
} else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
/* DIF PLL Freq Word reg exists; chip must be a CX23888 */
- ret = V4L2_IDENT_CX23888_AV;
+ ret = CX23888_AV;
} else {
v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
- ret = V4L2_IDENT_CX23887_AV;
+ ret = CX23887_AV;
}
/* Back into digital power down */
@@ -5153,7 +5135,7 @@
struct cx25840_state *state;
struct v4l2_subdev *sd;
int default_volume;
- u32 id = V4L2_IDENT_NONE;
+ u32 id;
u16 device_id;
/* Check if the adapter supports the needed features */
@@ -5169,14 +5151,14 @@
/* The high byte of the device ID should be
* 0x83 for the cx2583x and 0x84 for the cx2584x */
if ((device_id & 0xff00) == 0x8300) {
- id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
+ id = CX25836 + ((device_id >> 4) & 0xf) - 6;
} else if ((device_id & 0xff00) == 0x8400) {
- id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
+ id = CX25840 + ((device_id >> 4) & 0xf);
} else if (device_id == 0x0000) {
id = get_cx2388x_ident(client);
} else if ((device_id & 0xfff0) == 0x5A30) {
/* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
- id = V4L2_IDENT_CX2310X_AV;
+ id = CX2310X_AV;
} else if ((device_id & 0xff) == (device_id >> 8)) {
v4l_err(client,
"likely a confused/unresponsive cx2388[578] A/V decoder"
@@ -5190,7 +5172,7 @@
return -ENODEV;
}
- state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
@@ -5198,26 +5180,26 @@
v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
switch (id) {
- case V4L2_IDENT_CX23885_AV:
+ case CX23885_AV:
v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
break;
- case V4L2_IDENT_CX23887_AV:
+ case CX23887_AV:
v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
break;
- case V4L2_IDENT_CX23888_AV:
+ case CX23888_AV:
v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
break;
- case V4L2_IDENT_CX2310X_AV:
+ case CX2310X_AV:
v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
device_id, client->addr << 1, client->adapter->name);
break;
- case V4L2_IDENT_CX25840:
- case V4L2_IDENT_CX25841:
- case V4L2_IDENT_CX25842:
- case V4L2_IDENT_CX25843:
+ case CX25840:
+ case CX25841:
+ case CX25842:
+ case CX25843:
/* Note: revision '(device_id & 0x0f) == 2' was never built. The
marking skips from 0x1 == 22 to 0x3 == 23. */
v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
@@ -5226,8 +5208,8 @@
: (device_id & 0x0f),
client->addr << 1, client->adapter->name);
break;
- case V4L2_IDENT_CX25836:
- case V4L2_IDENT_CX25837:
+ case CX25836:
+ case CX25837:
default:
v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
(device_id & 0xfff0) >> 4, device_id & 0x0f,
@@ -5292,7 +5274,6 @@
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return err;
}
if (!is_cx2583x(state))
@@ -5317,7 +5298,6 @@
cx25840_ir_remove(sd);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return 0;
}
diff --git a/drivers/media/i2c/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h
index bd4ada2..37bc042 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.h
+++ b/drivers/media/i2c/cx25840/cx25840-core.h
@@ -23,12 +23,24 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <linux/i2c.h>
struct cx25840_ir_state;
+enum cx25840_model {
+ CX23885_AV,
+ CX23887_AV,
+ CX23888_AV,
+ CX2310X_AV,
+ CX25840,
+ CX25841,
+ CX25842,
+ CX25843,
+ CX25836,
+ CX25837,
+};
+
struct cx25840_state {
struct i2c_client *c;
struct v4l2_subdev sd;
@@ -46,7 +58,7 @@
u32 audclk_freq;
int audmode;
int vbi_line_offset;
- u32 id;
+ enum cx25840_model id;
u32 rev;
int is_initialized;
wait_queue_head_t fw_wait; /* wake up when the fw load is finished */
@@ -66,35 +78,35 @@
static inline bool is_cx2583x(struct cx25840_state *state)
{
- return state->id == V4L2_IDENT_CX25836 ||
- state->id == V4L2_IDENT_CX25837;
+ return state->id == CX25836 ||
+ state->id == CX25837;
}
static inline bool is_cx231xx(struct cx25840_state *state)
{
- return state->id == V4L2_IDENT_CX2310X_AV;
+ return state->id == CX2310X_AV;
}
static inline bool is_cx2388x(struct cx25840_state *state)
{
- return state->id == V4L2_IDENT_CX23885_AV ||
- state->id == V4L2_IDENT_CX23887_AV ||
- state->id == V4L2_IDENT_CX23888_AV;
+ return state->id == CX23885_AV ||
+ state->id == CX23887_AV ||
+ state->id == CX23888_AV;
}
static inline bool is_cx23885(struct cx25840_state *state)
{
- return state->id == V4L2_IDENT_CX23885_AV;
+ return state->id == CX23885_AV;
}
static inline bool is_cx23887(struct cx25840_state *state)
{
- return state->id == V4L2_IDENT_CX23887_AV;
+ return state->id == CX23887_AV;
}
static inline bool is_cx23888(struct cx25840_state *state)
{
- return state->id == V4L2_IDENT_CX23888_AV;
+ return state->id == CX23888_AV;
}
/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index 9ae977b..e6588ee 100644
--- a/drivers/media/i2c/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
@@ -1230,16 +1230,14 @@
if (!(is_cx23885(state) || is_cx23887(state)))
return 0;
- ir_state = kzalloc(sizeof(struct cx25840_ir_state), GFP_KERNEL);
+ ir_state = devm_kzalloc(&state->c->dev, sizeof(*ir_state), GFP_KERNEL);
if (ir_state == NULL)
return -ENOMEM;
spin_lock_init(&ir_state->rx_kfifo_lock);
if (kfifo_alloc(&ir_state->rx_kfifo,
- CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL)) {
- kfree(ir_state);
+ CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL))
return -ENOMEM;
- }
ir_state->c = state->c;
state->ir_state = ir_state;
@@ -1273,7 +1271,6 @@
cx25840_ir_tx_shutdown(sd);
kfifo_free(&ir_state->rx_kfifo);
- kfree(ir_state);
state->ir_state = NULL;
return 0;
}
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index 8e2f79c..82bf567 100644
--- a/drivers/media/i2c/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
@@ -295,7 +295,7 @@
unsigned short addr = client->addr;
int err;
- ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
+ ir = devm_kzalloc(&client->dev, sizeof(*ir), GFP_KERNEL);
if (!ir)
return -ENOMEM;
@@ -398,10 +398,8 @@
* internally
*/
rc = rc_allocate_device();
- if (!rc) {
- err = -ENOMEM;
- goto err_out_free;
- }
+ if (!rc)
+ return -ENOMEM;
}
ir->rc = rc;
@@ -454,7 +452,6 @@
err_out_free:
/* Only frees rc if it were allocated internally */
rc_free_device(rc);
- kfree(ir);
return err;
}
@@ -470,7 +467,6 @@
rc_unregister_device(ir->rc);
/* free memory */
- kfree(ir);
return 0;
}
diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c
index 04a6efa..c3e94ae 100644
--- a/drivers/media/i2c/ks0127.c
+++ b/drivers/media/i2c/ks0127.c
@@ -42,7 +42,6 @@
#include <linux/videodev2.h>
#include <linux/slab.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include "ks0127.h"
MODULE_DESCRIPTION("KS0127 video decoder driver");
@@ -200,7 +199,6 @@
struct ks0127 {
struct v4l2_subdev sd;
v4l2_std_id norm;
- int ident;
u8 regs[256];
};
@@ -371,12 +369,9 @@
****************************************************************************/
static void ks0127_init(struct v4l2_subdev *sd)
{
- struct ks0127 *ks = to_ks0127(sd);
u8 *table = reg_defaults;
int i;
- ks->ident = V4L2_IDENT_KS0127;
-
v4l2_dbg(1, debug, sd, "reset\n");
msleep(1);
@@ -397,7 +392,6 @@
if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) {
- ks->ident = V4L2_IDENT_KS0122S;
v4l2_dbg(1, debug, sd, "ks0122s found\n");
return;
}
@@ -408,7 +402,6 @@
break;
case 9:
- ks->ident = V4L2_IDENT_KS0127B;
v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
break;
@@ -616,17 +609,24 @@
{
int stat = V4L2_IN_ST_NO_SIGNAL;
u8 status;
- v4l2_std_id std = V4L2_STD_ALL;
+ v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
status = ks0127_read(sd, KS_STAT);
if (!(status & 0x20)) /* NOVID not set */
stat = 0;
- if (!(status & 0x01)) /* CLOCK set */
+ if (!(status & 0x01)) { /* CLOCK set */
stat |= V4L2_IN_ST_NO_COLOR;
- if ((status & 0x08)) /* PALDET set */
- std = V4L2_STD_PAL;
+ std = V4L2_STD_UNKNOWN;
+ } else {
+ if ((status & 0x08)) /* PALDET set */
+ std &= V4L2_STD_PAL;
+ else
+ std &= V4L2_STD_NTSC;
+ }
+ if ((status & 0x10)) /* PALDET set */
+ std &= V4L2_STD_525_60;
else
- std = V4L2_STD_NTSC;
+ std &= V4L2_STD_625_50;
if (pstd)
*pstd = std;
if (pstatus)
@@ -646,18 +646,9 @@
return ks0127_status(sd, status, NULL);
}
-static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ks0127 *ks = to_ks0127(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, ks->ident, 0);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops ks0127_core_ops = {
- .g_chip_ident = ks0127_g_chip_ident,
.s_std = ks0127_s_std,
};
@@ -685,7 +676,7 @@
client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
client->addr << 1, client->adapter->name);
- ks = kzalloc(sizeof(*ks), GFP_KERNEL);
+ ks = devm_kzalloc(&client->dev, sizeof(*ks), GFP_KERNEL);
if (ks == NULL)
return -ENOMEM;
sd = &ks->sd;
@@ -708,7 +699,6 @@
v4l2_device_unregister_subdev(sd);
ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
- kfree(to_ks0127(sd));
return 0;
}
diff --git a/drivers/media/i2c/m52790.c b/drivers/media/i2c/m52790.c
index 39f50fd..bf47635 100644
--- a/drivers/media/i2c/m52790.c
+++ b/drivers/media/i2c/m52790.c
@@ -29,7 +29,6 @@
#include <linux/videodev2.h>
#include <media/m52790.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch");
MODULE_AUTHOR("Hans Verkuil");
@@ -83,12 +82,7 @@
static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
struct m52790_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
if (reg->reg != 0)
return -EINVAL;
reg->size = 1;
@@ -99,12 +93,7 @@
static int m52790_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
struct m52790_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
if (reg->reg != 0)
return -EINVAL;
state->input = reg->val & 0x0303;
@@ -114,13 +103,6 @@
}
#endif
-static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_M52790, 0);
-}
-
static int m52790_log_status(struct v4l2_subdev *sd)
{
struct m52790_state *state = to_state(sd);
@@ -136,7 +118,6 @@
static const struct v4l2_subdev_core_ops m52790_core_ops = {
.log_status = m52790_log_status,
- .g_chip_ident = m52790_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = m52790_g_register,
.s_register = m52790_s_register,
@@ -174,7 +155,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct m52790_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
@@ -191,7 +172,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index 0b899cb..8d870b7 100644
--- a/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -930,6 +930,7 @@
const struct i2c_device_id *id)
{
const struct m5mols_platform_data *pdata = client->dev.platform_data;
+ unsigned long gpio_flags;
struct m5mols_info *info;
struct v4l2_subdev *sd;
int ret;
@@ -949,24 +950,27 @@
return -EINVAL;
}
- info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
+ info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->pdata = pdata;
info->set_power = pdata->set_power;
- ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
+ gpio_flags = pdata->reset_polarity
+ ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags,
+ "M5MOLS_NRST");
if (ret) {
dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
- goto out_free;
+ return ret;
}
- gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);
- ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
+ ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
+ supplies);
if (ret) {
dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
- goto out_gpio;
+ return ret;
}
sd = &info->sd;
@@ -978,17 +982,17 @@
info->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
if (ret < 0)
- goto out_reg;
+ return ret;
sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
init_waitqueue_head(&info->irq_waitq);
mutex_init(&info->lock);
- ret = request_irq(client->irq, m5mols_irq_handler,
- IRQF_TRIGGER_RISING, MODULE_NAME, sd);
+ ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler,
+ IRQF_TRIGGER_RISING, MODULE_NAME, sd);
if (ret) {
dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
- goto out_me;
+ goto error;
}
info->res_type = M5MOLS_RESTYPE_MONITOR;
info->ffmt[0] = m5mols_default_ffmt[0];
@@ -996,7 +1000,7 @@
ret = m5mols_sensor_power(info, true);
if (ret)
- goto out_irq;
+ goto error;
ret = m5mols_fw_start(sd);
if (!ret)
@@ -1005,32 +1009,19 @@
ret = m5mols_sensor_power(info, false);
if (!ret)
return 0;
-out_irq:
- free_irq(client->irq, sd);
-out_me:
+error:
media_entity_cleanup(&sd->entity);
-out_reg:
- regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
-out_gpio:
- gpio_free(pdata->gpio_reset);
-out_free:
- kfree(info);
return ret;
}
static int m5mols_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct m5mols_info *info = to_m5mols(sd);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- free_irq(client->irq, sd);
-
- regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
- gpio_free(info->pdata->gpio_reset);
media_entity_cleanup(&sd->entity);
- kfree(info);
+
return 0;
}
diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c
new file mode 100644
index 0000000..efdc873
--- /dev/null
+++ b/drivers/media/i2c/ml86v7667.c
@@ -0,0 +1,431 @@
+/*
+ * OKI Semiconductor ML86V7667 video decoder driver
+ *
+ * Author: Vladimir Barinov <source@cogentembedded.com>
+ * Copyright (C) 2013 Cogent Embedded, Inc.
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+
+#define DRV_NAME "ml86v7667"
+
+/* Subaddresses */
+#define MRA_REG 0x00 /* Mode Register A */
+#define MRC_REG 0x02 /* Mode Register C */
+#define LUMC_REG 0x0C /* Luminance Control */
+#define CLC_REG 0x10 /* Contrast level control */
+#define SSEPL_REG 0x11 /* Sync separation level */
+#define CHRCA_REG 0x12 /* Chrominance Control A */
+#define ACCC_REG 0x14 /* ACC Loop filter & Chrominance control */
+#define ACCRC_REG 0x15 /* ACC Reference level control */
+#define HUE_REG 0x16 /* Hue control */
+#define ADC2_REG 0x1F /* ADC Register 2 */
+#define PLLR1_REG 0x20 /* PLL Register 1 */
+#define STATUS_REG 0x2C /* STATUS Register */
+
+/* Mode Register A register bits */
+#define MRA_OUTPUT_MODE_MASK (3 << 6)
+#define MRA_ITUR_BT601 (1 << 6)
+#define MRA_ITUR_BT656 (0 << 6)
+#define MRA_INPUT_MODE_MASK (7 << 3)
+#define MRA_PAL_BT601 (4 << 3)
+#define MRA_NTSC_BT601 (0 << 3)
+#define MRA_REGISTER_MODE (1 << 0)
+
+/* Mode Register C register bits */
+#define MRC_AUTOSELECT (1 << 7)
+
+/* Luminance Control register bits */
+#define LUMC_ONOFF_SHIFT 7
+#define LUMC_ONOFF_MASK (1 << 7)
+
+/* Contrast level control register bits */
+#define CLC_CONTRAST_ONOFF (1 << 7)
+#define CLC_CONTRAST_MASK 0x0F
+
+/* Sync separation level register bits */
+#define SSEPL_LUMINANCE_ONOFF (1 << 7)
+#define SSEPL_LUMINANCE_MASK 0x7F
+
+/* Chrominance Control A register bits */
+#define CHRCA_MODE_SHIFT 6
+#define CHRCA_MODE_MASK (1 << 6)
+
+/* ACC Loop filter & Chrominance control register bits */
+#define ACCC_CHROMA_CR_SHIFT 3
+#define ACCC_CHROMA_CR_MASK (7 << 3)
+#define ACCC_CHROMA_CB_SHIFT 0
+#define ACCC_CHROMA_CB_MASK (7 << 0)
+
+/* ACC Reference level control register bits */
+#define ACCRC_CHROMA_MASK 0xfc
+#define ACCRC_CHROMA_SHIFT 2
+
+/* ADC Register 2 register bits */
+#define ADC2_CLAMP_VOLTAGE_MASK (7 << 1)
+#define ADC2_CLAMP_VOLTAGE(n) ((n & 7) << 1)
+
+/* PLL Register 1 register bits */
+#define PLLR1_FIXED_CLOCK (1 << 7)
+
+/* STATUS Register register bits */
+#define STATUS_HLOCK_DETECT (1 << 3)
+#define STATUS_NTSCPAL (1 << 2)
+
+struct ml86v7667_priv {
+ struct v4l2_subdev sd;
+ struct v4l2_ctrl_handler hdl;
+ v4l2_std_id std;
+};
+
+static inline struct ml86v7667_priv *to_ml86v7667(struct v4l2_subdev *subdev)
+{
+ return container_of(subdev, struct ml86v7667_priv, sd);
+}
+
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+ return &container_of(ctrl->handler, struct ml86v7667_priv, hdl)->sd;
+}
+
+static int ml86v7667_mask_set(struct i2c_client *client, const u8 reg,
+ const u8 mask, const u8 data)
+{
+ int val = i2c_smbus_read_byte_data(client, reg);
+ if (val < 0)
+ return val;
+
+ val = (val & ~mask) | (data & mask);
+ return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int ml86v7667_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct v4l2_subdev *sd = to_sd(ctrl);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ret = ml86v7667_mask_set(client, SSEPL_REG,
+ SSEPL_LUMINANCE_MASK, ctrl->val);
+ break;
+ case V4L2_CID_CONTRAST:
+ ret = ml86v7667_mask_set(client, CLC_REG,
+ CLC_CONTRAST_MASK, ctrl->val);
+ break;
+ case V4L2_CID_CHROMA_GAIN:
+ ret = ml86v7667_mask_set(client, ACCRC_REG, ACCRC_CHROMA_MASK,
+ ctrl->val << ACCRC_CHROMA_SHIFT);
+ break;
+ case V4L2_CID_HUE:
+ ret = ml86v7667_mask_set(client, HUE_REG, ~0, ctrl->val);
+ break;
+ case V4L2_CID_RED_BALANCE:
+ ret = ml86v7667_mask_set(client, ACCC_REG,
+ ACCC_CHROMA_CR_MASK,
+ ctrl->val << ACCC_CHROMA_CR_SHIFT);
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ ret = ml86v7667_mask_set(client, ACCC_REG,
+ ACCC_CHROMA_CB_MASK,
+ ctrl->val << ACCC_CHROMA_CB_SHIFT);
+ break;
+ case V4L2_CID_SHARPNESS:
+ ret = ml86v7667_mask_set(client, LUMC_REG,
+ LUMC_ONOFF_MASK,
+ ctrl->val << LUMC_ONOFF_SHIFT);
+ break;
+ case V4L2_CID_COLOR_KILLER:
+ ret = ml86v7667_mask_set(client, CHRCA_REG,
+ CHRCA_MODE_MASK,
+ ctrl->val << CHRCA_MODE_SHIFT);
+ break;
+ }
+
+ return 0;
+}
+
+static int ml86v7667_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int status;
+
+ status = i2c_smbus_read_byte_data(client, STATUS_REG);
+ if (status < 0)
+ return status;
+
+ if (status & STATUS_HLOCK_DETECT)
+ *std &= status & STATUS_NTSCPAL ? V4L2_STD_625_50 : V4L2_STD_525_60;
+ else
+ *std = V4L2_STD_UNKNOWN;
+
+ return 0;
+}
+
+static int ml86v7667_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int status_reg;
+
+ status_reg = i2c_smbus_read_byte_data(client, STATUS_REG);
+ if (status_reg < 0)
+ return status_reg;
+
+ *status = status_reg & STATUS_HLOCK_DETECT ? 0 : V4L2_IN_ST_NO_SIGNAL;
+
+ return 0;
+}
+
+static int ml86v7667_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+ enum v4l2_mbus_pixelcode *code)
+{
+ if (index > 0)
+ return -EINVAL;
+
+ *code = V4L2_MBUS_FMT_YUYV8_2X8;
+
+ return 0;
+}
+
+static int ml86v7667_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ struct ml86v7667_priv *priv = to_ml86v7667(sd);
+
+ fmt->code = V4L2_MBUS_FMT_YUYV8_2X8;
+ fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ fmt->field = V4L2_FIELD_INTERLACED;
+ fmt->width = 720;
+ fmt->height = priv->std & V4L2_STD_525_60 ? 480 : 576;
+
+ return 0;
+}
+
+static int ml86v7667_g_mbus_config(struct v4l2_subdev *sd,
+ struct v4l2_mbus_config *cfg)
+{
+ cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+ V4L2_MBUS_DATA_ACTIVE_HIGH;
+ cfg->type = V4L2_MBUS_BT656;
+
+ return 0;
+}
+
+static int ml86v7667_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct ml86v7667_priv *priv = to_ml86v7667(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+ int ret;
+ u8 mode;
+
+ /* PAL/NTSC ITU-R BT.601 input mode */
+ mode = std & V4L2_STD_525_60 ? MRA_NTSC_BT601 : MRA_PAL_BT601;
+ ret = ml86v7667_mask_set(client, MRA_REG, MRA_INPUT_MODE_MASK, mode);
+ if (ret < 0)
+ return ret;
+
+ priv->std = std;
+
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ml86v7667_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(client, (u8)reg->reg);
+ if (ret < 0)
+ return ret;
+
+ reg->val = ret;
+ reg->size = sizeof(u8);
+
+ return 0;
+}
+
+static int ml86v7667_s_register(struct v4l2_subdev *sd,
+ const struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return i2c_smbus_write_byte_data(client, (u8)reg->reg, (u8)reg->val);
+}
+#endif
+
+static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = {
+ .s_ctrl = ml86v7667_s_ctrl,
+};
+
+static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
+ .querystd = ml86v7667_querystd,
+ .g_input_status = ml86v7667_g_input_status,
+ .enum_mbus_fmt = ml86v7667_enum_mbus_fmt,
+ .try_mbus_fmt = ml86v7667_mbus_fmt,
+ .g_mbus_fmt = ml86v7667_mbus_fmt,
+ .s_mbus_fmt = ml86v7667_mbus_fmt,
+ .g_mbus_config = ml86v7667_g_mbus_config,
+};
+
+static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
+ .s_std = ml86v7667_s_std,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ml86v7667_g_register,
+ .s_register = ml86v7667_s_register,
+#endif
+};
+
+static struct v4l2_subdev_ops ml86v7667_subdev_ops = {
+ .core = &ml86v7667_subdev_core_ops,
+ .video = &ml86v7667_subdev_video_ops,
+};
+
+static int ml86v7667_init(struct ml86v7667_priv *priv)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+ int val;
+ int ret;
+
+ /* BT.656-4 output mode, register mode */
+ ret = ml86v7667_mask_set(client, MRA_REG,
+ MRA_OUTPUT_MODE_MASK | MRA_REGISTER_MODE,
+ MRA_ITUR_BT656 | MRA_REGISTER_MODE);
+
+ /* PLL circuit fixed clock, 32MHz */
+ ret |= ml86v7667_mask_set(client, PLLR1_REG, PLLR1_FIXED_CLOCK,
+ PLLR1_FIXED_CLOCK);
+
+ /* ADC2 clamping voltage maximum */
+ ret |= ml86v7667_mask_set(client, ADC2_REG, ADC2_CLAMP_VOLTAGE_MASK,
+ ADC2_CLAMP_VOLTAGE(7));
+
+ /* enable luminance function */
+ ret |= ml86v7667_mask_set(client, SSEPL_REG, SSEPL_LUMINANCE_ONOFF,
+ SSEPL_LUMINANCE_ONOFF);
+
+ /* enable contrast function */
+ ret |= ml86v7667_mask_set(client, CLC_REG, CLC_CONTRAST_ONOFF, 0);
+
+ /*
+ * PAL/NTSC autodetection is enabled after reset,
+ * set the autodetected std in manual std mode and
+ * disable autodetection
+ */
+ val = i2c_smbus_read_byte_data(client, STATUS_REG);
+ if (val < 0)
+ return val;
+
+ priv->std = val & STATUS_NTSCPAL ? V4L2_STD_625_50 : V4L2_STD_525_60;
+ ret |= ml86v7667_mask_set(client, MRC_REG, MRC_AUTOSELECT, 0);
+
+ val = priv->std & V4L2_STD_525_60 ? MRA_NTSC_BT601 : MRA_PAL_BT601;
+ ret |= ml86v7667_mask_set(client, MRA_REG, MRA_INPUT_MODE_MASK, val);
+
+ return ret;
+}
+
+static int ml86v7667_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+{
+ struct ml86v7667_priv *priv;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ v4l2_i2c_subdev_init(&priv->sd, client, &ml86v7667_subdev_ops);
+
+ v4l2_ctrl_handler_init(&priv->hdl, 8);
+ v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+ V4L2_CID_BRIGHTNESS, -64, 63, 1, 0);
+ v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+ V4L2_CID_CONTRAST, -8, 7, 1, 0);
+ v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+ V4L2_CID_CHROMA_GAIN, -32, 31, 1, 0);
+ v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+ V4L2_CID_HUE, -128, 127, 1, 0);
+ v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+ V4L2_CID_RED_BALANCE, -4, 3, 1, 0);
+ v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+ V4L2_CID_BLUE_BALANCE, -4, 3, 1, 0);
+ v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+ V4L2_CID_SHARPNESS, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+ V4L2_CID_COLOR_KILLER, 0, 1, 1, 0);
+ priv->sd.ctrl_handler = &priv->hdl;
+
+ ret = priv->hdl.error;
+ if (ret)
+ goto cleanup;
+
+ v4l2_ctrl_handler_setup(&priv->hdl);
+
+ ret = ml86v7667_init(priv);
+ if (ret)
+ goto cleanup;
+
+ v4l_info(client, "chip found @ 0x%02x (%s)\n",
+ client->addr, client->adapter->name);
+ return 0;
+
+cleanup:
+ v4l2_ctrl_handler_free(&priv->hdl);
+ v4l2_device_unregister_subdev(&priv->sd);
+ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
+ client->addr, client->adapter->name);
+ return ret;
+}
+
+static int ml86v7667_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ml86v7667_priv *priv = to_ml86v7667(sd);
+
+ v4l2_ctrl_handler_free(&priv->hdl);
+ v4l2_device_unregister_subdev(&priv->sd);
+
+ return 0;
+}
+
+static const struct i2c_device_id ml86v7667_id[] = {
+ {DRV_NAME, 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, ml86v7667_id);
+
+static struct i2c_driver ml86v7667_i2c_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = ml86v7667_probe,
+ .remove = ml86v7667_remove,
+ .id_table = ml86v7667_id,
+};
+
+module_i2c_driver(ml86v7667_i2c_driver);
+
+MODULE_DESCRIPTION("OKI Semiconductor ML86V7667 video decoder driver");
+MODULE_AUTHOR("Vladimir Barinov");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c
index 54a9dd3..8190fec 100644
--- a/drivers/media/i2c/msp3400-driver.c
+++ b/drivers/media/i2c/msp3400-driver.c
@@ -570,15 +570,6 @@
return 0;
}
-static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->ident,
- (state->rev1 << 16) | state->rev2);
-}
-
static int msp_log_status(struct v4l2_subdev *sd)
{
struct msp_state *state = to_state(sd);
@@ -651,7 +642,6 @@
static const struct v4l2_subdev_core_ops msp_core_ops = {
.log_status = msp_log_status,
- .g_chip_ident = msp_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -707,7 +697,7 @@
return -ENODEV;
}
- state = kzalloc(sizeof(*state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
@@ -732,7 +722,6 @@
if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) {
v4l_dbg(1, msp_debug, client,
"not an msp3400 (cannot read chip version)\n");
- kfree(state);
return -ENODEV;
}
@@ -827,7 +816,6 @@
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
- kfree(state);
return err;
}
@@ -889,7 +877,6 @@
msp_reset(client);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return 0;
}
diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c
index 8edb3d8..846b15f 100644
--- a/drivers/media/i2c/mt9m032.c
+++ b/drivers/media/i2c/mt9m032.c
@@ -554,10 +554,8 @@
struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
int val;
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+ if (reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
val = mt9m032_read(client, reg->reg);
if (val < 0)
@@ -575,12 +573,9 @@
struct mt9m032 *sensor = to_mt9m032(sd);
struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+ if (reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
return mt9m032_write(client, reg->reg, reg->val);
}
#endif
@@ -730,7 +725,7 @@
if (!client->dev.platform_data)
return -ENODEV;
- sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+ sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
if (sensor == NULL)
return -ENOMEM;
@@ -860,7 +855,6 @@
v4l2_ctrl_handler_free(&sensor->ctrls);
error_sensor:
mutex_destroy(&sensor->lock);
- kfree(sensor);
return ret;
}
@@ -873,7 +867,6 @@
v4l2_ctrl_handler_free(&sensor->ctrls);
media_entity_cleanup(&subdev->entity);
mutex_destroy(&sensor->lock);
- kfree(sensor);
return 0;
}
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 28cf95b..4734836 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -16,18 +16,19 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio.h>
-#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
#include <linux/pm.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/mt9p031.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-of.h>
#include <media/v4l2-subdev.h>
#include "aptina-pll.h"
@@ -124,9 +125,7 @@
int power_count;
struct clk *clk;
- struct regulator *vaa;
- struct regulator *vdd;
- struct regulator *vdd_io;
+ struct regulator_bulk_data regulators[3];
enum mt9p031_model model;
struct aptina_pll pll;
@@ -271,23 +270,26 @@
static int mt9p031_power_on(struct mt9p031 *mt9p031)
{
+ int ret;
+
/* Ensure RESET_BAR is low */
- if (mt9p031->reset != -1) {
+ if (gpio_is_valid(mt9p031->reset)) {
gpio_set_value(mt9p031->reset, 0);
usleep_range(1000, 2000);
}
/* Bring up the supplies */
- regulator_enable(mt9p031->vdd);
- regulator_enable(mt9p031->vdd_io);
- regulator_enable(mt9p031->vaa);
+ ret = regulator_bulk_enable(ARRAY_SIZE(mt9p031->regulators),
+ mt9p031->regulators);
+ if (ret < 0)
+ return ret;
/* Emable clock */
if (mt9p031->clk)
clk_prepare_enable(mt9p031->clk);
/* Now RESET_BAR must be high */
- if (mt9p031->reset != -1) {
+ if (gpio_is_valid(mt9p031->reset)) {
gpio_set_value(mt9p031->reset, 1);
usleep_range(1000, 2000);
}
@@ -297,14 +299,13 @@
static void mt9p031_power_off(struct mt9p031 *mt9p031)
{
- if (mt9p031->reset != -1) {
+ if (gpio_is_valid(mt9p031->reset)) {
gpio_set_value(mt9p031->reset, 0);
usleep_range(1000, 2000);
}
- regulator_disable(mt9p031->vaa);
- regulator_disable(mt9p031->vdd_io);
- regulator_disable(mt9p031->vdd);
+ regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
+ mt9p031->regulators);
if (mt9p031->clk)
clk_disable_unprepare(mt9p031->clk);
@@ -849,18 +850,18 @@
/* Read out the chip version register */
data = mt9p031_read(client, MT9P031_CHIP_VERSION);
+ mt9p031_power_off(mt9p031);
+
if (data != MT9P031_CHIP_VERSION_VALUE) {
dev_err(&client->dev, "MT9P031 not detected, wrong version "
"0x%04x\n", data);
return -ENODEV;
}
- mt9p031_power_off(mt9p031);
-
dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n",
client->addr);
- return ret;
+ return 0;
}
static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
@@ -928,10 +929,36 @@
* Driver initialization and probing
*/
+static struct mt9p031_platform_data *
+mt9p031_get_pdata(struct i2c_client *client)
+{
+ struct mt9p031_platform_data *pdata;
+ struct device_node *np;
+
+ if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
+ return client->dev.platform_data;
+
+ np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+ if (!np)
+ return NULL;
+
+ pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ goto done;
+
+ pdata->reset = of_get_named_gpio(client->dev.of_node, "reset-gpios", 0);
+ of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq);
+ of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq);
+
+done:
+ of_node_put(np);
+ return pdata;
+}
+
static int mt9p031_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
- struct mt9p031_platform_data *pdata = client->dev.platform_data;
+ struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct mt9p031 *mt9p031;
unsigned int i;
@@ -958,14 +985,14 @@
mt9p031->model = did->driver_data;
mt9p031->reset = -1;
- mt9p031->vaa = devm_regulator_get(&client->dev, "vaa");
- mt9p031->vdd = devm_regulator_get(&client->dev, "vdd");
- mt9p031->vdd_io = devm_regulator_get(&client->dev, "vdd_io");
+ mt9p031->regulators[0].supply = "vdd";
+ mt9p031->regulators[1].supply = "vdd_io";
+ mt9p031->regulators[2].supply = "vaa";
- if (IS_ERR(mt9p031->vaa) || IS_ERR(mt9p031->vdd) ||
- IS_ERR(mt9p031->vdd_io)) {
+ ret = devm_regulator_bulk_get(&client->dev, 3, mt9p031->regulators);
+ if (ret < 0) {
dev_err(&client->dev, "Unable to get regulators\n");
- return -ENODEV;
+ return ret;
}
v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6);
@@ -1031,7 +1058,7 @@
mt9p031->format.field = V4L2_FIELD_NONE;
mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
- if (pdata->reset != -1) {
+ if (gpio_is_valid(pdata->reset)) {
ret = devm_gpio_request_one(&client->dev, pdata->reset,
GPIOF_OUT_INIT_LOW, "mt9p031_rst");
if (ret < 0)
@@ -1070,8 +1097,18 @@
};
MODULE_DEVICE_TABLE(i2c, mt9p031_id);
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id mt9p031_of_match[] = {
+ { .compatible = "aptina,mt9p031", },
+ { .compatible = "aptina,mt9p031m", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt9p031_of_match);
+#endif
+
static struct i2c_driver mt9p031_i2c_driver = {
.driver = {
+ .of_match_table = of_match_ptr(mt9p031_of_match),
.name = "mt9p031",
},
.probe = mt9p031_probe,
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index 2e189d8..7964634 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -740,7 +740,7 @@
if (ret < 0)
return ret;
- mt9t001 = kzalloc(sizeof(*mt9t001), GFP_KERNEL);
+ mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
if (!mt9t001)
return -ENOMEM;
@@ -801,7 +801,6 @@
if (ret < 0) {
v4l2_ctrl_handler_free(&mt9t001->ctrls);
media_entity_cleanup(&mt9t001->subdev.entity);
- kfree(mt9t001);
}
return ret;
@@ -815,7 +814,6 @@
v4l2_ctrl_handler_free(&mt9t001->ctrls);
v4l2_device_unregister_subdev(subdev);
media_entity_cleanup(&subdev->entity);
- kfree(mt9t001);
return 0;
}
diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 3f415fd..f74698c 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <asm/div64.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/mt9v011.h>
@@ -407,13 +406,6 @@
static int mt9v011_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
reg->val = mt9v011_read(sd, reg->reg & 0xff);
reg->size = 2;
@@ -423,31 +415,12 @@
static int mt9v011_s_register(struct v4l2_subdev *sd,
const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
mt9v011_write(sd, reg->reg & 0xff, reg->val & 0xffff);
return 0;
}
#endif
-static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- u16 version;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011,
- version);
-}
-
static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct mt9v011 *core =
@@ -489,7 +462,6 @@
static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
.reset = mt9v011_reset,
- .g_chip_ident = mt9v011_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = mt9v011_g_register,
.s_register = mt9v011_s_register,
@@ -526,7 +498,7 @@
I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
return -EIO;
- core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL);
+ core = devm_kzalloc(&c->dev, sizeof(struct mt9v011), GFP_KERNEL);
if (!core)
return -ENOMEM;
@@ -539,7 +511,6 @@
(version != MT9V011_REV_B_VERSION)) {
v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
version);
- kfree(core);
return -EINVAL;
}
@@ -562,7 +533,6 @@
v4l2_err(sd, "control initialization error %d\n", ret);
v4l2_ctrl_handler_free(&core->ctrls);
- kfree(core);
return ret;
}
core->sd.ctrl_handler = &core->ctrls;
@@ -598,7 +568,7 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&core->ctrls);
- kfree(to_mt9v011(sd));
+
return 0;
}
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 3f356cb..60c6f67 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -744,7 +744,7 @@
return -EIO;
}
- mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
+ mt9v032 = devm_kzalloc(&client->dev, sizeof(*mt9v032), GFP_KERNEL);
if (!mt9v032)
return -ENOMEM;
@@ -830,8 +830,9 @@
mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
+
if (ret < 0)
- kfree(mt9v032);
+ v4l2_ctrl_handler_free(&mt9v032->ctrls);
return ret;
}
@@ -841,9 +842,10 @@
struct v4l2_subdev *subdev = i2c_get_clientdata(client);
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+ v4l2_ctrl_handler_free(&mt9v032->ctrls);
v4l2_device_unregister_subdev(subdev);
media_entity_cleanup(&subdev->entity);
- kfree(mt9v032);
+
return 0;
}
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
index 8554b47..271d0b7 100644
--- a/drivers/media/i2c/noon010pc30.c
+++ b/drivers/media/i2c/noon010pc30.c
@@ -19,7 +19,6 @@
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <media/noon010pc30.h>
-#include <media/v4l2-chip-ident.h>
#include <linux/videodev2.h>
#include <linux/module.h>
#include <media/v4l2-ctrls.h>
@@ -712,7 +711,7 @@
return -EIO;
}
- info = kzalloc(sizeof(*info), GFP_KERNEL);
+ info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
@@ -746,57 +745,50 @@
info->curr_win = &noon010_sizes[0];
if (gpio_is_valid(pdata->gpio_nreset)) {
- ret = gpio_request(pdata->gpio_nreset, "NOON010PC30 NRST");
+ ret = devm_gpio_request_one(&client->dev, pdata->gpio_nreset,
+ GPIOF_OUT_INIT_LOW,
+ "NOON010PC30 NRST");
if (ret) {
dev_err(&client->dev, "GPIO request error: %d\n", ret);
goto np_err;
}
info->gpio_nreset = pdata->gpio_nreset;
- gpio_direction_output(info->gpio_nreset, 0);
gpio_export(info->gpio_nreset, 0);
}
if (gpio_is_valid(pdata->gpio_nstby)) {
- ret = gpio_request(pdata->gpio_nstby, "NOON010PC30 NSTBY");
+ ret = devm_gpio_request_one(&client->dev, pdata->gpio_nstby,
+ GPIOF_OUT_INIT_LOW,
+ "NOON010PC30 NSTBY");
if (ret) {
dev_err(&client->dev, "GPIO request error: %d\n", ret);
- goto np_gpio_err;
+ goto np_err;
}
info->gpio_nstby = pdata->gpio_nstby;
- gpio_direction_output(info->gpio_nstby, 0);
gpio_export(info->gpio_nstby, 0);
}
for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
info->supply[i].supply = noon010_supply_name[i];
- ret = regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
+ ret = devm_regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
info->supply);
if (ret)
- goto np_reg_err;
+ goto np_err;
info->pad.flags = MEDIA_PAD_FL_SOURCE;
sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
if (ret < 0)
- goto np_me_err;
+ goto np_err;
ret = noon010_detect(client, info);
if (!ret)
return 0;
-np_me_err:
- regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
-np_reg_err:
- if (gpio_is_valid(info->gpio_nstby))
- gpio_free(info->gpio_nstby);
-np_gpio_err:
- if (gpio_is_valid(info->gpio_nreset))
- gpio_free(info->gpio_nreset);
np_err:
v4l2_ctrl_handler_free(&info->hdl);
v4l2_device_unregister_subdev(sd);
- kfree(info);
return ret;
}
@@ -807,17 +799,8 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&info->hdl);
-
- regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
-
- if (gpio_is_valid(info->gpio_nreset))
- gpio_free(info->gpio_nreset);
-
- if (gpio_is_valid(info->gpio_nstby))
- gpio_free(info->gpio_nstby);
-
media_entity_cleanup(&sd->entity);
- kfree(info);
+
return 0;
}
diff --git a/drivers/media/i2c/ov7640.c b/drivers/media/i2c/ov7640.c
index b0cc927..faa64ba 100644
--- a/drivers/media/i2c/ov7640.c
+++ b/drivers/media/i2c/ov7640.c
@@ -20,7 +20,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <linux/slab.h>
MODULE_DESCRIPTION("OmniVision ov7640 sensor driver");
@@ -59,7 +58,7 @@
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
if (sd == NULL)
return -ENOMEM;
v4l2_i2c_subdev_init(sd, client, &ov7640_ops);
@@ -71,7 +70,6 @@
if (write_regs(client, initial_registers) < 0) {
v4l_err(client, "error initializing OV7640\n");
- kfree(sd);
return -ENODEV;
}
@@ -84,7 +82,7 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(sd);
+
return 0;
}
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 617ad3f..e8a1ce2 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -17,7 +17,6 @@
#include <linux/delay.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-mediabus.h>
#include <media/ov7670.h>
@@ -1462,25 +1461,12 @@
.g_volatile_ctrl = ov7670_g_volatile_ctrl,
};
-static int ov7670_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0);
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
unsigned char val = 0;
int ret;
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
ret = ov7670_read(sd, reg->reg & 0xff, &val);
reg->val = val;
reg->size = 1;
@@ -1489,12 +1475,6 @@
static int ov7670_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
ov7670_write(sd, reg->reg & 0xff, reg->val & 0xff);
return 0;
}
@@ -1503,7 +1483,6 @@
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops ov7670_core_ops = {
- .g_chip_ident = ov7670_g_chip_ident,
.reset = ov7670_reset,
.init = ov7670_init,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1552,7 +1531,7 @@
struct ov7670_info *info;
int ret;
- info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL);
+ info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
if (info == NULL)
return -ENOMEM;
sd = &info->sd;
@@ -1590,7 +1569,6 @@
v4l_dbg(1, debug, client,
"chip found @ 0x%x (%s) is not an ov7670 chip.\n",
client->addr << 1, client->adapter->name);
- kfree(info);
return ret;
}
v4l_info(client, "chip found @ 0x%02x (%s)\n",
@@ -1635,7 +1613,6 @@
int err = info->hdl.error;
v4l2_ctrl_handler_free(&info->hdl);
- kfree(info);
return err;
}
/*
@@ -1659,7 +1636,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&info->hdl);
- kfree(info);
return 0;
}
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 9eac531..825ea86 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1385,9 +1385,12 @@
}
return 0;
err:
- for (++i; i < S5C73M3_MAX_SUPPLIES; i++)
- regulator_enable(state->supplies[i].consumer);
-
+ for (++i; i < S5C73M3_MAX_SUPPLIES; i++) {
+ int r = regulator_enable(state->supplies[i].consumer);
+ if (r < 0)
+ v4l2_err(&state->oif_sd, "Failed to reenable %s: %d\n",
+ state->supplies[i].supply, r);
+ }
return ret;
}
@@ -1511,59 +1514,40 @@
.video = &s5c73m3_oif_video_ops,
};
-static int s5c73m3_configure_gpio(int nr, int val, const char *name)
-{
- unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
- int ret;
-
- if (!gpio_is_valid(nr))
- return 0;
- ret = gpio_request_one(nr, flags, name);
- if (!ret)
- gpio_export(nr, 0);
- return ret;
-}
-
-static int s5c73m3_free_gpios(struct s5c73m3 *state)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(state->gpio); i++) {
- if (!gpio_is_valid(state->gpio[i].gpio))
- continue;
- gpio_free(state->gpio[i].gpio);
- state->gpio[i].gpio = -EINVAL;
- }
- return 0;
-}
-
static int s5c73m3_configure_gpios(struct s5c73m3 *state,
const struct s5c73m3_platform_data *pdata)
{
- const struct s5c73m3_gpio *gpio = &pdata->gpio_stby;
+ struct device *dev = &state->i2c_client->dev;
+ const struct s5c73m3_gpio *gpio;
+ unsigned long flags;
int ret;
state->gpio[STBY].gpio = -EINVAL;
state->gpio[RST].gpio = -EINVAL;
- ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_STBY");
- if (ret) {
- s5c73m3_free_gpios(state);
- return ret;
+ gpio = &pdata->gpio_stby;
+ if (gpio_is_valid(gpio->gpio)) {
+ flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+ | GPIOF_EXPORT;
+ ret = devm_gpio_request_one(dev, gpio->gpio, flags,
+ "S5C73M3_STBY");
+ if (ret < 0)
+ return ret;
+
+ state->gpio[STBY] = *gpio;
}
- state->gpio[STBY] = *gpio;
- if (gpio_is_valid(gpio->gpio))
- gpio_set_value(gpio->gpio, 0);
gpio = &pdata->gpio_reset;
- ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_RST");
- if (ret) {
- s5c73m3_free_gpios(state);
- return ret;
+ if (gpio_is_valid(gpio->gpio)) {
+ flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+ | GPIOF_EXPORT;
+ ret = devm_gpio_request_one(dev, gpio->gpio, flags,
+ "S5C73M3_RST");
+ if (ret < 0)
+ return ret;
+
+ state->gpio[RST] = *gpio;
}
- state->gpio[RST] = *gpio;
- if (gpio_is_valid(gpio->gpio))
- gpio_set_value(gpio->gpio, 0);
return 0;
}
@@ -1626,10 +1610,11 @@
state->mclk_frequency = pdata->mclk_frequency;
state->bus_type = pdata->bus_type;
+ state->i2c_client = client;
ret = s5c73m3_configure_gpios(state, pdata);
if (ret)
- goto out_err1;
+ goto out_err;
for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++)
state->supplies[i].supply = s5c73m3_supply_names[i];
@@ -1638,12 +1623,12 @@
state->supplies);
if (ret) {
dev_err(dev, "failed to get regulators\n");
- goto out_err2;
+ goto out_err;
}
ret = s5c73m3_init_controls(state);
if (ret)
- goto out_err2;
+ goto out_err;
state->sensor_pix_size[RES_ISP] = &s5c73m3_isp_resolutions[1];
state->sensor_pix_size[RES_JPEG] = &s5c73m3_jpeg_resolutions[1];
@@ -1659,16 +1644,12 @@
ret = s5c73m3_register_spi_driver(state);
if (ret < 0)
- goto out_err2;
-
- state->i2c_client = client;
+ goto out_err;
v4l2_info(sd, "%s: completed succesfully\n", __func__);
return 0;
-out_err2:
- s5c73m3_free_gpios(state);
-out_err1:
+out_err:
media_entity_cleanup(&sd->entity);
return ret;
}
@@ -1688,7 +1669,6 @@
media_entity_cleanup(&sensor_sd->entity);
s5c73m3_unregister_spi_driver(state);
- s5c73m3_free_gpios(state);
return 0;
}
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
index 6f3a9c0..8079e26 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
@@ -73,7 +73,7 @@
memset(padding, 0, sizeof(padding));
- for (i = 0; i < count ; i++) {
+ for (i = 0; i < count; i++) {
r = spi_xmit(spi_dev, (void *)addr + j, tx_size, SPI_DIR_TX);
if (r < 0)
return r;
@@ -98,7 +98,7 @@
unsigned int i, j = 0;
int r = 0;
- for (i = 0; i < count ; i++) {
+ for (i = 0; i < count; i++) {
r = spi_xmit(spi_dev, addr + j, tx_size, SPI_DIR_RX);
if (r < 0)
return r;
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index bdf5e3d..789c02a 100644
--- a/drivers/media/i2c/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -1491,58 +1491,41 @@
/*
* GPIO setup
*/
-static int s5k6aa_configure_gpio(int nr, int val, const char *name)
-{
- unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
- int ret;
-
- if (!gpio_is_valid(nr))
- return 0;
- ret = gpio_request_one(nr, flags, name);
- if (!ret)
- gpio_export(nr, 0);
- return ret;
-}
-
-static void s5k6aa_free_gpios(struct s5k6aa *s5k6aa)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(s5k6aa->gpio); i++) {
- if (!gpio_is_valid(s5k6aa->gpio[i].gpio))
- continue;
- gpio_free(s5k6aa->gpio[i].gpio);
- s5k6aa->gpio[i].gpio = -EINVAL;
- }
-}
static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
const struct s5k6aa_platform_data *pdata)
{
- const struct s5k6aa_gpio *gpio = &pdata->gpio_stby;
+ struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+ const struct s5k6aa_gpio *gpio;
+ unsigned long flags;
int ret;
s5k6aa->gpio[STBY].gpio = -EINVAL;
s5k6aa->gpio[RST].gpio = -EINVAL;
- ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_STBY");
- if (ret) {
- s5k6aa_free_gpios(s5k6aa);
- return ret;
+ gpio = &pdata->gpio_stby;
+ if (gpio_is_valid(gpio->gpio)) {
+ flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+ | GPIOF_EXPORT;
+ ret = devm_gpio_request_one(&client->dev, gpio->gpio, flags,
+ "S5K6AA_STBY");
+ if (ret < 0)
+ return ret;
+
+ s5k6aa->gpio[STBY] = *gpio;
}
- s5k6aa->gpio[STBY] = *gpio;
- if (gpio_is_valid(gpio->gpio))
- gpio_set_value(gpio->gpio, 0);
gpio = &pdata->gpio_reset;
- ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_RST");
- if (ret) {
- s5k6aa_free_gpios(s5k6aa);
- return ret;
+ if (gpio_is_valid(gpio->gpio)) {
+ flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+ | GPIOF_EXPORT;
+ ret = devm_gpio_request_one(&client->dev, gpio->gpio, flags,
+ "S5K6AA_RST");
+ if (ret < 0)
+ return ret;
+
+ s5k6aa->gpio[RST] = *gpio;
}
- s5k6aa->gpio[RST] = *gpio;
- if (gpio_is_valid(gpio->gpio))
- gpio_set_value(gpio->gpio, 0);
return 0;
}
@@ -1593,7 +1576,7 @@
ret = s5k6aa_configure_gpios(s5k6aa, pdata);
if (ret)
- goto out_err2;
+ goto out_err;
for (i = 0; i < S5K6AA_NUM_SUPPLIES; i++)
s5k6aa->supplies[i].supply = s5k6aa_supply_names[i];
@@ -1602,12 +1585,12 @@
s5k6aa->supplies);
if (ret) {
dev_err(&client->dev, "Failed to get regulators\n");
- goto out_err3;
+ goto out_err;
}
ret = s5k6aa_initialize_ctrls(s5k6aa);
if (ret)
- goto out_err3;
+ goto out_err;
s5k6aa_presets_data_init(s5k6aa);
@@ -1618,9 +1601,7 @@
return 0;
-out_err3:
- s5k6aa_free_gpios(s5k6aa);
-out_err2:
+out_err:
media_entity_cleanup(&s5k6aa->sd.entity);
return ret;
}
@@ -1628,12 +1609,10 @@
static int s5k6aa_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct s5k6aa *s5k6aa = to_s5k6aa(sd);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(sd->ctrl_handler);
media_entity_cleanup(&sd->entity);
- s5k6aa_free_gpios(s5k6aa);
return 0;
}
diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c
index b4e1ccb..70bc72e 100644
--- a/drivers/media/i2c/saa6588.c
+++ b/drivers/media/i2c/saa6588.c
@@ -33,7 +33,6 @@
#include <media/saa6588.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
/* insmod options */
@@ -443,17 +442,9 @@
return 0;
}
-static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa6588_core_ops = {
- .g_chip_ident = saa6588_g_chip_ident,
.ioctl = saa6588_ioctl,
};
@@ -478,17 +469,15 @@
v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- s = kzalloc(sizeof(*s), GFP_KERNEL);
+ s = devm_kzalloc(&client->dev, sizeof(*s), GFP_KERNEL);
if (s == NULL)
return -ENOMEM;
s->buf_size = bufblocks * 3;
- s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
- if (s->buffer == NULL) {
- kfree(s);
+ s->buffer = devm_kzalloc(&client->dev, s->buf_size, GFP_KERNEL);
+ if (s->buffer == NULL)
return -ENOMEM;
- }
sd = &s->sd;
v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
spin_lock_init(&s->lock);
@@ -516,8 +505,6 @@
cancel_delayed_work_sync(&s->work);
- kfree(s->buffer);
- kfree(s);
return 0;
}
diff --git a/drivers/media/i2c/saa7110.c b/drivers/media/i2c/saa7110.c
index 51cd4c8..ac43e92 100644
--- a/drivers/media/i2c/saa7110.c
+++ b/drivers/media/i2c/saa7110.c
@@ -35,7 +35,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
@@ -203,7 +202,7 @@
status = saa7110_read(sd);
if (status & 0x40) {
v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
- return decoder->norm; /* no change*/
+ return V4L2_STD_UNKNOWN;
}
if ((status & 3) == 0) {
saa7110_write(sd, 0x06, 0x83);
@@ -265,7 +264,7 @@
static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{
- *(v4l2_std_id *)std = determine_norm(sd);
+ *std &= determine_norm(sd);
return 0;
}
@@ -352,13 +351,6 @@
return 0;
}
-static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7110, 0);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
@@ -366,7 +358,6 @@
};
static const struct v4l2_subdev_core_ops saa7110_core_ops = {
- .g_chip_ident = saa7110_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -406,7 +397,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
+ decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (!decoder)
return -ENOMEM;
sd = &decoder->sd;
@@ -428,7 +419,6 @@
int err = decoder->hdl.error;
v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
return err;
}
v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -469,7 +459,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
return 0;
}
diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index 52c717d..7fd766e 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -46,7 +46,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
#include <media/saa7115.h>
#include <asm/div64.h>
@@ -63,6 +62,16 @@
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+enum saa711x_model {
+ SAA7111A,
+ SAA7111,
+ SAA7113,
+ GM7113C,
+ SAA7114,
+ SAA7115,
+ SAA7118,
+};
+
struct saa711x_state {
struct v4l2_subdev sd;
struct v4l2_ctrl_handler hdl;
@@ -80,7 +89,7 @@
int radio;
int width;
int height;
- u32 ident;
+ enum saa711x_model ident;
u32 audclk_freq;
u32 crystal_freq;
bool ucgc;
@@ -111,10 +120,10 @@
/* Sanity routine to check if a register is present */
static int saa711x_has_reg(const int id, const u8 reg)
{
- if (id == V4L2_IDENT_SAA7111)
+ if (id == SAA7111)
return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
(reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
- if (id == V4L2_IDENT_SAA7111A)
+ if (id == SAA7111A)
return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
reg != 0x14 && reg != 0x18 && reg != 0x19 &&
reg != 0x1d && reg != 0x1e;
@@ -127,16 +136,18 @@
return 0;
switch (id) {
- case V4L2_IDENT_SAA7113:
+ case GM7113C:
+ return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && reg < 0x20;
+ case SAA7113:
return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
reg != 0x5d && reg < 0x63;
- case V4L2_IDENT_SAA7114:
+ case SAA7114:
return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
(reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
reg != 0x81 && reg < 0xf0;
- case V4L2_IDENT_SAA7115:
+ case SAA7115:
return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
- case V4L2_IDENT_SAA7118:
+ case SAA7118:
return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
(reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
(reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
@@ -214,7 +225,10 @@
0x00, 0x00
};
-/* SAA7113 init codes */
+/* SAA7113/GM7113C init codes
+ * It's important that R_14... R_17 == 0x00
+ * for the gm7113c chip to deliver stable video
+ */
static const unsigned char saa7113_init[] = {
R_01_INC_DELAY, 0x08,
R_02_INPUT_CNTL_1, 0xc2,
@@ -448,6 +462,24 @@
/* ============== SAA7715 VIDEO templates (end) ======= */
+/* ============== GM7113C VIDEO templates ============= */
+static const unsigned char gm7113c_cfg_60hz_video[] = {
+ R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
+ R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
+
+ 0x00, 0x00
+};
+
+static const unsigned char gm7113c_cfg_50hz_video[] = {
+ R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
+ R_0E_CHROMA_CNTL_1, 0x07,
+
+ 0x00, 0x00
+};
+
+/* ============== GM7113C VIDEO templates (end) ======= */
+
+
static const unsigned char saa7115_cfg_vbi_on[] = {
R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
@@ -932,11 +964,17 @@
// This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
if (std & V4L2_STD_525_60) {
v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
- saa711x_writeregs(sd, saa7115_cfg_60hz_video);
+ if (state->ident == GM7113C)
+ saa711x_writeregs(sd, gm7113c_cfg_60hz_video);
+ else
+ saa711x_writeregs(sd, saa7115_cfg_60hz_video);
saa711x_set_size(sd, 720, 480);
} else {
v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
- saa711x_writeregs(sd, saa7115_cfg_50hz_video);
+ if (state->ident == GM7113C)
+ saa711x_writeregs(sd, gm7113c_cfg_50hz_video);
+ else
+ saa711x_writeregs(sd, saa7115_cfg_50hz_video);
saa711x_set_size(sd, 720, 576);
}
@@ -949,7 +987,8 @@
011 NTSC N (3.58MHz) PAL M (3.58MHz)
100 reserved NTSC-Japan (3.58MHz)
*/
- if (state->ident <= V4L2_IDENT_SAA7113) {
+ if (state->ident <= SAA7113 ||
+ state->ident == GM7113C) {
u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
if (std == V4L2_STD_PAL_M) {
@@ -968,9 +1007,8 @@
/* restart task B if needed */
int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
- if (taskb && state->ident == V4L2_IDENT_SAA7114) {
+ if (taskb && state->ident == SAA7114)
saa711x_writeregs(sd, saa7115_cfg_vbi_on);
- }
/* switch audio mode too! */
saa711x_s_clock_freq(sd, state->audclk_freq);
@@ -992,7 +1030,7 @@
#else
/* SAA7113 and SAA7118 also should support VBI - Need testing */
- if (state->ident != V4L2_IDENT_SAA7115)
+ if (state->ident != SAA7115)
return;
#endif
@@ -1214,13 +1252,14 @@
u32 input, u32 output, u32 config)
{
struct saa711x_state *state = to_state(sd);
- u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
+ u8 mask = (state->ident <= SAA7111A) ? 0xf8 : 0xf0;
v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
input, output);
/* saa7111/3 does not have these inputs */
- if (state->ident <= V4L2_IDENT_SAA7113 &&
+ if ((state->ident <= SAA7113 ||
+ state->ident == GM7113C) &&
(input == SAA7115_COMPOSITE4 ||
input == SAA7115_COMPOSITE5)) {
return -EINVAL;
@@ -1235,7 +1274,7 @@
state->input = input;
/* saa7111 has slightly different input numbering */
- if (state->ident <= V4L2_IDENT_SAA7111A) {
+ if (state->ident <= SAA7111A) {
if (input >= SAA7115_COMPOSITE4)
input -= 2;
/* saa7111 specific */
@@ -1258,13 +1297,13 @@
(state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
state->output = output;
- if (state->ident == V4L2_IDENT_SAA7114 ||
- state->ident == V4L2_IDENT_SAA7115) {
+ if (state->ident == SAA7114 ||
+ state->ident == SAA7115) {
saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
(saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
(state->output & 0x01));
}
- if (state->ident > V4L2_IDENT_SAA7111A) {
+ if (state->ident > SAA7111A) {
if (config & SAA7115_IDQ_IS_DEFAULT)
saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x20);
else
@@ -1277,7 +1316,7 @@
{
struct saa711x_state *state = to_state(sd);
- if (state->ident > V4L2_IDENT_SAA7111A)
+ if (state->ident > SAA7111A)
return -EINVAL;
saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
(val ? 0x80 : 0));
@@ -1367,7 +1406,7 @@
reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
- if (state->ident == V4L2_IDENT_SAA7115) {
+ if (state->ident == SAA7115) {
reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
@@ -1389,6 +1428,7 @@
*std &= V4L2_STD_SECAM;
break;
default:
+ *std = V4L2_STD_UNKNOWN;
/* Can't detect anything */
break;
}
@@ -1397,8 +1437,10 @@
v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
/* horizontal/vertical not locked */
- if (reg1f & 0x40)
+ if (reg1f & 0x40) {
+ *std = V4L2_STD_UNKNOWN;
goto ret;
+ }
if (reg1f & 0x20)
*std &= V4L2_STD_525_60;
@@ -1418,7 +1460,7 @@
int reg1f;
*status = V4L2_IN_ST_NO_SIGNAL;
- if (state->ident == V4L2_IDENT_SAA7115)
+ if (state->ident == SAA7115)
reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
@@ -1429,12 +1471,6 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = saa711x_read(sd, reg->reg & 0xff);
reg->size = 1;
return 0;
@@ -1442,25 +1478,11 @@
static int saa711x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
return 0;
}
#endif
-static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct saa711x_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
-}
-
static int saa711x_log_status(struct v4l2_subdev *sd)
{
struct saa711x_state *state = to_state(sd);
@@ -1469,7 +1491,7 @@
int vcr;
v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
- if (state->ident != V4L2_IDENT_SAA7115) {
+ if (state->ident != SAA7115) {
/* status for the saa7114 */
reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
signalOk = (reg1f & 0xc1) == 0x81;
@@ -1520,7 +1542,6 @@
static const struct v4l2_subdev_core_ops saa711x_core_ops = {
.log_status = saa711x_log_status,
- .g_chip_ident = saa711x_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -1571,55 +1592,145 @@
.vbi = &saa711x_vbi_ops,
};
+#define CHIP_VER_SIZE 16
+
/* ----------------------------------------------------------------------- */
+/**
+ * saa711x_detect_chip - Detects the saa711x (or clone) variant
+ * @client: I2C client structure.
+ * @id: I2C device ID structure.
+ * @name: Name of the device to be filled.
+ *
+ * Detects the Philips/NXP saa711x chip, or some clone of it.
+ * if 'id' is NULL or id->driver_data is equal to 1, it auto-probes
+ * the analog demod.
+ * If the tuner is not found, it returns -ENODEV.
+ * If auto-detection is disabled and the tuner doesn't match what it was
+ * requred, it returns -EINVAL and fills 'name'.
+ * If the chip is found, it returns the chip ID and fills 'name'.
+ */
+static int saa711x_detect_chip(struct i2c_client *client,
+ const struct i2c_device_id *id,
+ char *name)
+{
+ char chip_ver[CHIP_VER_SIZE];
+ char chip_id;
+ int i;
+ int autodetect;
+
+ autodetect = !id || id->driver_data == 1;
+
+ /* Read the chip version register */
+ for (i = 0; i < CHIP_VER_SIZE; i++) {
+ i2c_smbus_write_byte_data(client, 0, i);
+ chip_ver[i] = i2c_smbus_read_byte_data(client, 0);
+ name[i] = (chip_ver[i] & 0x0f) + '0';
+ if (name[i] > '9')
+ name[i] += 'a' - '9' - 1;
+ }
+ name[i] = '\0';
+
+ /* Check if it is a Philips/NXP chip */
+ if (!memcmp(name + 1, "f711", 4)) {
+ chip_id = name[5];
+ snprintf(name, CHIP_VER_SIZE, "saa711%c", chip_id);
+
+ if (!autodetect && strcmp(name, id->name))
+ return -EINVAL;
+
+ switch (chip_id) {
+ case '1':
+ if (chip_ver[0] & 0xf0) {
+ snprintf(name, CHIP_VER_SIZE, "saa711%ca", chip_id);
+ v4l_info(client, "saa7111a variant found\n");
+ return SAA7111A;
+ }
+ return SAA7111;
+ case '3':
+ return SAA7113;
+ case '4':
+ return SAA7114;
+ case '5':
+ return SAA7115;
+ case '8':
+ return SAA7118;
+ default:
+ v4l2_info(client,
+ "WARNING: Philips/NXP chip unknown - Falling back to saa7111\n");
+ return SAA7111;
+ }
+ }
+
+ /* Check if it is a gm7113c */
+ if (!memcmp(name, "0000", 4)) {
+ chip_id = 0;
+ for (i = 0; i < 4; i++) {
+ chip_id = chip_id << 1;
+ chip_id |= (chip_ver[i] & 0x80) ? 1 : 0;
+ }
+
+ /*
+ * Note: From the datasheet, only versions 1 and 2
+ * exists. However, tests on a device labeled as:
+ * "GM7113C 1145" returned "10" on all 16 chip
+ * version (reg 0x00) reads. So, we need to also
+ * accept at least verion 0. For now, let's just
+ * assume that a device that returns "0000" for
+ * the lower nibble is a gm7113c.
+ */
+
+ strlcpy(name, "gm7113c", CHIP_VER_SIZE);
+
+ if (!autodetect && strcmp(name, id->name))
+ return -EINVAL;
+
+ v4l_dbg(1, debug, client,
+ "It seems to be a %s chip (%*ph) @ 0x%x.\n",
+ name, 16, chip_ver, client->addr << 1);
+
+ return GM7113C;
+ }
+
+ /* Chip was not discovered. Return its ID and don't bind */
+ v4l_dbg(1, debug, client, "chip %*ph @ 0x%x is unknown.\n",
+ 16, chip_ver, client->addr << 1);
+ return -ENODEV;
+}
+
static int saa711x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct saa711x_state *state;
struct v4l2_subdev *sd;
struct v4l2_ctrl_handler *hdl;
- int i;
- char name[17];
- char chip_id;
- int autodetect = !id || id->driver_data == 1;
+ int ident;
+ char name[CHIP_VER_SIZE + 1];
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
- for (i = 0; i < 0x0f; i++) {
- i2c_smbus_write_byte_data(client, 0, i);
- name[i] = (i2c_smbus_read_byte_data(client, 0) & 0x0f) + '0';
- if (name[i] > '9')
- name[i] += 'a' - '9' - 1;
- }
- name[i] = '\0';
-
- chip_id = name[5];
-
- /* Check whether this chip is part of the saa711x series */
- if (memcmp(name + 1, "f711", 4)) {
- v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
- client->addr << 1, name);
+ ident = saa711x_detect_chip(client, id, name);
+ if (ident == -EINVAL) {
+ /* Chip exists, but doesn't match */
+ v4l_warn(client, "found %s while %s was expected\n",
+ name, id->name);
return -ENODEV;
}
+ if (ident < 0)
+ return ident;
- /* Safety check */
- if (!autodetect && id->name[6] != chip_id) {
- v4l_warn(client, "found saa711%c while %s was expected\n",
- chip_id, id->name);
- }
- snprintf(client->name, sizeof(client->name), "saa711%c", chip_id);
- v4l_info(client, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id, name,
- client->addr << 1, client->adapter->name);
+ strlcpy(client->name, name, sizeof(client->name));
- state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
+ v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+ client->addr << 1, client->adapter->name);
hdl = &state->hdl;
v4l2_ctrl_handler_init(hdl, 6);
/* add in ascending ID order */
@@ -1640,7 +1751,6 @@
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
- kfree(state);
return err;
}
v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
@@ -1649,31 +1759,7 @@
state->output = SAA7115_IPORT_ON;
state->enable = 1;
state->radio = 0;
- switch (chip_id) {
- case '1':
- state->ident = V4L2_IDENT_SAA7111;
- if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
- v4l_info(client, "saa7111a variant found\n");
- state->ident = V4L2_IDENT_SAA7111A;
- }
- break;
- case '3':
- state->ident = V4L2_IDENT_SAA7113;
- break;
- case '4':
- state->ident = V4L2_IDENT_SAA7114;
- break;
- case '5':
- state->ident = V4L2_IDENT_SAA7115;
- break;
- case '8':
- state->ident = V4L2_IDENT_SAA7118;
- break;
- default:
- state->ident = V4L2_IDENT_SAA7111;
- v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
- break;
- }
+ state->ident = ident;
state->audclk_freq = 48000;
@@ -1682,18 +1768,19 @@
/* init to 60hz/48khz */
state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
switch (state->ident) {
- case V4L2_IDENT_SAA7111:
- case V4L2_IDENT_SAA7111A:
+ case SAA7111:
+ case SAA7111A:
saa711x_writeregs(sd, saa7111_init);
break;
- case V4L2_IDENT_SAA7113:
+ case GM7113C:
+ case SAA7113:
saa711x_writeregs(sd, saa7113_init);
break;
default:
state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
saa711x_writeregs(sd, saa7115_init_auto_input);
}
- if (state->ident > V4L2_IDENT_SAA7111A)
+ if (state->ident > SAA7111A)
saa711x_writeregs(sd, saa7115_init_misc);
saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
v4l2_ctrl_handler_setup(hdl);
@@ -1712,7 +1799,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- kfree(to_state(sd));
return 0;
}
@@ -1723,6 +1809,7 @@
{ "saa7114", 0 },
{ "saa7115", 0 },
{ "saa7118", 0 },
+ { "gm7113c", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, saa711x_id);
diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c
index 8a47ac1..264b755 100644
--- a/drivers/media/i2c/saa7127.c
+++ b/drivers/media/i2c/saa7127.c
@@ -54,7 +54,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/saa7127.h>
static int debug;
@@ -251,10 +250,15 @@
**********************************************************************
*/
+enum saa712x_model {
+ SAA7127,
+ SAA7129,
+};
+
struct saa7127_state {
struct v4l2_subdev sd;
v4l2_std_id std;
- u32 ident;
+ enum saa712x_model ident;
enum saa7127_input_type input_type;
enum saa7127_output_type output_type;
int video_enable;
@@ -482,7 +486,7 @@
inittab = saa7127_init_config_60hz;
state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
- } else if (state->ident == V4L2_IDENT_SAA7129 &&
+ } else if (state->ident == SAA7129 &&
(std & V4L2_STD_SECAM) &&
!(std & (V4L2_STD_625_50 & ~V4L2_STD_SECAM))) {
@@ -517,7 +521,7 @@
break;
case SAA7127_OUTPUT_TYPE_COMPOSITE:
- if (state->ident == V4L2_IDENT_SAA7129)
+ if (state->ident == SAA7129)
state->reg_2d = 0x20; /* CVBS only */
else
state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
@@ -525,7 +529,7 @@
break;
case SAA7127_OUTPUT_TYPE_SVIDEO:
- if (state->ident == V4L2_IDENT_SAA7129)
+ if (state->ident == SAA7129)
state->reg_2d = 0x18; /* Y + C */
else
state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */
@@ -543,7 +547,7 @@
break;
case SAA7127_OUTPUT_TYPE_BOTH:
- if (state->ident == V4L2_IDENT_SAA7129)
+ if (state->ident == SAA7129)
state->reg_2d = 0x38;
else
state->reg_2d = 0xbf;
@@ -661,12 +665,6 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = saa7127_read(sd, reg->reg & 0xff);
reg->size = 1;
return 0;
@@ -674,25 +672,11 @@
static int saa7127_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
saa7127_write(sd, reg->reg & 0xff, reg->val & 0xff);
return 0;
}
#endif
-static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct saa7127_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
-}
-
static int saa7127_log_status(struct v4l2_subdev *sd)
{
struct saa7127_state *state = to_state(sd);
@@ -712,7 +696,6 @@
static const struct v4l2_subdev_core_ops saa7127_core_ops = {
.log_status = saa7127_log_status,
- .g_chip_ident = saa7127_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = saa7127_g_register,
.s_register = saa7127_s_register,
@@ -752,7 +735,7 @@
v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n",
client->addr << 1);
- state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
@@ -767,7 +750,6 @@
if ((saa7127_read(sd, 0) & 0xe4) != 0 ||
(saa7127_read(sd, 0x29) & 0x3f) != 0x1d) {
v4l2_dbg(1, debug, sd, "saa7127 not found\n");
- kfree(state);
return -ENODEV;
}
@@ -782,10 +764,10 @@
if (saa7127_read(sd, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
saa7127_write(sd, SAA7129_REG_FADE_KEY_COL2,
read_result);
- state->ident = V4L2_IDENT_SAA7129;
+ state->ident = SAA7129;
strlcpy(client->name, "saa7129", I2C_NAME_SIZE);
} else {
- state->ident = V4L2_IDENT_SAA7127;
+ state->ident = SAA7127;
strlcpy(client->name, "saa7127", I2C_NAME_SIZE);
}
}
@@ -809,7 +791,7 @@
saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
saa7127_set_video_enable(sd, 1);
- if (state->ident == V4L2_IDENT_SAA7129)
+ if (state->ident == SAA7129)
saa7127_write_inittab(sd, saa7129_init_config_extra);
return 0;
}
@@ -823,7 +805,6 @@
v4l2_device_unregister_subdev(sd);
/* Turn off TV output */
saa7127_set_video_enable(sd, 0);
- kfree(to_state(sd));
return 0;
}
@@ -831,10 +812,10 @@
static struct i2c_device_id saa7127_id[] = {
{ "saa7127_auto", 0 }, /* auto-detection */
- { "saa7126", V4L2_IDENT_SAA7127 },
- { "saa7127", V4L2_IDENT_SAA7127 },
- { "saa7128", V4L2_IDENT_SAA7129 },
- { "saa7129", V4L2_IDENT_SAA7129 },
+ { "saa7126", SAA7127 },
+ { "saa7127", SAA7127 },
+ { "saa7128", SAA7129 },
+ { "saa7129", SAA7129 },
{ }
};
MODULE_DEVICE_TABLE(i2c, saa7127_id);
diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c
index cf3a0aa..401ca11 100644
--- a/drivers/media/i2c/saa717x.c
+++ b/drivers/media/i2c/saa717x.c
@@ -977,12 +977,6 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = saa717x_read(sd, reg->reg);
reg->size = 1;
return 0;
@@ -990,14 +984,9 @@
static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
u16 addr = reg->reg & 0xffff;
u8 val = reg->val & 0xff;
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
saa717x_write(sd, addr, val);
return 0;
}
@@ -1262,7 +1251,7 @@
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
- decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
+ decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
@@ -1276,7 +1265,6 @@
id = saa717x_read(sd, 0x5a0);
if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
- kfree(decoder);
return -ENODEV;
}
if (id == 0xc2)
@@ -1316,7 +1304,6 @@
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
- kfree(decoder);
return err;
}
@@ -1353,7 +1340,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/saa7185.c b/drivers/media/i2c/saa7185.c
index 2c6b65c..f56c1c8 100644
--- a/drivers/media/i2c/saa7185.c
+++ b/drivers/media/i2c/saa7185.c
@@ -32,7 +32,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
MODULE_AUTHOR("Dave Perks");
@@ -285,17 +284,9 @@
return 0;
}
-static int saa7185_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7185, 0);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa7185_core_ops = {
- .g_chip_ident = saa7185_g_chip_ident,
.init = saa7185_init,
};
@@ -326,7 +317,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
+ encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
encoder->norm = V4L2_STD_NTSC;
@@ -352,7 +343,6 @@
v4l2_device_unregister_subdev(sd);
/* SW: output off is active */
saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
- kfree(encoder);
return 0;
}
diff --git a/drivers/media/i2c/saa7191.c b/drivers/media/i2c/saa7191.c
index d7d1670..606a4ba 100644
--- a/drivers/media/i2c/saa7191.c
+++ b/drivers/media/i2c/saa7191.c
@@ -22,7 +22,6 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include "saa7191.h"
@@ -272,7 +271,7 @@
dprintk("SAA7191 extended signal auto-detection...\n");
- *norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
+ *norm &= V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_FSEL);
@@ -303,7 +302,7 @@
if (status & SAA7191_STATUS_FIDT) {
/* 60Hz signal -> NTSC */
dprintk("60Hz signal: NTSC\n");
- *norm = V4L2_STD_NTSC;
+ *norm &= V4L2_STD_NTSC;
return 0;
}
@@ -325,12 +324,13 @@
if (status & SAA7191_STATUS_FIDT) {
dprintk("No 50Hz signal\n");
saa7191_s_std(sd, old_norm);
- return -EAGAIN;
+ *norm = V4L2_STD_UNKNOWN;
+ return 0;
}
if (status & SAA7191_STATUS_CODE) {
dprintk("PAL\n");
- *norm = V4L2_STD_PAL;
+ *norm &= V4L2_STD_PAL;
return saa7191_s_std(sd, old_norm);
}
@@ -350,18 +350,19 @@
/* not 50Hz ? */
if (status & SAA7191_STATUS_FIDT) {
dprintk("No 50Hz signal\n");
- err = -EAGAIN;
+ *norm = V4L2_STD_UNKNOWN;
goto out;
}
if (status & SAA7191_STATUS_CODE) {
/* Color detected -> SECAM */
dprintk("SECAM\n");
- *norm = V4L2_STD_SECAM;
+ *norm &= V4L2_STD_SECAM;
return saa7191_s_std(sd, old_norm);
}
dprintk("No color detected with SECAM - Going back to PAL.\n");
+ *norm = V4L2_STD_UNKNOWN;
out:
return saa7191_s_std(sd, old_norm);
@@ -567,18 +568,9 @@
}
-static int saa7191_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa7191_core_ops = {
- .g_chip_ident = saa7191_g_chip_ident,
.g_ctrl = saa7191_g_ctrl,
.s_ctrl = saa7191_s_ctrl,
.s_std = saa7191_s_std,
@@ -605,7 +597,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+ decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (!decoder)
return -ENOMEM;
@@ -615,7 +607,6 @@
err = saa7191_write_block(sd, sizeof(initseq), initseq);
if (err) {
printk(KERN_ERR "SAA7191 initialization failed\n");
- kfree(decoder);
return err;
}
@@ -636,7 +627,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_saa7191(sd));
return 0;
}
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index cae4f46..7ac7580 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2383,8 +2383,9 @@
}
if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) {
- if (gpio_request_one(sensor->platform_data->xshutdown, 0,
- "SMIA++ xshutdown") != 0) {
+ if (devm_gpio_request_one(&client->dev,
+ sensor->platform_data->xshutdown, 0,
+ "SMIA++ xshutdown") != 0) {
dev_err(&client->dev,
"unable to acquire reset gpio %d\n",
sensor->platform_data->xshutdown);
@@ -2393,10 +2394,8 @@
}
rval = smiapp_power_on(sensor);
- if (rval) {
- rval = -ENODEV;
- goto out_smiapp_power_on;
- }
+ if (rval)
+ return -ENODEV;
rval = smiapp_identify_module(subdev);
if (rval) {
@@ -2656,11 +2655,6 @@
out_power_off:
smiapp_power_off(sensor);
-
-out_smiapp_power_on:
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
- gpio_free(sensor->platform_data->xshutdown);
-
return rval;
}
@@ -2854,12 +2848,10 @@
device_remove_file(&client->dev, &dev_attr_nvm);
for (i = 0; i < sensor->ssds_used; i++) {
- media_entity_cleanup(&sensor->ssds[i].sd.entity);
v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
+ media_entity_cleanup(&sensor->ssds[i].sd.entity);
}
smiapp_free_controls(sensor);
- if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
- gpio_free(sensor->platform_data->xshutdown);
return 0;
}
diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c
index a2a5cbb..1d384a3 100644
--- a/drivers/media/i2c/soc_camera/imx074.c
+++ b/drivers/media/i2c/soc_camera/imx074.c
@@ -18,8 +18,9 @@
#include <linux/module.h>
#include <media/soc_camera.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
/* IMX074 registers */
@@ -77,6 +78,7 @@
struct imx074 {
struct v4l2_subdev subdev;
const struct imx074_datafmt *fmt;
+ struct v4l2_clk *clk;
};
static const struct imx074_datafmt imx074_colour_fmts[] = {
@@ -251,29 +253,13 @@
return reg_write(client, MODE_SELECT, !!enable);
}
-static int imx074_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = V4L2_IDENT_IMX074;
- id->revision = 0;
-
- return 0;
-}
-
static int imx074_s_power(struct v4l2_subdev *sd, int on)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct imx074 *priv = to_imx074(client);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
}
static int imx074_g_mbus_config(struct v4l2_subdev *sd,
@@ -299,7 +285,6 @@
};
static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
- .g_chip_ident = imx074_g_chip_ident,
.s_power = imx074_s_power,
};
@@ -431,6 +416,7 @@
struct imx074 *priv;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ int ret;
if (!ssdd) {
dev_err(&client->dev, "IMX074: missing platform data!\n");
@@ -451,12 +437,35 @@
priv->fmt = &imx074_colour_fmts[0];
- return imx074_video_probe(client);
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk)) {
+ dev_info(&client->dev, "Error %ld getting clock\n", PTR_ERR(priv->clk));
+ return -EPROBE_DEFER;
+ }
+
+ ret = soc_camera_power_init(&client->dev, ssdd);
+ if (ret < 0)
+ goto epwrinit;
+
+ ret = imx074_video_probe(client);
+ if (ret < 0)
+ goto eprobe;
+
+ return v4l2_async_register_subdev(&priv->subdev);
+
+epwrinit:
+eprobe:
+ v4l2_clk_put(priv->clk);
+ return ret;
}
static int imx074_remove(struct i2c_client *client)
{
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct imx074 *priv = to_imx074(client);
+
+ v4l2_async_unregister_subdev(&priv->subdev);
+ v4l2_clk_put(priv->clk);
if (ssdd->free_bus)
ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c
index dd90898..df97033 100644
--- a/drivers/media/i2c/soc_camera/mt9m001.c
+++ b/drivers/media/i2c/soc_camera/mt9m001.c
@@ -16,8 +16,8 @@
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
/*
@@ -94,10 +94,10 @@
struct v4l2_ctrl *exposure;
};
struct v4l2_rect rect; /* Sensor window */
+ struct v4l2_clk *clk;
const struct mt9m001_datafmt *fmt;
const struct mt9m001_datafmt *fmts;
int num_fmts;
- int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
unsigned int total_h;
unsigned short y_skip_top; /* Lines to skip at the top */
};
@@ -320,36 +320,15 @@
return 0;
}
-static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m001 *mt9m001 = to_mt9m001(client);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = mt9m001->model;
- id->revision = 0;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int mt9m001_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+ if (reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
reg->size = 2;
reg->val = reg_read(client, reg->reg);
@@ -364,12 +343,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+ if (reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
if (reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
@@ -381,8 +357,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct mt9m001 *mt9m001 = to_mt9m001(client);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, mt9m001->clk, on);
}
static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -505,11 +482,9 @@
switch (data) {
case 0x8411:
case 0x8421:
- mt9m001->model = V4L2_IDENT_MT9M001C12ST;
mt9m001->fmts = mt9m001_colour_fmts;
break;
case 0x8431:
- mt9m001->model = V4L2_IDENT_MT9M001C12STM;
mt9m001->fmts = mt9m001_monochrome_fmts;
break;
default:
@@ -580,7 +555,6 @@
};
static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
- .g_chip_ident = mt9m001_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = mt9m001_g_register,
.s_register = mt9m001_s_register,
@@ -710,9 +684,18 @@
mt9m001->rect.width = MT9M001_MAX_WIDTH;
mt9m001->rect.height = MT9M001_MAX_HEIGHT;
+ mt9m001->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(mt9m001->clk)) {
+ ret = PTR_ERR(mt9m001->clk);
+ goto eclkget;
+ }
+
ret = mt9m001_video_probe(ssdd, client);
- if (ret)
+ if (ret) {
+ v4l2_clk_put(mt9m001->clk);
+eclkget:
v4l2_ctrl_handler_free(&mt9m001->hdl);
+ }
return ret;
}
@@ -722,6 +705,7 @@
struct mt9m001 *mt9m001 = to_mt9m001(client);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ v4l2_clk_put(mt9m001->clk);
v4l2_device_unregister_subdev(&mt9m001->subdev);
v4l2_ctrl_handler_free(&mt9m001->hdl);
mt9m001_video_remove(ssdd);
diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c
index 8bd4e0d..de3605d 100644
--- a/drivers/media/i2c/soc_camera/mt9m111.c
+++ b/drivers/media/i2c/soc_camera/mt9m111.c
@@ -17,9 +17,9 @@
#include <linux/module.h>
#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
/*
* MT9M111, MT9M112 and MT9M131:
@@ -205,10 +205,9 @@
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
struct v4l2_ctrl *gain;
- int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code
- * from v4l2-chip-ident.h */
struct mt9m111_context *ctx;
struct v4l2_rect rect; /* cropping rectangle */
+ struct v4l2_clk *clk;
int width; /* output */
int height; /* sizes */
struct mutex power_lock; /* lock to protect power_count */
@@ -600,24 +599,6 @@
return ret;
}
-static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = mt9m111->model;
- id->revision = 0;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int mt9m111_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@@ -625,10 +606,8 @@
struct i2c_client *client = v4l2_get_subdevdata(sd);
int val;
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
+ if (reg->reg > 0x2ff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
val = mt9m111_reg_read(client, reg->reg);
reg->size = 2;
@@ -645,12 +624,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
+ if (reg->reg > 0x2ff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
@@ -801,14 +777,14 @@
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
int ret;
- ret = soc_camera_power_on(&client->dev, ssdd);
+ ret = soc_camera_power_on(&client->dev, ssdd, mt9m111->clk);
if (ret < 0)
return ret;
ret = mt9m111_resume(mt9m111);
if (ret < 0) {
dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
- soc_camera_power_off(&client->dev, ssdd);
+ soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
}
return ret;
@@ -820,7 +796,7 @@
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
mt9m111_suspend(mt9m111);
- soc_camera_power_off(&client->dev, ssdd);
+ soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
}
static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
@@ -856,7 +832,6 @@
};
static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
- .g_chip_ident = mt9m111_g_chip_ident,
.s_power = mt9m111_s_power,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = mt9m111_g_register,
@@ -923,12 +898,10 @@
switch (data) {
case 0x143a: /* MT9M111 or MT9M131 */
- mt9m111->model = V4L2_IDENT_MT9M111;
dev_info(&client->dev,
"Detected a MT9M111/MT9M131 chip ID %x\n", data);
break;
case 0x148c: /* MT9M112 */
- mt9m111->model = V4L2_IDENT_MT9M112;
dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
break;
default:
@@ -1002,9 +975,18 @@
mt9m111->lastpage = -1;
mutex_init(&mt9m111->power_lock);
+ mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(mt9m111->clk)) {
+ ret = PTR_ERR(mt9m111->clk);
+ goto eclkget;
+ }
+
ret = mt9m111_video_probe(client);
- if (ret)
+ if (ret) {
+ v4l2_clk_put(mt9m111->clk);
+eclkget:
v4l2_ctrl_handler_free(&mt9m111->hdl);
+ }
return ret;
}
@@ -1013,6 +995,7 @@
{
struct mt9m111 *mt9m111 = to_mt9m111(client);
+ v4l2_clk_put(mt9m111->clk);
v4l2_device_unregister_subdev(&mt9m111->subdev);
v4l2_ctrl_handler_free(&mt9m111->hdl);
diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c
index 26a15b8..47d18d0 100644
--- a/drivers/media/i2c/soc_camera/mt9t031.c
+++ b/drivers/media/i2c/soc_camera/mt9t031.c
@@ -18,7 +18,7 @@
#include <linux/module.h>
#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-ctrls.h>
@@ -76,7 +76,7 @@
struct v4l2_ctrl *exposure;
};
struct v4l2_rect rect; /* Sensor window */
- int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
+ struct v4l2_clk *clk;
u16 xskip;
u16 yskip;
unsigned int total_h;
@@ -391,36 +391,16 @@
return 0;
}
-static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t031 *mt9t031 = to_mt9t031(client);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = mt9t031->model;
- id->revision = 0;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int mt9t031_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+ if (reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
+ reg->size = 1;
reg->val = reg_read(client, reg->reg);
if (reg->val > 0xffff)
@@ -434,12 +414,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+ if (reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
if (reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
@@ -595,7 +572,7 @@
return 0;
}
-static struct dev_pm_ops mt9t031_dev_pm_ops = {
+static const struct dev_pm_ops mt9t031_dev_pm_ops = {
.runtime_suspend = mt9t031_runtime_suspend,
.runtime_resume = mt9t031_runtime_resume,
};
@@ -610,16 +587,17 @@
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
struct video_device *vdev = soc_camera_i2c_to_vdev(client);
+ struct mt9t031 *mt9t031 = to_mt9t031(client);
int ret;
if (on) {
- ret = soc_camera_power_on(&client->dev, ssdd);
+ ret = soc_camera_power_on(&client->dev, ssdd, mt9t031->clk);
if (ret < 0)
return ret;
vdev->dev.type = &mt9t031_dev_type;
} else {
vdev->dev.type = NULL;
- soc_camera_power_off(&client->dev, ssdd);
+ soc_camera_power_off(&client->dev, ssdd, mt9t031->clk);
}
return 0;
@@ -650,7 +628,6 @@
switch (data) {
case 0x1621:
- mt9t031->model = V4L2_IDENT_MT9T031;
break;
default:
dev_err(&client->dev,
@@ -685,7 +662,6 @@
};
static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
- .g_chip_ident = mt9t031_g_chip_ident,
.s_power = mt9t031_s_power,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = mt9t031_g_register,
@@ -812,9 +788,18 @@
mt9t031->xskip = 1;
mt9t031->yskip = 1;
+ mt9t031->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(mt9t031->clk)) {
+ ret = PTR_ERR(mt9t031->clk);
+ goto eclkget;
+ }
+
ret = mt9t031_video_probe(client);
- if (ret)
+ if (ret) {
+ v4l2_clk_put(mt9t031->clk);
+eclkget:
v4l2_ctrl_handler_free(&mt9t031->hdl);
+ }
return ret;
}
@@ -823,6 +808,7 @@
{
struct mt9t031 *mt9t031 = to_mt9t031(client);
+ v4l2_clk_put(mt9t031->clk);
v4l2_device_unregister_subdev(&mt9t031->subdev);
v4l2_ctrl_handler_free(&mt9t031->hdl);
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
index a7256b7..46f431a 100644
--- a/drivers/media/i2c/soc_camera/mt9t112.c
+++ b/drivers/media/i2c/soc_camera/mt9t112.c
@@ -27,7 +27,7 @@
#include <media/mt9t112.h>
#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>
/* you can check PLL/clock info */
@@ -90,8 +90,8 @@
struct mt9t112_camera_info *info;
struct i2c_client *client;
struct v4l2_rect frame;
+ struct v4l2_clk *clk;
const struct mt9t112_format *format;
- int model;
int num_formats;
u32 flags;
/* for flags */
@@ -738,17 +738,6 @@
/************************************************************************
v4l2_subdev_core_ops
************************************************************************/
-static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9t112_priv *priv = to_mt9t112(client);
-
- id->ident = priv->model;
- id->revision = 0;
-
- return 0;
-}
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int mt9t112_g_register(struct v4l2_subdev *sd,
@@ -781,12 +770,12 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct mt9t112_priv *priv = to_mt9t112(client);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
}
static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
- .g_chip_ident = mt9t112_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = mt9t112_g_register,
.s_register = mt9t112_s_register,
@@ -1061,12 +1050,10 @@
switch (chipid) {
case 0x2680:
devname = "mt9t111";
- priv->model = V4L2_IDENT_MT9T111;
priv->num_formats = 1;
break;
case 0x2682:
devname = "mt9t112";
- priv->model = V4L2_IDENT_MT9T112;
priv->num_formats = ARRAY_SIZE(mt9t112_cfmts);
break;
default:
@@ -1108,18 +1095,26 @@
v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
ret = mt9t112_camera_probe(client);
- if (ret)
- return ret;
/* Cannot fail: using the default supported pixel code */
- mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
+ if (!ret)
+ mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
+ else
+ v4l2_clk_put(priv->clk);
return ret;
}
static int mt9t112_remove(struct i2c_client *client)
{
+ struct mt9t112_priv *priv = to_mt9t112(client);
+
+ v4l2_clk_put(priv->clk);
return 0;
}
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index a295e59..f9f95f8 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -19,7 +19,7 @@
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h>
/*
@@ -133,6 +133,11 @@
.pixclk_fv_lv = MT9V024_PIXCLK_FV_LV,
};
+enum mt9v022_model {
+ MT9V022IX7ATM,
+ MT9V022IX7ATC,
+};
+
struct mt9v022 {
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
@@ -149,11 +154,12 @@
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *vblank;
struct v4l2_rect rect; /* Sensor window */
+ struct v4l2_clk *clk;
const struct mt9v022_datafmt *fmt;
const struct mt9v022_datafmt *fmts;
const struct mt9v02x_register *reg;
int num_fmts;
- int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
+ enum mt9v022_model model;
u16 chip_control;
u16 chip_version;
unsigned short y_skip_top; /* Lines to skip at the top */
@@ -406,12 +412,12 @@
switch (mf->code) {
case V4L2_MBUS_FMT_Y8_1X8:
case V4L2_MBUS_FMT_Y10_1X10:
- if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
+ if (mt9v022->model != MT9V022IX7ATM)
return -EINVAL;
break;
case V4L2_MBUS_FMT_SBGGR8_1X8:
case V4L2_MBUS_FMT_SBGGR10_1X10:
- if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
+ if (mt9v022->model != MT9V022IX7ATC)
return -EINVAL;
break;
default:
@@ -457,36 +463,15 @@
return 0;
}
-static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct mt9v022 *mt9v022 = to_mt9v022(client);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = mt9v022->model;
- id->revision = 0;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int mt9v022_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+ if (reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
reg->size = 2;
reg->val = reg_read(client, reg->reg);
@@ -501,12 +486,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+ if (reg->reg > 0xff)
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
if (reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
@@ -518,8 +500,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct mt9v022 *mt9v022 = to_mt9v022(client);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on);
}
static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -706,11 +689,11 @@
if (sensor_type && (!strcmp("colour", sensor_type) ||
!strcmp("color", sensor_type))) {
ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
- mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
+ mt9v022->model = MT9V022IX7ATC;
mt9v022->fmts = mt9v022_colour_fmts;
} else {
ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
- mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
+ mt9v022->model = MT9V022IX7ATM;
mt9v022->fmts = mt9v022_monochrome_fmts;
}
@@ -740,7 +723,7 @@
mt9v022->fmt = &mt9v022->fmts[0];
dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
- data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
+ data, mt9v022->model == MT9V022IX7ATM ?
"monochrome" : "colour");
ret = mt9v022_init(client);
@@ -768,7 +751,6 @@
};
static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
- .g_chip_ident = mt9v022_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = mt9v022_g_register,
.s_register = mt9v022_s_register,
@@ -957,9 +939,18 @@
mt9v022->rect.width = MT9V022_MAX_WIDTH;
mt9v022->rect.height = MT9V022_MAX_HEIGHT;
+ mt9v022->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(mt9v022->clk)) {
+ ret = PTR_ERR(mt9v022->clk);
+ goto eclkget;
+ }
+
ret = mt9v022_video_probe(client);
- if (ret)
+ if (ret) {
+ v4l2_clk_put(mt9v022->clk);
+eclkget:
v4l2_ctrl_handler_free(&mt9v022->hdl);
+ }
return ret;
}
@@ -969,6 +960,7 @@
struct mt9v022 *mt9v022 = to_mt9v022(client);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ v4l2_clk_put(mt9v022->clk);
v4l2_device_unregister_subdev(&mt9v022->subdev);
if (ssdd->free_bus)
ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c
index e316842..6c6b1c3 100644
--- a/drivers/media/i2c/soc_camera/ov2640.c
+++ b/drivers/media/i2c/soc_camera/ov2640.c
@@ -22,7 +22,7 @@
#include <linux/videodev2.h>
#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-ctrls.h>
@@ -303,8 +303,8 @@
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
enum v4l2_mbus_pixelcode cfmt_code;
+ struct v4l2_clk *clk;
const struct ov2640_win_size *win;
- int model;
};
/*
@@ -723,18 +723,6 @@
return -EINVAL;
}
-static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov2640_priv *priv = to_ov2640(client);
-
- id->ident = priv->model;
- id->revision = 0;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int ov2640_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@@ -772,8 +760,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct ov2640_priv *priv = to_ov2640(client);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
}
/* Select the nearest higher resolution for capture */
@@ -1009,7 +998,6 @@
switch (VERSION(pid, ver)) {
case PID_OV2640:
devname = "ov2640";
- priv->model = V4L2_IDENT_OV2640;
break;
default:
dev_err(&client->dev,
@@ -1034,7 +1022,6 @@
};
static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
- .g_chip_ident = ov2640_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ov2640_g_register,
.s_register = ov2640_s_register,
@@ -1113,11 +1100,20 @@
if (priv->hdl.error)
return priv->hdl.error;
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ goto eclkget;
+ }
+
ret = ov2640_video_probe(client);
- if (ret)
+ if (ret) {
+ v4l2_clk_put(priv->clk);
+eclkget:
v4l2_ctrl_handler_free(&priv->hdl);
- else
+ } else {
dev_info(&adapter->dev, "OV2640 Probed\n");
+ }
return ret;
}
@@ -1126,6 +1122,7 @@
{
struct ov2640_priv *priv = to_ov2640(client);
+ v4l2_clk_put(priv->clk);
v4l2_device_unregister_subdev(&priv->subdev);
v4l2_ctrl_handler_free(&priv->hdl);
return 0;
diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
index 9aa56de..0a5c5d4 100644
--- a/drivers/media/i2c/soc_camera/ov5642.c
+++ b/drivers/media/i2c/soc_camera/ov5642.c
@@ -24,7 +24,7 @@
#include <linux/v4l2-mediabus.h>
#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>
/* OV5642 registers */
@@ -610,6 +610,7 @@
struct v4l2_subdev subdev;
const struct ov5642_datafmt *fmt;
struct v4l2_rect crop_rect;
+ struct v4l2_clk *clk;
/* blanking information */
int total_width;
@@ -848,23 +849,6 @@
return 0;
}
-static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = V4L2_IDENT_OV5642;
- id->revision = 0;
-
- return 0;
-}
-
static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -935,12 +919,13 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct ov5642 *priv = to_ov5642(client);
int ret;
if (!on)
- return soc_camera_power_off(&client->dev, ssdd);
+ return soc_camera_power_off(&client->dev, ssdd, priv->clk);
- ret = soc_camera_power_on(&client->dev, ssdd);
+ ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
if (ret < 0)
return ret;
@@ -966,7 +951,6 @@
static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
.s_power = ov5642_s_power,
- .g_chip_ident = ov5642_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ov5642_get_register,
.s_register = ov5642_set_register,
@@ -1021,6 +1005,7 @@
{
struct ov5642 *priv;
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ int ret;
if (!ssdd) {
dev_err(&client->dev, "OV5642: missing platform data!\n");
@@ -1042,13 +1027,23 @@
priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
priv->total_height = BLANKING_MIN_HEIGHT;
- return ov5642_video_probe(client);
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+ ret = ov5642_video_probe(client);
+ if (ret < 0)
+ v4l2_clk_put(priv->clk);
+
+ return ret;
}
static int ov5642_remove(struct i2c_client *client)
{
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct ov5642 *priv = to_ov5642(client);
+ v4l2_clk_put(priv->clk);
if (ssdd->free_bus)
ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c
index 991202d..ab01598 100644
--- a/drivers/media/i2c/soc_camera/ov6650.c
+++ b/drivers/media/i2c/soc_camera/ov6650.c
@@ -32,7 +32,7 @@
#include <linux/module.h>
#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h>
/* Register definitions */
@@ -196,6 +196,7 @@
struct v4l2_ctrl *blue;
struct v4l2_ctrl *red;
};
+ struct v4l2_clk *clk;
bool half_scale; /* scale down output by 2 */
struct v4l2_rect rect; /* sensor cropping window */
unsigned long pclk_limit; /* from host */
@@ -390,16 +391,6 @@
return -EINVAL;
}
-/* Get chip identification */
-static int ov6650_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- id->ident = V4L2_IDENT_OV6650;
- id->revision = 0;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int ov6650_get_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@@ -436,8 +427,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct ov6650 *priv = to_ov6650(client);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
}
static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
@@ -879,7 +871,6 @@
};
static struct v4l2_subdev_core_ops ov6650_core_ops = {
- .g_chip_ident = ov6650_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ov6650_get_register,
.s_register = ov6650_set_register,
@@ -1025,9 +1016,18 @@
priv->code = V4L2_MBUS_FMT_YUYV8_2X8;
priv->colorspace = V4L2_COLORSPACE_JPEG;
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ goto eclkget;
+ }
+
ret = ov6650_video_probe(client);
- if (ret)
+ if (ret) {
+ v4l2_clk_put(priv->clk);
+eclkget:
v4l2_ctrl_handler_free(&priv->hdl);
+ }
return ret;
}
@@ -1036,6 +1036,7 @@
{
struct ov6650 *priv = to_ov6650(client);
+ v4l2_clk_put(priv->clk);
v4l2_device_unregister_subdev(&priv->subdev);
v4l2_ctrl_handler_free(&priv->hdl);
return 0;
diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c
index 713d62e..7f2b3c8 100644
--- a/drivers/media/i2c/soc_camera/ov772x.c
+++ b/drivers/media/i2c/soc_camera/ov772x.c
@@ -26,8 +26,8 @@
#include <media/ov772x.h>
#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-subdev.h>
/*
@@ -396,10 +396,10 @@
struct ov772x_priv {
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
+ struct v4l2_clk *clk;
struct ov772x_camera_info *info;
const struct ov772x_color_format *cfmt;
const struct ov772x_win_size *win;
- int model;
unsigned short flag_vflip:1;
unsigned short flag_hflip:1;
/* band_filter = COM8[5] ? 256 - BDBASE : 0 */
@@ -620,17 +620,6 @@
return -EINVAL;
}
-static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct ov772x_priv *priv = to_ov772x(sd);
-
- id->ident = priv->model;
- id->revision = 0;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int ov772x_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@@ -668,8 +657,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct ov772x_priv *priv = to_ov772x(sd);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
}
static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
@@ -965,11 +955,9 @@
switch (VERSION(pid, ver)) {
case OV7720:
devname = "ov7720";
- priv->model = V4L2_IDENT_OV7720;
break;
case OV7725:
devname = "ov7725";
- priv->model = V4L2_IDENT_OV7725;
break;
default:
dev_err(&client->dev,
@@ -997,7 +985,6 @@
};
static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
- .g_chip_ident = ov772x_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ov772x_g_register,
.s_register = ov772x_s_register,
@@ -1088,13 +1075,22 @@
if (priv->hdl.error)
return priv->hdl.error;
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ goto eclkget;
+ }
+
ret = ov772x_video_probe(priv);
if (ret < 0) {
+ v4l2_clk_put(priv->clk);
+eclkget:
v4l2_ctrl_handler_free(&priv->hdl);
} else {
priv->cfmt = &ov772x_cfmts[0];
priv->win = &ov772x_win_sizes[0];
}
+
return ret;
}
@@ -1102,6 +1098,7 @@
{
struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client));
+ v4l2_clk_put(priv->clk);
v4l2_device_unregister_subdev(&priv->subdev);
v4l2_ctrl_handler_free(&priv->hdl);
return 0;
diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c
index 20ca62d..e968c3f 100644
--- a/drivers/media/i2c/soc_camera/ov9640.c
+++ b/drivers/media/i2c/soc_camera/ov9640.c
@@ -28,7 +28,7 @@
#include <linux/videodev2.h>
#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
@@ -61,7 +61,7 @@
/* Configurations
* NOTE: for YUV, alter the following registers:
- * COM12 |= OV9640_COM12_YUV_AVG
+ * COM12 |= OV9640_COM12_YUV_AVG
*
* for RGB, alter the following registers:
* COM7 |= OV9640_COM7_RGB
@@ -287,18 +287,6 @@
return -EINVAL;
}
-/* Get chip identification */
-static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
- id->ident = priv->model;
- id->revision = priv->revision;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int ov9640_get_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@@ -337,8 +325,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct ov9640_priv *priv = to_ov9640_sensor(sd);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
}
/* select nearest higher resolution for capture */
@@ -615,12 +604,10 @@
switch (VERSION(pid, ver)) {
case OV9640_V2:
devname = "ov9640";
- priv->model = V4L2_IDENT_OV9640;
priv->revision = 2;
break;
case OV9640_V3:
devname = "ov9640";
- priv->model = V4L2_IDENT_OV9640;
priv->revision = 3;
break;
default:
@@ -644,7 +631,6 @@
};
static struct v4l2_subdev_core_ops ov9640_core_ops = {
- .g_chip_ident = ov9640_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ov9640_get_register,
.s_register = ov9640_set_register,
@@ -716,10 +702,18 @@
if (priv->hdl.error)
return priv->hdl.error;
- ret = ov9640_video_probe(client);
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ goto eclkget;
+ }
- if (ret)
+ ret = ov9640_video_probe(client);
+ if (ret) {
+ v4l2_clk_put(priv->clk);
+eclkget:
v4l2_ctrl_handler_free(&priv->hdl);
+ }
return ret;
}
@@ -729,6 +723,7 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct ov9640_priv *priv = to_ov9640_sensor(sd);
+ v4l2_clk_put(priv->clk);
v4l2_device_unregister_subdev(&priv->subdev);
v4l2_ctrl_handler_free(&priv->hdl);
return 0;
diff --git a/drivers/media/i2c/soc_camera/ov9640.h b/drivers/media/i2c/soc_camera/ov9640.h
index 6b33a97..65d13ff 100644
--- a/drivers/media/i2c/soc_camera/ov9640.h
+++ b/drivers/media/i2c/soc_camera/ov9640.h
@@ -199,6 +199,7 @@
struct ov9640_priv {
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
+ struct v4l2_clk *clk;
int model;
int revision;
diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
index 012bd62..ea76863 100644
--- a/drivers/media/i2c/soc_camera/ov9740.c
+++ b/drivers/media/i2c/soc_camera/ov9740.c
@@ -17,7 +17,7 @@
#include <linux/v4l2-mediabus.h>
#include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h>
#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev)
@@ -196,8 +196,8 @@
struct ov9740_priv {
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
+ struct v4l2_clk *clk;
- int ident;
u16 model;
u8 revision;
u8 manid;
@@ -772,18 +772,6 @@
return 0;
}
-/* Get chip identification */
-static int ov9740_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct ov9740_priv *priv = to_ov9740(sd);
-
- id->ident = priv->ident;
- id->revision = priv->revision;
-
- return 0;
-}
-
static int ov9740_s_power(struct v4l2_subdev *sd, int on)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -792,7 +780,7 @@
int ret;
if (on) {
- ret = soc_camera_power_on(&client->dev, ssdd);
+ ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
if (ret < 0)
return ret;
@@ -806,7 +794,7 @@
priv->current_enable = true;
}
- soc_camera_power_off(&client->dev, ssdd);
+ soc_camera_power_off(&client->dev, ssdd, priv->clk);
}
return 0;
@@ -887,8 +875,6 @@
goto done;
}
- priv->ident = V4L2_IDENT_OV9740;
-
dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, "
"Manufacturer 0x%02x, SMIA Version 0x%02x\n",
priv->model, priv->revision, priv->manid, priv->smiaver);
@@ -927,7 +913,6 @@
};
static struct v4l2_subdev_core_ops ov9740_core_ops = {
- .g_chip_ident = ov9740_g_chip_ident,
.s_power = ov9740_s_power,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ov9740_get_register,
@@ -975,9 +960,18 @@
if (priv->hdl.error)
return priv->hdl.error;
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk)) {
+ ret = PTR_ERR(priv->clk);
+ goto eclkget;
+ }
+
ret = ov9740_video_probe(client);
- if (ret < 0)
+ if (ret < 0) {
+ v4l2_clk_put(priv->clk);
+eclkget:
v4l2_ctrl_handler_free(&priv->hdl);
+ }
return ret;
}
@@ -986,6 +980,7 @@
{
struct ov9740_priv *priv = i2c_get_clientdata(client);
+ v4l2_clk_put(priv->clk);
v4l2_device_unregister_subdev(&priv->subdev);
v4l2_ctrl_handler_free(&priv->hdl);
return 0;
diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
index 1f9ec3b..7e6d978 100644
--- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c
+++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
@@ -17,8 +17,8 @@
#include <media/rj54n1cb0c.h>
#include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#define RJ54N1_DEV_CODE 0x0400
@@ -151,6 +151,7 @@
struct rj54n1 {
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
+ struct v4l2_clk *clk;
struct rj54n1_clock_div clk_div;
const struct rj54n1_datafmt *fmt;
struct v4l2_rect rect; /* Sensor window */
@@ -1120,37 +1121,16 @@
return 0;
}
-static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- if (id->match.addr != client->addr)
- return -ENODEV;
-
- id->ident = V4L2_IDENT_RJ54N1CB0C;
- id->revision = 0;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int rj54n1_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
- reg->reg < 0x400 || reg->reg > 0x1fff)
+ if (reg->reg < 0x400 || reg->reg > 0x1fff)
/* Registers > 0x0800 are only available from Sharp support */
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
reg->size = 1;
reg->val = reg_read(client, reg->reg);
@@ -1165,14 +1145,10 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
- reg->reg < 0x400 || reg->reg > 0x1fff)
+ if (reg->reg < 0x400 || reg->reg > 0x1fff)
/* Registers >= 0x0800 are only available from Sharp support */
return -EINVAL;
- if (reg->match.addr != client->addr)
- return -ENODEV;
-
if (reg_write(client, reg->reg, reg->val) < 0)
return -EIO;
@@ -1184,8 +1160,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct rj54n1 *rj54n1 = to_rj54n1(client);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, rj54n1->clk, on);
}
static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -1233,7 +1210,6 @@
};
static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
- .g_chip_ident = rj54n1_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = rj54n1_g_register,
.s_register = rj54n1_s_register,
@@ -1382,9 +1358,18 @@
rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
(clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
+ rj54n1->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(rj54n1->clk)) {
+ ret = PTR_ERR(rj54n1->clk);
+ goto eclkget;
+ }
+
ret = rj54n1_video_probe(client, rj54n1_priv);
- if (ret < 0)
+ if (ret < 0) {
+ v4l2_clk_put(rj54n1->clk);
+eclkget:
v4l2_ctrl_handler_free(&rj54n1->hdl);
+ }
return ret;
}
@@ -1394,6 +1379,7 @@
struct rj54n1 *rj54n1 = to_rj54n1(client);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ v4l2_clk_put(rj54n1->clk);
v4l2_device_unregister_subdev(&rj54n1->subdev);
if (ssdd->free_bus)
ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c
index bad90b1..ab54628 100644
--- a/drivers/media/i2c/soc_camera/tw9910.c
+++ b/drivers/media/i2c/soc_camera/tw9910.c
@@ -27,7 +27,7 @@
#include <media/soc_camera.h>
#include <media/tw9910.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>
#define GET_ID(val) ((val & 0xF8) >> 3)
@@ -228,6 +228,7 @@
struct tw9910_priv {
struct v4l2_subdev subdev;
+ struct v4l2_clk *clk;
struct tw9910_video_info *info;
const struct tw9910_scale_ctrl *scale;
v4l2_std_id norm;
@@ -518,18 +519,6 @@
return 0;
}
-static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *id)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tw9910_priv *priv = to_tw9910(client);
-
- id->ident = V4L2_IDENT_TW9910;
- id->revision = priv->revision;
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int tw9910_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@@ -540,6 +529,7 @@
if (reg->reg > 0xff)
return -EINVAL;
+ reg->size = 1;
ret = i2c_smbus_read_byte_data(client, reg->reg);
if (ret < 0)
return ret;
@@ -570,8 +560,9 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ struct tw9910_priv *priv = to_tw9910(client);
- return soc_camera_set_power(&client->dev, ssdd, on);
+ return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
}
static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
@@ -823,7 +814,6 @@
}
static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
- .g_chip_ident = tw9910_g_chip_ident,
.s_std = tw9910_s_std,
.g_std = tw9910_g_std,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -912,6 +902,7 @@
struct i2c_adapter *adapter =
to_i2c_adapter(client->dev.parent);
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ int ret;
if (!ssdd || !ssdd->drv_priv) {
dev_err(&client->dev, "TW9910: missing platform data!\n");
@@ -935,11 +926,21 @@
v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
- return tw9910_video_probe(client);
+ priv->clk = v4l2_clk_get(&client->dev, "mclk");
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+ ret = tw9910_video_probe(client);
+ if (ret < 0)
+ v4l2_clk_put(priv->clk);
+
+ return ret;
}
static int tw9910_remove(struct i2c_client *client)
{
+ struct tw9910_priv *priv = to_tw9910(client);
+ v4l2_clk_put(priv->clk);
return 0;
}
diff --git a/drivers/media/i2c/sony-btf-mpx.c b/drivers/media/i2c/sony-btf-mpx.c
index 38cbea9..32d8232 100644
--- a/drivers/media/i2c/sony-btf-mpx.c
+++ b/drivers/media/i2c/sony-btf-mpx.c
@@ -30,7 +30,7 @@
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on\n");
+MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on");
/* #define MPX_DEBUG */
@@ -355,7 +355,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- t = kzalloc(sizeof(struct sony_btf_mpx), GFP_KERNEL);
+ t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
if (t == NULL)
return -ENOMEM;
@@ -374,7 +374,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c
index e9d95bd..ae94326 100644
--- a/drivers/media/i2c/sr030pc30.c
+++ b/drivers/media/i2c/sr030pc30.c
@@ -23,6 +23,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
+#include <media/v4l2-ctrls.h>
#include <media/sr030pc30.h>
static int debug;
@@ -142,17 +143,24 @@
struct sr030pc30_info {
struct v4l2_subdev sd;
+ struct v4l2_ctrl_handler hdl;
const struct sr030pc30_platform_data *pdata;
const struct sr030pc30_format *curr_fmt;
const struct sr030pc30_frmsize *curr_win;
- unsigned int auto_wb:1;
- unsigned int auto_exp:1;
unsigned int hflip:1;
unsigned int vflip:1;
unsigned int sleep:1;
- unsigned int exposure;
- u8 blue_balance;
- u8 red_balance;
+ struct {
+ /* auto whitebalance control cluster */
+ struct v4l2_ctrl *awb;
+ struct v4l2_ctrl *red;
+ struct v4l2_ctrl *blue;
+ };
+ struct {
+ /* auto exposure control cluster */
+ struct v4l2_ctrl *autoexp;
+ struct v4l2_ctrl *exp;
+ };
u8 i2c_reg_page;
};
@@ -173,52 +181,6 @@
u16 val;
};
-static const struct v4l2_queryctrl sr030pc30_ctrl[] = {
- {
- .id = V4L2_CID_AUTO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Auto White Balance",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- }, {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 64,
- .flags = 0,
- }, {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 64,
- }, {
- .id = V4L2_CID_EXPOSURE_AUTO,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Auto Exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1,
- }, {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = EXPOS_MIN_MS,
- .maximum = EXPOS_MAX_MS,
- .step = 1,
- .default_value = 1,
- }, {
- }
-};
-
/* supported resolutions */
static const struct sr030pc30_frmsize sr030pc30_sizes[] = {
{
@@ -394,48 +356,6 @@
return ret;
}
-static inline int sr030pc30_enable_autoexposure(struct v4l2_subdev *sd, int on)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
- /* auto anti-flicker is also enabled here */
- int ret = cam_i2c_write(sd, AE_CTL1_REG, on ? 0xDC : 0x0C);
- if (!ret)
- info->auto_exp = on;
- return ret;
-}
-
-static int sr030pc30_set_exposure(struct v4l2_subdev *sd, int value)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- unsigned long expos = value * info->pdata->clk_rate / (8 * 1000);
-
- int ret = cam_i2c_write(sd, EXP_TIMEH_REG, expos >> 16 & 0xFF);
- if (!ret)
- ret = cam_i2c_write(sd, EXP_TIMEM_REG, expos >> 8 & 0xFF);
- if (!ret)
- ret = cam_i2c_write(sd, EXP_TIMEL_REG, expos & 0xFF);
- if (!ret) { /* Turn off AE */
- info->exposure = value;
- ret = sr030pc30_enable_autoexposure(sd, 0);
- }
- return ret;
-}
-
-/* Automatic white balance control */
-static int sr030pc30_enable_autowhitebalance(struct v4l2_subdev *sd, int on)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- int ret = cam_i2c_write(sd, AWB_CTL2_REG, on ? 0x2E : 0x2F);
- if (!ret)
- ret = cam_i2c_write(sd, AWB_CTL1_REG, on ? 0xFB : 0x7B);
- if (!ret)
- info->auto_wb = on;
-
- return ret;
-}
-
static int sr030pc30_set_flip(struct v4l2_subdev *sd)
{
struct sr030pc30_info *info = to_sr030pc30(sd);
@@ -498,107 +418,56 @@
return -EINVAL;
}
-static int sr030pc30_queryctrl(struct v4l2_subdev *sd,
- struct v4l2_queryctrl *qc)
+static int sr030pc30_s_ctrl(struct v4l2_ctrl *ctrl)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++)
- if (qc->id == sr030pc30_ctrl[i].id) {
- *qc = sr030pc30_ctrl[i];
- v4l2_dbg(1, debug, sd, "%s id: %d\n",
- __func__, qc->id);
- return 0;
- }
-
- return -EINVAL;
-}
-
-static inline int sr030pc30_set_bluebalance(struct v4l2_subdev *sd, int value)
-{
- int ret = cam_i2c_write(sd, MWB_BGAIN_REG, value);
- if (!ret)
- to_sr030pc30(sd)->blue_balance = value;
- return ret;
-}
-
-static inline int sr030pc30_set_redbalance(struct v4l2_subdev *sd, int value)
-{
- int ret = cam_i2c_write(sd, MWB_RGAIN_REG, value);
- if (!ret)
- to_sr030pc30(sd)->red_balance = value;
- return ret;
-}
-
-static int sr030pc30_s_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- int i, ret = 0;
-
- for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++)
- if (ctrl->id == sr030pc30_ctrl[i].id)
- break;
-
- if (i == ARRAY_SIZE(sr030pc30_ctrl))
- return -EINVAL;
-
- if (ctrl->value < sr030pc30_ctrl[i].minimum ||
- ctrl->value > sr030pc30_ctrl[i].maximum)
- return -ERANGE;
+ struct sr030pc30_info *info =
+ container_of(ctrl->handler, struct sr030pc30_info, hdl);
+ struct v4l2_subdev *sd = &info->sd;
+ int ret = 0;
v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n",
- __func__, ctrl->id, ctrl->value);
+ __func__, ctrl->id, ctrl->val);
switch (ctrl->id) {
case V4L2_CID_AUTO_WHITE_BALANCE:
- sr030pc30_enable_autowhitebalance(sd, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- ret = sr030pc30_set_bluebalance(sd, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- ret = sr030pc30_set_redbalance(sd, ctrl->value);
- break;
+ if (ctrl->is_new) {
+ ret = cam_i2c_write(sd, AWB_CTL2_REG,
+ ctrl->val ? 0x2E : 0x2F);
+ if (!ret)
+ ret = cam_i2c_write(sd, AWB_CTL1_REG,
+ ctrl->val ? 0xFB : 0x7B);
+ }
+ if (!ret && info->blue->is_new)
+ ret = cam_i2c_write(sd, MWB_BGAIN_REG, info->blue->val);
+ if (!ret && info->red->is_new)
+ ret = cam_i2c_write(sd, MWB_RGAIN_REG, info->red->val);
+ return ret;
+
case V4L2_CID_EXPOSURE_AUTO:
- sr030pc30_enable_autoexposure(sd,
- ctrl->value == V4L2_EXPOSURE_AUTO);
- break;
- case V4L2_CID_EXPOSURE:
- ret = sr030pc30_set_exposure(sd, ctrl->value);
- break;
+ /* auto anti-flicker is also enabled here */
+ if (ctrl->is_new)
+ ret = cam_i2c_write(sd, AE_CTL1_REG,
+ ctrl->val == V4L2_EXPOSURE_AUTO ? 0xDC : 0x0C);
+ if (info->exp->is_new) {
+ unsigned long expos = info->exp->val;
+
+ expos = expos * info->pdata->clk_rate / (8 * 1000);
+
+ if (!ret)
+ ret = cam_i2c_write(sd, EXP_TIMEH_REG,
+ expos >> 16 & 0xFF);
+ if (!ret)
+ ret = cam_i2c_write(sd, EXP_TIMEM_REG,
+ expos >> 8 & 0xFF);
+ if (!ret)
+ ret = cam_i2c_write(sd, EXP_TIMEL_REG,
+ expos & 0xFF);
+ }
+ return ret;
default:
return -EINVAL;
}
- return ret;
-}
-
-static int sr030pc30_g_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct sr030pc30_info *info = to_sr030pc30(sd);
-
- v4l2_dbg(1, debug, sd, "%s: id: %d\n", __func__, ctrl->id);
-
- switch (ctrl->id) {
- case V4L2_CID_AUTO_WHITE_BALANCE:
- ctrl->value = info->auto_wb;
- break;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = info->blue_balance;
- break;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = info->red_balance;
- break;
- case V4L2_CID_EXPOSURE_AUTO:
- ctrl->value = info->auto_exp;
- break;
- case V4L2_CID_EXPOSURE:
- ctrl->value = info->exposure;
- break;
- default:
- return -EINVAL;
- }
return 0;
}
@@ -752,11 +621,19 @@
return ret;
}
+static const struct v4l2_ctrl_ops sr030pc30_ctrl_ops = {
+ .s_ctrl = sr030pc30_s_ctrl,
+};
+
static const struct v4l2_subdev_core_ops sr030pc30_core_ops = {
.s_power = sr030pc30_s_power,
- .queryctrl = sr030pc30_queryctrl,
- .s_ctrl = sr030pc30_s_ctrl,
- .g_ctrl = sr030pc30_g_ctrl,
+ .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+ .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+ .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+ .g_ctrl = v4l2_subdev_g_ctrl,
+ .s_ctrl = v4l2_subdev_s_ctrl,
+ .queryctrl = v4l2_subdev_queryctrl,
+ .querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_video_ops sr030pc30_video_ops = {
@@ -807,6 +684,7 @@
{
struct sr030pc30_info *info;
struct v4l2_subdev *sd;
+ struct v4l2_ctrl_handler *hdl;
const struct sr030pc30_platform_data *pdata
= client->dev.platform_data;
int ret;
@@ -820,7 +698,7 @@
if (ret)
return ret;
- info = kzalloc(sizeof(*info), GFP_KERNEL);
+ info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
@@ -830,10 +708,31 @@
v4l2_i2c_subdev_init(sd, client, &sr030pc30_ops);
+ hdl = &info->hdl;
+ v4l2_ctrl_handler_init(hdl, 6);
+ info->awb = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+ V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+ info->red = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+ V4L2_CID_RED_BALANCE, 0, 127, 1, 64);
+ info->blue = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+ V4L2_CID_BLUE_BALANCE, 0, 127, 1, 64);
+ info->autoexp = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+ V4L2_CID_EXPOSURE_AUTO, 0, 1, 1, 1);
+ info->exp = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+ V4L2_CID_EXPOSURE, EXPOS_MIN_MS, EXPOS_MAX_MS, 1, 30);
+ sd->ctrl_handler = hdl;
+ if (hdl->error) {
+ int err = hdl->error;
+
+ v4l2_ctrl_handler_free(hdl);
+ return err;
+ }
+ v4l2_ctrl_auto_cluster(3, &info->awb, 0, false);
+ v4l2_ctrl_auto_cluster(2, &info->autoexp, V4L2_EXPOSURE_MANUAL, false);
+ v4l2_ctrl_handler_setup(hdl);
+
info->i2c_reg_page = -1;
info->hflip = 1;
- info->auto_exp = 1;
- info->exposure = 30;
return 0;
}
@@ -841,10 +740,9 @@
static int sr030pc30_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct sr030pc30_info *info = to_sr030pc30(sd);
v4l2_device_unregister_subdev(sd);
- kfree(info);
+ v4l2_ctrl_handler_free(sd->ctrl_handler);
return 0;
}
diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c
index 28b5121..72af644 100644
--- a/drivers/media/i2c/tda7432.c
+++ b/drivers/media/i2c/tda7432.c
@@ -359,7 +359,7 @@
v4l_info(client, "chip found @ 0x%02x (%s)\n",
client->addr << 1, client->adapter->name);
- t = kzalloc(sizeof(*t), GFP_KERNEL);
+ t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
if (!t)
return -ENOMEM;
sd = &t->sd;
@@ -380,7 +380,6 @@
int err = t->hdl.error;
v4l2_ctrl_handler_free(&t->hdl);
- kfree(t);
return err;
}
v4l2_ctrl_cluster(2, &t->bass);
@@ -406,7 +405,6 @@
tda7432_set(sd);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&t->hdl);
- kfree(t);
return 0;
}
diff --git a/drivers/media/i2c/tda9840.c b/drivers/media/i2c/tda9840.c
index 01441e3..fbdff8b 100644
--- a/drivers/media/i2c/tda9840.c
+++ b/drivers/media/i2c/tda9840.c
@@ -31,7 +31,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("tda9840 driver");
@@ -145,26 +144,14 @@
return 0;
}
-static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0);
-}
-
/* ----------------------------------------------------------------------- */
-static const struct v4l2_subdev_core_ops tda9840_core_ops = {
- .g_chip_ident = tda9840_g_chip_ident,
-};
-
static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
.s_tuner = tda9840_s_tuner,
.g_tuner = tda9840_g_tuner,
};
static const struct v4l2_subdev_ops tda9840_ops = {
- .core = &tda9840_core_ops,
.tuner = &tda9840_tuner_ops,
};
@@ -184,7 +171,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
if (sd == NULL)
return -ENOMEM;
v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
@@ -201,7 +188,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(sd);
return 0;
}
diff --git a/drivers/media/i2c/tea6415c.c b/drivers/media/i2c/tea6415c.c
index 3d5b06a..bbe1a99 100644
--- a/drivers/media/i2c/tea6415c.c
+++ b/drivers/media/i2c/tea6415c.c
@@ -33,7 +33,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include "tea6415c.h"
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -119,25 +118,13 @@
return ret;
}
-static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0);
-}
-
/* ----------------------------------------------------------------------- */
-static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
- .g_chip_ident = tea6415c_g_chip_ident,
-};
-
static const struct v4l2_subdev_video_ops tea6415c_video_ops = {
.s_routing = tea6415c_s_routing,
};
static const struct v4l2_subdev_ops tea6415c_ops = {
- .core = &tea6415c_core_ops,
.video = &tea6415c_video_ops,
};
@@ -152,7 +139,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
if (sd == NULL)
return -ENOMEM;
v4l2_i2c_subdev_init(sd, client, &tea6415c_ops);
@@ -164,7 +151,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(sd);
return 0;
}
diff --git a/drivers/media/i2c/tea6420.c b/drivers/media/i2c/tea6420.c
index 3875721..30a8d75 100644
--- a/drivers/media/i2c/tea6420.c
+++ b/drivers/media/i2c/tea6420.c
@@ -33,7 +33,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include "tea6420.h"
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -90,25 +89,13 @@
return 0;
}
-static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
-}
-
/* ----------------------------------------------------------------------- */
-static const struct v4l2_subdev_core_ops tea6420_core_ops = {
- .g_chip_ident = tea6420_g_chip_ident,
-};
-
static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
.s_routing = tea6420_s_routing,
};
static const struct v4l2_subdev_ops tea6420_ops = {
- .core = &tea6420_core_ops,
.audio = &tea6420_audio_ops,
};
@@ -125,7 +112,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
if (sd == NULL)
return -ENOMEM;
v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
@@ -146,7 +133,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(sd);
return 0;
}
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c
index c433955..0a2dacb 100644
--- a/drivers/media/i2c/ths7303.c
+++ b/drivers/media/i2c/ths7303.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <media/ths7303.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-device.h>
#define THS7303_CHANNEL_1 1
@@ -35,11 +34,10 @@
struct ths7303_state {
struct v4l2_subdev sd;
- struct ths7303_platform_data pdata;
+ const struct ths7303_platform_data *pdata;
struct v4l2_bt_timings bt;
int std_id;
int stream_on;
- int driver_data;
};
enum ths7303_filter_mode {
@@ -89,7 +87,7 @@
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ths7303_state *state = to_state(sd);
- struct ths7303_platform_data *pdata = &state->pdata;
+ const struct ths7303_platform_data *pdata = state->pdata;
u8 val, sel = 0;
int err, disable = 0;
@@ -212,15 +210,6 @@
return ths7303_config(sd);
}
-static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ths7303_state *state = to_state(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, state->driver_data, 0);
-}
-
static const struct v4l2_subdev_video_ops ths7303_video_ops = {
.s_stream = ths7303_s_stream,
.s_std_output = ths7303_s_std_output,
@@ -232,13 +221,6 @@
static int ths7303_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
reg->size = 1;
reg->val = ths7303_read(sd, reg->reg);
return 0;
@@ -247,13 +229,6 @@
static int ths7303_s_register(struct v4l2_subdev *sd,
const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
ths7303_write(sd, reg->reg, reg->val);
return 0;
}
@@ -340,7 +315,6 @@
}
static const struct v4l2_subdev_core_ops ths7303_core_ops = {
- .g_chip_ident = ths7303_g_chip_ident,
.log_status = ths7303_log_status,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = ths7303_g_register,
@@ -353,32 +327,6 @@
.video = &ths7303_video_ops,
};
-static int ths7303_setup(struct v4l2_subdev *sd)
-{
- struct ths7303_state *state = to_state(sd);
- struct ths7303_platform_data *pdata = &state->pdata;
- int ret;
- u8 mask;
-
- state->stream_on = pdata->init_enable;
-
- mask = state->stream_on ? 0xff : 0xf8;
-
- ret = ths7303_write(sd, THS7303_CHANNEL_1, pdata->ch_1 & mask);
- if (ret)
- return ret;
-
- ret = ths7303_write(sd, THS7303_CHANNEL_2, pdata->ch_2 & mask);
- if (ret)
- return ret;
-
- ret = ths7303_write(sd, THS7303_CHANNEL_3, pdata->ch_3 & mask);
- if (ret)
- return ret;
-
- return 0;
-}
-
static int ths7303_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -386,6 +334,11 @@
struct ths7303_state *state;
struct v4l2_subdev *sd;
+ if (pdata == NULL) {
+ dev_err(&client->dev, "No platform data\n");
+ return -EINVAL;
+ }
+
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
@@ -397,20 +350,14 @@
if (!state)
return -ENOMEM;
- if (!pdata)
- v4l_warn(client, "No platform data, using default data!\n");
- else
- state->pdata = *pdata;
-
+ state->pdata = pdata;
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
- /* store the driver data to differntiate the chip */
- state->driver_data = (int)id->driver_data;
-
- if (ths7303_setup(sd) < 0) {
- v4l_err(client, "init failed\n");
- return -EIO;
+ /* set to default 480I_576I filter mode */
+ if (ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I) < 0) {
+ v4l_err(client, "Setting to 480I_576I filter mode failed!\n");
+ return -EINVAL;
}
return 0;
@@ -426,8 +373,8 @@
}
static const struct i2c_device_id ths7303_id[] = {
- {"ths7303", V4L2_IDENT_THS7303},
- {"ths7353", V4L2_IDENT_THS7353},
+ {"ths7303", 0},
+ {"ths7353", 0},
{},
};
diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c
new file mode 100644
index 0000000..a24f90c
--- /dev/null
+++ b/drivers/media/i2c/ths8200.c
@@ -0,0 +1,556 @@
+/*
+ * ths8200 - Texas Instruments THS8200 video encoder driver
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/v4l2-dv-timings.h>
+
+#include <media/v4l2-device.h>
+
+#include "ths8200_regs.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+MODULE_DESCRIPTION("Texas Instruments THS8200 video encoder driver");
+MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
+MODULE_AUTHOR("Martin Bugge <martin.bugge@cisco.com>");
+MODULE_LICENSE("GPL v2");
+
+struct ths8200_state {
+ struct v4l2_subdev sd;
+ uint8_t chip_version;
+ /* Is the ths8200 powered on? */
+ bool power_on;
+ struct v4l2_dv_timings dv_timings;
+};
+
+static const struct v4l2_dv_timings ths8200_timings[] = {
+ V4L2_DV_BT_CEA_720X480P59_94,
+ V4L2_DV_BT_CEA_1280X720P24,
+ V4L2_DV_BT_CEA_1280X720P25,
+ V4L2_DV_BT_CEA_1280X720P30,
+ V4L2_DV_BT_CEA_1280X720P50,
+ V4L2_DV_BT_CEA_1280X720P60,
+ V4L2_DV_BT_CEA_1920X1080P24,
+ V4L2_DV_BT_CEA_1920X1080P25,
+ V4L2_DV_BT_CEA_1920X1080P30,
+ V4L2_DV_BT_CEA_1920X1080P50,
+ V4L2_DV_BT_CEA_1920X1080P60,
+};
+
+static inline struct ths8200_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct ths8200_state, sd);
+}
+
+static inline unsigned hblanking(const struct v4l2_bt_timings *t)
+{
+ return t->hfrontporch + t->hsync + t->hbackporch;
+}
+
+static inline unsigned htotal(const struct v4l2_bt_timings *t)
+{
+ return t->width + t->hfrontporch + t->hsync + t->hbackporch;
+}
+
+static inline unsigned vblanking(const struct v4l2_bt_timings *t)
+{
+ return t->vfrontporch + t->vsync + t->vbackporch;
+}
+
+static inline unsigned vtotal(const struct v4l2_bt_timings *t)
+{
+ return t->height + t->vfrontporch + t->vsync + t->vbackporch;
+}
+
+static int ths8200_read(struct v4l2_subdev *sd, u8 reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int ths8200_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret == 0)
+ return 0;
+ }
+ v4l2_err(sd, "I2C Write Problem\n");
+ return ret;
+}
+
+/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
+ * and then the value-mask (to be OR-ed).
+ */
+static inline void
+ths8200_write_and_or(struct v4l2_subdev *sd, u8 reg,
+ uint8_t clr_mask, uint8_t val_mask)
+{
+ ths8200_write(sd, reg, (ths8200_read(sd, reg) & clr_mask) | val_mask);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+static int ths8200_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ reg->val = ths8200_read(sd, reg->reg & 0xff);
+ reg->size = 1;
+
+ return 0;
+}
+
+static int ths8200_s_register(struct v4l2_subdev *sd,
+ const struct v4l2_dbg_register *reg)
+{
+ ths8200_write(sd, reg->reg & 0xff, reg->val & 0xff);
+
+ return 0;
+}
+#endif
+
+static void ths8200_print_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings,
+ const char *txt, bool detailed)
+{
+ struct v4l2_bt_timings *bt = &timings->bt;
+ u32 htot, vtot;
+
+ if (timings->type != V4L2_DV_BT_656_1120)
+ return;
+
+ htot = htotal(bt);
+ vtot = vtotal(bt);
+
+ v4l2_info(sd, "%s %dx%d%s%d (%dx%d)",
+ txt, bt->width, bt->height, bt->interlaced ? "i" : "p",
+ (htot * vtot) > 0 ? ((u32)bt->pixelclock / (htot * vtot)) : 0,
+ htot, vtot);
+
+ if (detailed) {
+ v4l2_info(sd, " horizontal: fp = %d, %ssync = %d, bp = %d\n",
+ bt->hfrontporch,
+ (bt->polarities & V4L2_DV_HSYNC_POS_POL) ? "+" : "-",
+ bt->hsync, bt->hbackporch);
+ v4l2_info(sd, " vertical: fp = %d, %ssync = %d, bp = %d\n",
+ bt->vfrontporch,
+ (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-",
+ bt->vsync, bt->vbackporch);
+ v4l2_info(sd,
+ " pixelclock: %lld, flags: 0x%x, standards: 0x%x\n",
+ bt->pixelclock, bt->flags, bt->standards);
+ }
+}
+
+static int ths8200_log_status(struct v4l2_subdev *sd)
+{
+ struct ths8200_state *state = to_state(sd);
+ uint8_t reg_03 = ths8200_read(sd, THS8200_CHIP_CTL);
+
+ v4l2_info(sd, "----- Chip status -----\n");
+ v4l2_info(sd, "version: %u\n", state->chip_version);
+ v4l2_info(sd, "power: %s\n", (reg_03 & 0x0c) ? "off" : "on");
+ v4l2_info(sd, "reset: %s\n", (reg_03 & 0x01) ? "off" : "on");
+ v4l2_info(sd, "test pattern: %s\n",
+ (reg_03 & 0x20) ? "enabled" : "disabled");
+ v4l2_info(sd, "format: %ux%u\n",
+ ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_MSB) * 256 +
+ ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_LSB),
+ (ths8200_read(sd, THS8200_DTG2_LINE_CNT_MSB) & 0x07) * 256 +
+ ths8200_read(sd, THS8200_DTG2_LINE_CNT_LSB));
+ ths8200_print_timings(sd, &state->dv_timings,
+ "Configured format:", true);
+
+ return 0;
+}
+
+/* Power up/down ths8200 */
+static int ths8200_s_power(struct v4l2_subdev *sd, int on)
+{
+ struct ths8200_state *state = to_state(sd);
+
+ v4l2_dbg(1, debug, sd, "%s: power %s\n", __func__, on ? "on" : "off");
+
+ state->power_on = on;
+
+ /* Power up/down - leave in reset state until input video is present */
+ ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0xf2, (on ? 0x00 : 0x0c));
+
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops ths8200_core_ops = {
+ .log_status = ths8200_log_status,
+ .s_power = ths8200_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ths8200_g_register,
+ .s_register = ths8200_s_register,
+#endif
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev video operations
+ */
+
+static int ths8200_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct ths8200_state *state = to_state(sd);
+
+ if (enable && !state->power_on)
+ ths8200_s_power(sd, true);
+
+ ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0xfe,
+ (enable ? 0x01 : 0x00));
+
+ v4l2_dbg(1, debug, sd, "%s: %sable\n",
+ __func__, (enable ? "en" : "dis"));
+
+ return 0;
+}
+
+static void ths8200_core_init(struct v4l2_subdev *sd)
+{
+ /* setup clocks */
+ ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0x3f, 0xc0);
+
+ /**** Data path control (DATA) ****/
+ /* Set FSADJ 700 mV,
+ * bypass 422-444 interpolation,
+ * input format 30 bit RGB444
+ */
+ ths8200_write(sd, THS8200_DATA_CNTL, 0x70);
+
+ /* DTG Mode (Video blocked during blanking
+ * VESA slave
+ */
+ ths8200_write(sd, THS8200_DTG1_MODE, 0x87);
+
+ /**** Display Timing Generator Control, Part 1 (DTG1). ****/
+
+ /* Disable embedded syncs on the output by setting
+ * the amplitude to zero for all channels.
+ */
+ ths8200_write(sd, THS8200_DTG1_Y_SYNC_MSB, 0x2a);
+ ths8200_write(sd, THS8200_DTG1_CBCR_SYNC_MSB, 0x2a);
+}
+
+static void ths8200_setup(struct v4l2_subdev *sd, struct v4l2_bt_timings *bt)
+{
+ uint8_t polarity = 0;
+ uint16_t line_start_active_video = (bt->vsync + bt->vbackporch);
+ uint16_t line_start_front_porch = (vtotal(bt) - bt->vfrontporch);
+
+ /*** System ****/
+ /* Set chip in reset while it is configured */
+ ths8200_s_stream(sd, false);
+
+ /* configure video output timings */
+ ths8200_write(sd, THS8200_DTG1_SPEC_A, bt->hsync);
+ ths8200_write(sd, THS8200_DTG1_SPEC_B, bt->hfrontporch);
+
+ /* Zero for progressive scan formats.*/
+ if (!bt->interlaced)
+ ths8200_write(sd, THS8200_DTG1_SPEC_C, 0x00);
+
+ /* Distance from leading edge of h sync to start of active video.
+ * MSB in 0x2b
+ */
+ ths8200_write(sd, THS8200_DTG1_SPEC_D_LSB,
+ (bt->hbackporch + bt->hsync) & 0xff);
+ /* Zero for SDTV-mode. MSB in 0x2b */
+ ths8200_write(sd, THS8200_DTG1_SPEC_E_LSB, 0x00);
+ /*
+ * MSB for dtg1_spec(d/e/h). See comment for
+ * corresponding LSB registers.
+ */
+ ths8200_write(sd, THS8200_DTG1_SPEC_DEH_MSB,
+ ((bt->hbackporch + bt->hsync) & 0x100) >> 1);
+
+ /* h front porch */
+ ths8200_write(sd, THS8200_DTG1_SPEC_K_LSB, (bt->hfrontporch) & 0xff);
+ ths8200_write(sd, THS8200_DTG1_SPEC_K_MSB,
+ ((bt->hfrontporch) & 0x700) >> 8);
+
+ /* Half the line length. Used to calculate SDTV line types. */
+ ths8200_write(sd, THS8200_DTG1_SPEC_G_LSB, (htotal(bt)/2) & 0xff);
+ ths8200_write(sd, THS8200_DTG1_SPEC_G_MSB,
+ ((htotal(bt)/2) >> 8) & 0x0f);
+
+ /* Total pixels per line (ex. 720p: 1650) */
+ ths8200_write(sd, THS8200_DTG1_TOT_PIXELS_MSB, htotal(bt) >> 8);
+ ths8200_write(sd, THS8200_DTG1_TOT_PIXELS_LSB, htotal(bt) & 0xff);
+
+ /* Frame height and field height */
+ /* Field height should be programmed higher than frame_size for
+ * progressive scan formats
+ */
+ ths8200_write(sd, THS8200_DTG1_FRAME_FIELD_SZ_MSB,
+ ((vtotal(bt) >> 4) & 0xf0) + 0x7);
+ ths8200_write(sd, THS8200_DTG1_FRAME_SZ_LSB, vtotal(bt) & 0xff);
+
+ /* Should be programmed higher than frame_size
+ * for progressive formats
+ */
+ if (!bt->interlaced)
+ ths8200_write(sd, THS8200_DTG1_FIELD_SZ_LSB, 0xff);
+
+ /**** Display Timing Generator Control, Part 2 (DTG2). ****/
+ /* Set breakpoint line numbers and types
+ * THS8200 generates line types with different properties. A line type
+ * that sets all the RGB-outputs to zero is used in the blanking areas,
+ * while a line type that enable the RGB-outputs is used in active video
+ * area. The line numbers for start of active video, start of front
+ * porch and after the last line in the frame must be set with the
+ * corresponding line types.
+ *
+ * Line types:
+ * 0x9 - Full normal sync pulse: Blocks data when dtg1_pass is off.
+ * Used in blanking area.
+ * 0x0 - Active video: Video data is always passed. Used in active
+ * video area.
+ */
+ ths8200_write_and_or(sd, THS8200_DTG2_BP1_2_MSB, 0x88,
+ ((line_start_active_video >> 4) & 0x70) +
+ ((line_start_front_porch >> 8) & 0x07));
+ ths8200_write(sd, THS8200_DTG2_BP3_4_MSB, ((vtotal(bt)) >> 4) & 0x70);
+ ths8200_write(sd, THS8200_DTG2_BP1_LSB, line_start_active_video & 0xff);
+ ths8200_write(sd, THS8200_DTG2_BP2_LSB, line_start_front_porch & 0xff);
+ ths8200_write(sd, THS8200_DTG2_BP3_LSB, (vtotal(bt)) & 0xff);
+
+ /* line types */
+ ths8200_write(sd, THS8200_DTG2_LINETYPE1, 0x90);
+ ths8200_write(sd, THS8200_DTG2_LINETYPE2, 0x90);
+
+ /* h sync width transmitted */
+ ths8200_write(sd, THS8200_DTG2_HLENGTH_LSB, bt->hsync & 0xff);
+ ths8200_write_and_or(sd, THS8200_DTG2_HLENGTH_LSB_HDLY_MSB, 0x3f,
+ (bt->hsync >> 2) & 0xc0);
+
+ /* The pixel value h sync is asserted on */
+ ths8200_write_and_or(sd, THS8200_DTG2_HLENGTH_LSB_HDLY_MSB, 0xe0,
+ (htotal(bt) >> 8) & 0x1f);
+ ths8200_write(sd, THS8200_DTG2_HLENGTH_HDLY_LSB, htotal(bt));
+
+ /* v sync width transmitted */
+ ths8200_write(sd, THS8200_DTG2_VLENGTH1_LSB, (bt->vsync) & 0xff);
+ ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0x3f,
+ ((bt->vsync) >> 2) & 0xc0);
+
+ /* The pixel value v sync is asserted on */
+ ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0xf8,
+ (vtotal(bt)>>8) & 0x7);
+ ths8200_write(sd, THS8200_DTG2_VDLY1_LSB, vtotal(bt));
+
+ /* For progressive video vlength2 must be set to all 0 and vdly2 must
+ * be set to all 1.
+ */
+ ths8200_write(sd, THS8200_DTG2_VLENGTH2_LSB, 0x00);
+ ths8200_write(sd, THS8200_DTG2_VLENGTH2_MSB_VDLY2_MSB, 0x07);
+ ths8200_write(sd, THS8200_DTG2_VDLY2_LSB, 0xff);
+
+ /* Internal delay factors to synchronize the sync pulses and the data */
+ /* Experimental values delays (hor 4, ver 1) */
+ ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_MSB, (htotal(bt)>>8) & 0x1f);
+ ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_LSB, (htotal(bt) - 4) & 0xff);
+ ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_MSB, 0);
+ ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_LSB, 1);
+
+ /* Polarity of received and transmitted sync signals */
+ if (bt->polarities & V4L2_DV_HSYNC_POS_POL) {
+ polarity |= 0x01; /* HS_IN */
+ polarity |= 0x08; /* HS_OUT */
+ }
+ if (bt->polarities & V4L2_DV_VSYNC_POS_POL) {
+ polarity |= 0x02; /* VS_IN */
+ polarity |= 0x10; /* VS_OUT */
+ }
+
+ /* RGB mode, no embedded timings */
+ /* Timing of video input bus is derived from HS, VS, and FID dedicated
+ * inputs
+ */
+ ths8200_write(sd, THS8200_DTG2_CNTL, 0x47 | polarity);
+
+ /* leave reset */
+ ths8200_s_stream(sd, true);
+
+ v4l2_dbg(1, debug, sd, "%s: frame %dx%d, polarity %d\n"
+ "horizontal: front porch %d, back porch %d, sync %d\n"
+ "vertical: sync %d\n", __func__, htotal(bt), vtotal(bt),
+ polarity, bt->hfrontporch, bt->hbackporch,
+ bt->hsync, bt->vsync);
+}
+
+static int ths8200_s_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
+{
+ struct ths8200_state *state = to_state(sd);
+ int i;
+
+ v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+ if (timings->type != V4L2_DV_BT_656_1120)
+ return -EINVAL;
+
+ /* TODO Support interlaced formats */
+ if (timings->bt.interlaced) {
+ v4l2_dbg(1, debug, sd, "TODO Support interlaced formats\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ths8200_timings); i++) {
+ if (v4l_match_dv_timings(&ths8200_timings[i], timings, 10))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(ths8200_timings)) {
+ v4l2_dbg(1, debug, sd, "Unsupported format\n");
+ return -EINVAL;
+ }
+
+ timings->bt.flags &= ~V4L2_DV_FL_REDUCED_FPS;
+
+ /* save timings */
+ state->dv_timings = *timings;
+
+ ths8200_setup(sd, &timings->bt);
+
+ return 0;
+}
+
+static int ths8200_g_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings *timings)
+{
+ struct ths8200_state *state = to_state(sd);
+
+ v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+ *timings = state->dv_timings;
+
+ return 0;
+}
+
+static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
+ struct v4l2_enum_dv_timings *timings)
+{
+ /* Check requested format index is within range */
+ if (timings->index >= ARRAY_SIZE(ths8200_timings))
+ return -EINVAL;
+
+ timings->timings = ths8200_timings[timings->index];
+
+ return 0;
+}
+
+static int ths8200_dv_timings_cap(struct v4l2_subdev *sd,
+ struct v4l2_dv_timings_cap *cap)
+{
+ cap->type = V4L2_DV_BT_656_1120;
+ cap->bt.max_width = 1920;
+ cap->bt.max_height = 1080;
+ cap->bt.min_pixelclock = 27000000;
+ cap->bt.max_pixelclock = 148500000;
+ cap->bt.standards = V4L2_DV_BT_STD_CEA861;
+ cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE;
+
+ return 0;
+}
+
+/* Specific video subsystem operation handlers */
+static const struct v4l2_subdev_video_ops ths8200_video_ops = {
+ .s_stream = ths8200_s_stream,
+ .s_dv_timings = ths8200_s_dv_timings,
+ .g_dv_timings = ths8200_g_dv_timings,
+ .enum_dv_timings = ths8200_enum_dv_timings,
+ .dv_timings_cap = ths8200_dv_timings_cap,
+};
+
+/* V4L2 top level operation handlers */
+static const struct v4l2_subdev_ops ths8200_ops = {
+ .core = &ths8200_core_ops,
+ .video = &ths8200_video_ops,
+};
+
+static int ths8200_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ths8200_state *state;
+ struct v4l2_subdev *sd;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return -ENOMEM;
+
+ sd = &state->sd;
+ v4l2_i2c_subdev_init(sd, client, &ths8200_ops);
+
+ state->chip_version = ths8200_read(sd, THS8200_VERSION);
+ v4l2_dbg(1, debug, sd, "chip version 0x%x\n", state->chip_version);
+
+ ths8200_core_init(sd);
+
+ v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
+ client->addr << 1, client->adapter->name);
+
+ return 0;
+}
+
+static int ths8200_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_dbg(1, debug, sd, "%s removed @ 0x%x (%s)\n", client->name,
+ client->addr << 1, client->adapter->name);
+
+ ths8200_s_power(sd, false);
+
+ v4l2_device_unregister_subdev(sd);
+
+ return 0;
+}
+
+static struct i2c_device_id ths8200_id[] = {
+ { "ths8200", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, ths8200_id);
+
+static struct i2c_driver ths8200_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ths8200",
+ },
+ .probe = ths8200_probe,
+ .remove = ths8200_remove,
+ .id_table = ths8200_id,
+};
+
+module_i2c_driver(ths8200_driver);
diff --git a/drivers/media/i2c/ths8200_regs.h b/drivers/media/i2c/ths8200_regs.h
new file mode 100644
index 0000000..6bc9fd1
--- /dev/null
+++ b/drivers/media/i2c/ths8200_regs.h
@@ -0,0 +1,161 @@
+/*
+ * ths8200 - Texas Instruments THS8200 video encoder driver
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef THS8200_REGS_H
+#define THS8200_REGS_H
+
+/* Register offset macros */
+#define THS8200_VERSION 0x02
+#define THS8200_CHIP_CTL 0x03
+#define THS8200_CSC_R11 0x04
+#define THS8200_CSC_R12 0x05
+#define THS8200_CSC_R21 0x06
+#define THS8200_CSC_R22 0x07
+#define THS8200_CSC_R31 0x08
+#define THS8200_CSC_R32 0x09
+#define THS8200_CSC_G11 0x0a
+#define THS8200_CSC_G12 0x0b
+#define THS8200_CSC_G21 0x0c
+#define THS8200_CSC_G22 0x0d
+#define THS8200_CSC_G31 0x0e
+#define THS8200_CSC_G32 0x0f
+#define THS8200_CSC_B11 0x10
+#define THS8200_CSC_B12 0x11
+#define THS8200_CSC_B21 0x12
+#define THS8200_CSC_B22 0x13
+#define THS8200_CSC_B31 0x14
+#define THS8200_CSC_B32 0x15
+#define THS8200_CSC_OFFS1 0x16
+#define THS8200_CSC_OFFS12 0x17
+#define THS8200_CSC_OFFS23 0x18
+#define THS8200_CSC_OFFS3 0x19
+#define THS8200_TST_CNTL1 0x1a
+#define THS8200_TST_CNTL2 0x1b
+#define THS8200_DATA_CNTL 0x1c
+#define THS8200_DTG1_Y_SYNC1_LSB 0x1d
+#define THS8200_DTG1_Y_SYNC2_LSB 0x1e
+#define THS8200_DTG1_Y_SYNC3_LSB 0x1f
+#define THS8200_DTG1_CBCR_SYNC1_LSB 0x20
+#define THS8200_DTG1_CBCR_SYNC2_LSB 0x21
+#define THS8200_DTG1_CBCR_SYNC3_LSB 0x22
+#define THS8200_DTG1_Y_SYNC_MSB 0x23
+#define THS8200_DTG1_CBCR_SYNC_MSB 0x24
+#define THS8200_DTG1_SPEC_A 0x25
+#define THS8200_DTG1_SPEC_B 0x26
+#define THS8200_DTG1_SPEC_C 0x27
+#define THS8200_DTG1_SPEC_D_LSB 0x28
+#define THS8200_DTG1_SPEC_D1 0x29
+#define THS8200_DTG1_SPEC_E_LSB 0x2a
+#define THS8200_DTG1_SPEC_DEH_MSB 0x2b
+#define THS8200_DTG1_SPEC_H_LSB 0x2c
+#define THS8200_DTG1_SPEC_I_MSB 0x2d
+#define THS8200_DTG1_SPEC_I_LSB 0x2e
+#define THS8200_DTG1_SPEC_K_LSB 0x2f
+#define THS8200_DTG1_SPEC_K_MSB 0x30
+#define THS8200_DTG1_SPEC_K1 0x31
+#define THS8200_DTG1_SPEC_G_LSB 0x32
+#define THS8200_DTG1_SPEC_G_MSB 0x33
+#define THS8200_DTG1_TOT_PIXELS_MSB 0x34
+#define THS8200_DTG1_TOT_PIXELS_LSB 0x35
+#define THS8200_DTG1_FLD_FLIP_LINECNT_MSB 0x36
+#define THS8200_DTG1_LINECNT_LSB 0x37
+#define THS8200_DTG1_MODE 0x38
+#define THS8200_DTG1_FRAME_FIELD_SZ_MSB 0x39
+#define THS8200_DTG1_FRAME_SZ_LSB 0x3a
+#define THS8200_DTG1_FIELD_SZ_LSB 0x3b
+#define THS8200_DTG1_VESA_CBAR_SIZE 0x3c
+#define THS8200_DAC_CNTL_MSB 0x3d
+#define THS8200_DAC1_CNTL_LSB 0x3e
+#define THS8200_DAC2_CNTL_LSB 0x3f
+#define THS8200_DAC3_CNTL_LSB 0x40
+#define THS8200_CSM_CLIP_GY_LOW 0x41
+#define THS8200_CSM_CLIP_BCB_LOW 0x42
+#define THS8200_CSM_CLIP_RCR_LOW 0x43
+#define THS8200_CSM_CLIP_GY_HIGH 0x44
+#define THS8200_CSM_CLIP_BCB_HIGH 0x45
+#define THS8200_CSM_CLIP_RCR_HIGH 0x46
+#define THS8200_CSM_SHIFT_GY 0x47
+#define THS8200_CSM_SHIFT_BCB 0x48
+#define THS8200_CSM_SHIFT_RCR 0x49
+#define THS8200_CSM_GY_CNTL_MULT_MSB 0x4a
+#define THS8200_CSM_MULT_BCB_RCR_MSB 0x4b
+#define THS8200_CSM_MULT_GY_LSB 0x4c
+#define THS8200_CSM_MULT_BCB_LSB 0x4d
+#define THS8200_CSM_MULT_RCR_LSB 0x4e
+#define THS8200_CSM_MULT_RCR_BCB_CNTL 0x4f
+#define THS8200_CSM_MULT_RCR_LSB 0x4e
+#define THS8200_DTG2_BP1_2_MSB 0x50
+#define THS8200_DTG2_BP3_4_MSB 0x51
+#define THS8200_DTG2_BP5_6_MSB 0x52
+#define THS8200_DTG2_BP7_8_MSB 0x53
+#define THS8200_DTG2_BP9_10_MSB 0x54
+#define THS8200_DTG2_BP11_12_MSB 0x55
+#define THS8200_DTG2_BP13_14_MSB 0x56
+#define THS8200_DTG2_BP15_16_MSB 0x57
+#define THS8200_DTG2_BP1_LSB 0x58
+#define THS8200_DTG2_BP2_LSB 0x59
+#define THS8200_DTG2_BP3_LSB 0x5a
+#define THS8200_DTG2_BP4_LSB 0x5b
+#define THS8200_DTG2_BP5_LSB 0x5c
+#define THS8200_DTG2_BP6_LSB 0x5d
+#define THS8200_DTG2_BP7_LSB 0x5e
+#define THS8200_DTG2_BP8_LSB 0x5f
+#define THS8200_DTG2_BP9_LSB 0x60
+#define THS8200_DTG2_BP10_LSB 0x61
+#define THS8200_DTG2_BP11_LSB 0x62
+#define THS8200_DTG2_BP12_LSB 0x63
+#define THS8200_DTG2_BP13_LSB 0x64
+#define THS8200_DTG2_BP14_LSB 0x65
+#define THS8200_DTG2_BP15_LSB 0x66
+#define THS8200_DTG2_BP16_LSB 0x67
+#define THS8200_DTG2_LINETYPE1 0x68
+#define THS8200_DTG2_LINETYPE2 0x69
+#define THS8200_DTG2_LINETYPE3 0x6a
+#define THS8200_DTG2_LINETYPE4 0x6b
+#define THS8200_DTG2_LINETYPE5 0x6c
+#define THS8200_DTG2_LINETYPE6 0x6d
+#define THS8200_DTG2_LINETYPE7 0x6e
+#define THS8200_DTG2_LINETYPE8 0x6f
+#define THS8200_DTG2_HLENGTH_LSB 0x70
+#define THS8200_DTG2_HLENGTH_LSB_HDLY_MSB 0x71
+#define THS8200_DTG2_HLENGTH_HDLY_LSB 0x72
+#define THS8200_DTG2_VLENGTH1_LSB 0x73
+#define THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB 0x74
+#define THS8200_DTG2_VDLY1_LSB 0x75
+#define THS8200_DTG2_VLENGTH2_LSB 0x76
+#define THS8200_DTG2_VLENGTH2_MSB_VDLY2_MSB 0x77
+#define THS8200_DTG2_VDLY2_LSB 0x78
+#define THS8200_DTG2_HS_IN_DLY_MSB 0x79
+#define THS8200_DTG2_HS_IN_DLY_LSB 0x7a
+#define THS8200_DTG2_VS_IN_DLY_MSB 0x7b
+#define THS8200_DTG2_VS_IN_DLY_LSB 0x7c
+#define THS8200_DTG2_PIXEL_CNT_MSB 0x7d
+#define THS8200_DTG2_PIXEL_CNT_LSB 0x7e
+#define THS8200_DTG2_LINE_CNT_MSB 0x7f
+#define THS8200_DTG2_LINE_CNT_LSB 0x80
+#define THS8200_DTG2_CNTL 0x82
+#define THS8200_CGMS_CNTL_HEADER 0x83
+#define THS8200_CGMS_PAYLOAD_MSB 0x84
+#define THS8200_CGMS_PAYLOAD_LSB 0x85
+#define THS8200_MISC_PPL_LSB 0x86
+#define THS8200_MISC_PPL_MSB 0x87
+#define THS8200_MISC_LPF_MSB 0x88
+#define THS8200_MISC_LPF_LSB 0x89
+
+#endif /* THS8200_REGS_H */
diff --git a/drivers/media/i2c/tlv320aic23b.c b/drivers/media/i2c/tlv320aic23b.c
index 809a75a..ef87f7b 100644
--- a/drivers/media/i2c/tlv320aic23b.c
+++ b/drivers/media/i2c/tlv320aic23b.c
@@ -162,7 +162,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -191,7 +191,6 @@
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return err;
}
v4l2_ctrl_handler_setup(&state->hdl);
@@ -205,7 +204,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return 0;
}
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c
index e0634c8..d76c53a8 100644
--- a/drivers/media/i2c/tvaudio.c
+++ b/drivers/media/i2c/tvaudio.c
@@ -38,7 +38,6 @@
#include <media/tvaudio.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/i2c-addr.h>
@@ -1838,13 +1837,6 @@
return 0;
}
-static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0);
-}
-
static int tvaudio_log_status(struct v4l2_subdev *sd)
{
struct CHIPSTATE *chip = to_state(sd);
@@ -1863,7 +1855,6 @@
static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
.log_status = tvaudio_log_status,
- .g_chip_ident = tvaudio_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -1910,7 +1901,7 @@
printk("\n");
}
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
sd = &chip->sd;
@@ -1930,7 +1921,6 @@
}
if (desc->name == NULL) {
v4l2_dbg(1, debug, sd, "no matching chip description found\n");
- kfree(chip);
return -EIO;
}
v4l2_info(sd, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name);
@@ -2001,7 +1991,6 @@
int err = chip->hdl.error;
v4l2_ctrl_handler_free(&chip->hdl);
- kfree(chip);
return err;
}
/* set controls to the default values */
@@ -2044,7 +2033,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&chip->hdl);
- kfree(chip);
return 0;
}
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index ab8f3fe..9c6d66a 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -39,7 +39,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-mediabus.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-of.h>
#include <media/v4l2-ctrls.h>
#include <media/tvp514x.h>
#include <media/media-entity.h>
@@ -123,6 +123,8 @@
/* mc related members */
struct media_pad pad;
struct v4l2_mbus_framefmt format;
+
+ struct tvp514x_reg *int_seq;
};
/* TVP514x default register values */
@@ -543,8 +545,6 @@
if (std_id == NULL)
return -EINVAL;
- *std_id = V4L2_STD_UNKNOWN;
-
/* To query the standard the TVP514x must power on the ADCs. */
if (!decoder->streaming) {
tvp514x_s_stream(sd, 1);
@@ -553,8 +553,10 @@
/* query the current standard */
current_std = tvp514x_query_current_std(sd);
- if (current_std == STD_INVALID)
+ if (current_std == STD_INVALID) {
+ *std_id = V4L2_STD_UNKNOWN;
return 0;
+ }
input_sel = decoder->input;
@@ -595,10 +597,12 @@
}
/* check whether signal is locked */
sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
- if (lock_mask != (sync_lock_status & lock_mask))
+ if (lock_mask != (sync_lock_status & lock_mask)) {
+ *std_id = V4L2_STD_UNKNOWN;
return 0; /* No input detected */
+ }
- *std_id = decoder->std_list[current_std].standard.id;
+ *std_id &= decoder->std_list[current_std].standard.id;
v4l2_dbg(1, debug, sd, "Current STD: %s\n",
decoder->std_list[current_std].standard.name);
@@ -862,7 +866,6 @@
static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
{
int err = 0;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tvp514x_decoder *decoder = to_decoder(sd);
if (decoder->streaming == enable)
@@ -882,11 +885,8 @@
}
case 1:
{
- struct tvp514x_reg *int_seq = (struct tvp514x_reg *)
- client->driver->id_table->driver_data;
-
/* Power Up Sequence */
- err = tvp514x_write_regs(sd, int_seq);
+ err = tvp514x_write_regs(sd, decoder->int_seq);
if (err) {
v4l2_err(sd, "Unable to turn on decoder\n");
return err;
@@ -1055,6 +1055,42 @@
};
+static struct tvp514x_platform_data *
+tvp514x_get_pdata(struct i2c_client *client)
+{
+ struct tvp514x_platform_data *pdata;
+ struct v4l2_of_endpoint bus_cfg;
+ struct device_node *endpoint;
+ unsigned int flags;
+
+ if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
+ return client->dev.platform_data;
+
+ endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+ if (!endpoint)
+ return NULL;
+
+ pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ goto done;
+
+ v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+ flags = bus_cfg.bus.parallel.flags;
+
+ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+ pdata->hs_polarity = 1;
+
+ if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+ pdata->vs_polarity = 1;
+
+ if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+ pdata->clk_polarity = 1;
+
+done:
+ of_node_put(endpoint);
+ return pdata;
+}
+
/**
* tvp514x_probe() - decoder driver i2c probe handler
* @client: i2c driver client device structure
@@ -1066,19 +1102,20 @@
static int
tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
+ struct tvp514x_platform_data *pdata = tvp514x_get_pdata(client);
struct tvp514x_decoder *decoder;
struct v4l2_subdev *sd;
int ret;
+ if (pdata == NULL) {
+ dev_err(&client->dev, "No platform data\n");
+ return -EINVAL;
+ }
+
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
- if (!client->dev.platform_data) {
- v4l2_err(client, "No platform data!!\n");
- return -ENODEV;
- }
-
decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (!decoder)
return -ENOMEM;
@@ -1089,8 +1126,10 @@
memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
sizeof(tvp514x_reg_list_default));
+ decoder->int_seq = (struct tvp514x_reg *)id->driver_data;
+
/* Copy board specific information here */
- decoder->pdata = client->dev.platform_data;
+ decoder->pdata = pdata;
/**
* Fetch platform specific data, and configure the
@@ -1109,7 +1148,6 @@
/* Register with V4L2 layer as slave device */
sd = &decoder->sd;
v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
- strlcpy(sd->name, TVP514X_MODULE_NAME, sizeof(sd->name));
#if defined(CONFIG_MEDIA_CONTROLLER)
decoder->pad.flags = MEDIA_PAD_FL_SOURCE;
@@ -1120,7 +1158,6 @@
if (ret < 0) {
v4l2_err(sd, "%s decoder driver failed to register !!\n",
sd->name);
- kfree(decoder);
return ret;
}
#endif
@@ -1231,8 +1268,20 @@
MODULE_DEVICE_TABLE(i2c, tvp514x_id);
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id tvp514x_of_match[] = {
+ { .compatible = "ti,tvp5146", },
+ { .compatible = "ti,tvp5146m2", },
+ { .compatible = "ti,tvp5147", },
+ { .compatible = "ti,tvp5147m1", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, tvp514x_of_match);
+#endif
+
static struct i2c_driver tvp514x_driver = {
.driver = {
+ .of_match_table = of_match_ptr(tvp514x_of_match),
.owner = THIS_MODULE,
.name = TVP514X_MODULE_NAME,
},
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 485159a..89c0b13 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <media/v4l2-device.h>
#include <media/tvp5150.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include "tvp5150_reg.h"
@@ -727,13 +726,11 @@
/* First tests should be against specific std */
- if (std == V4L2_STD_ALL) {
- fmt = VIDEO_STD_AUTO_SWITCH_BIT; /* Autodetect mode */
- } else if (std & V4L2_STD_NTSC_443) {
+ if (std == V4L2_STD_NTSC_443) {
fmt = VIDEO_STD_NTSC_4_43_BIT;
- } else if (std & V4L2_STD_PAL_M) {
+ } else if (std == V4L2_STD_PAL_M) {
fmt = VIDEO_STD_PAL_M_BIT;
- } else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
+ } else if (std == V4L2_STD_PAL_N || std == V4L2_STD_PAL_Nc) {
fmt = VIDEO_STD_PAL_COMBINATION_N_BIT;
} else {
/* Then, test against generic ones */
@@ -1031,31 +1028,11 @@
return 0;
}
-static int tvp5150_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- int rev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- rev = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER) << 8 |
- tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP5150,
- rev);
-}
-
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
int res;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
res = tvp5150_read(sd, reg->reg & 0xff);
if (res < 0) {
v4l2_err(sd, "%s: failed with error = %d\n", __func__, res);
@@ -1069,12 +1046,6 @@
static int tvp5150_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff);
return 0;
}
@@ -1098,7 +1069,6 @@
.log_status = tvp5150_log_status,
.s_std = tvp5150_s_std,
.reset = tvp5150_reset,
- .g_chip_ident = tvp5150_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = tvp5150_g_register,
.s_register = tvp5150_s_register,
@@ -1152,10 +1122,9 @@
I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
return -EIO;
- core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL);
- if (!core) {
+ core = devm_kzalloc(&c->dev, sizeof(*core), GFP_KERNEL);
+ if (!core)
return -ENOMEM;
- }
sd = &core->sd;
v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
@@ -1166,7 +1135,7 @@
for (i = 0; i < 4; i++) {
res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
if (res < 0)
- goto free_core;
+ return res;
tvp5150_id[i] = res;
}
@@ -1209,7 +1178,7 @@
if (core->hdl.error) {
res = core->hdl.error;
v4l2_ctrl_handler_free(&core->hdl);
- goto free_core;
+ return res;
}
v4l2_ctrl_handler_setup(&core->hdl);
@@ -1225,10 +1194,6 @@
if (debug > 1)
tvp5150_log_status(sd);
return 0;
-
-free_core:
- kfree(core);
- return res;
}
static int tvp5150_remove(struct i2c_client *c)
@@ -1242,7 +1207,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(to_tvp5150(sd));
return 0;
}
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 027809c..a4e4948 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -32,7 +32,6 @@
#include <linux/v4l2-dv-timings.h>
#include <media/tvp7002.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include "tvp7002_reg.h"
@@ -41,9 +40,6 @@
MODULE_AUTHOR("Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>");
MODULE_LICENSE("GPL");
-/* Module Name */
-#define TVP7002_MODULE_NAME "tvp7002"
-
/* I2C retry attempts */
#define I2C_RETRY_COUNT (5)
@@ -424,6 +420,7 @@
int streaming;
const struct tvp7002_timings_definition *current_timings;
+ struct media_pad pad;
};
/*
@@ -535,29 +532,6 @@
}
/*
- * tvp7002_g_chip_ident() - Get chip identification number
- * @sd: ptr to v4l2_subdev struct
- * @chip: ptr to v4l2_dbg_chip_ident struct
- *
- * Obtains the chip's identification number.
- * Returns zero or -EINVAL if read operation fails.
- */
-static int tvp7002_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- u8 rev;
- int error;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- error = tvp7002_read(sd, TVP7002_CHIP_REV, &rev);
-
- if (error < 0)
- return error;
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP7002, rev);
-}
-
-/*
* tvp7002_write_inittab() - Write initialization values
* @sd: ptr to v4l2_subdev struct
* @regs: ptr to i2c_reg_value struct
@@ -738,23 +712,17 @@
*
* Get the value of a TVP7002 decoder device register.
* Returns zero when successful, -EINVAL if register read fails or
- * access to I2C client fails, -EPERM if the call is not allowed
- * by disabled CAP_SYS_ADMIN.
+ * access to I2C client fails.
*/
static int tvp7002_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 val;
int ret;
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
ret = tvp7002_read(sd, reg->reg & 0xff, &val);
reg->val = val;
+ reg->size = 1;
return ret;
}
@@ -764,19 +732,11 @@
* @reg: ptr to v4l2_dbg_register struct
*
* Get the value of a TVP7002 decoder device register.
- * Returns zero when successful, -EINVAL if register read fails or
- * -EPERM if call not allowed.
+ * Returns zero when successful, -EINVAL if register read fails.
*/
static int tvp7002_s_register(struct v4l2_subdev *sd,
const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
}
#endif
@@ -880,9 +840,67 @@
.s_ctrl = tvp7002_s_ctrl,
};
+/*
+ * tvp7002_enum_mbus_code() - Enum supported digital video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @code: pointer to subdev enum mbus code struct
+ *
+ * Enumerate supported digital video formats for pad.
+ */
+static int
+tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ /* Check requested format index is within range */
+ if (code->index != 0)
+ return -EINVAL;
+
+ code->code = V4L2_MBUS_FMT_YUYV10_1X20;
+
+ return 0;
+}
+
+/*
+ * tvp7002_get_pad_format() - get video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @fmt: pointer to subdev format struct
+ *
+ * get video format for pad.
+ */
+static int
+tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_format *fmt)
+{
+ struct tvp7002 *tvp7002 = to_tvp7002(sd);
+
+ fmt->format.code = V4L2_MBUS_FMT_YUYV10_1X20;
+ fmt->format.width = tvp7002->current_timings->timings.bt.width;
+ fmt->format.height = tvp7002->current_timings->timings.bt.height;
+ fmt->format.field = tvp7002->current_timings->scanmode;
+ fmt->format.colorspace = tvp7002->current_timings->color_space;
+
+ return 0;
+}
+
+/*
+ * tvp7002_set_pad_format() - set video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @fmt: pointer to subdev format struct
+ *
+ * set video format for pad.
+ */
+static int
+tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_format *fmt)
+{
+ return tvp7002_get_pad_format(sd, fh, fmt);
+}
+
/* V4L2 core operation handlers */
static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
- .g_chip_ident = tvp7002_g_chip_ident,
.log_status = tvp7002_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
@@ -910,10 +928,18 @@
.enum_mbus_fmt = tvp7002_enum_mbus_fmt,
};
+/* media pad related operation handlers */
+static const struct v4l2_subdev_pad_ops tvp7002_pad_ops = {
+ .enum_mbus_code = tvp7002_enum_mbus_code,
+ .get_fmt = tvp7002_get_pad_format,
+ .set_fmt = tvp7002_set_pad_format,
+};
+
/* V4L2 top level operation handlers */
static const struct v4l2_subdev_ops tvp7002_ops = {
.core = &tvp7002_core_ops,
.video = &tvp7002_video_ops,
+ .pad = &tvp7002_pad_ops,
};
/*
@@ -993,19 +1019,34 @@
timings = device->current_timings->timings;
error = tvp7002_s_dv_timings(sd, &timings);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ device->pad.flags = MEDIA_PAD_FL_SOURCE;
+ device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
+
+ error = media_entity_init(&device->sd.entity, 1, &device->pad, 0);
+ if (error < 0)
+ return error;
+#endif
+
v4l2_ctrl_handler_init(&device->hdl, 1);
v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
V4L2_CID_GAIN, 0, 255, 1, 0);
sd->ctrl_handler = &device->hdl;
if (device->hdl.error) {
- int err = device->hdl.error;
-
- v4l2_ctrl_handler_free(&device->hdl);
- return err;
+ error = device->hdl.error;
+ goto error;
}
v4l2_ctrl_handler_setup(&device->hdl);
return 0;
+
+error:
+ v4l2_ctrl_handler_free(&device->hdl);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ media_entity_cleanup(&device->sd.entity);
+#endif
+ return error;
}
/*
@@ -1022,7 +1063,9 @@
v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
"on address 0x%x\n", c->addr);
-
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ media_entity_cleanup(&device->sd.entity);
+#endif
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&device->hdl);
return 0;
diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c
index c5dc2c3b..f58607d 100644
--- a/drivers/media/i2c/tw2804.c
+++ b/drivers/media/i2c/tw2804.c
@@ -23,7 +23,6 @@
#include <linux/slab.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#define TW2804_REG_AUTOGAIN 0x02
@@ -368,8 +367,7 @@
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
- state = kzalloc(sizeof(struct tw2804), GFP_KERNEL);
-
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -410,7 +408,6 @@
err = state->hdl.error;
if (err) {
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return err;
}
@@ -427,7 +424,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return 0;
}
diff --git a/drivers/media/i2c/tw9903.c b/drivers/media/i2c/tw9903.c
index 87880b1..285b759 100644
--- a/drivers/media/i2c/tw9903.c
+++ b/drivers/media/i2c/tw9903.c
@@ -215,7 +215,7 @@
v4l_info(client, "chip found @ 0x%02x (%s)\n",
client->addr << 1, client->adapter->name);
- dec = kzalloc(sizeof(struct tw9903), GFP_KERNEL);
+ dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
if (dec == NULL)
return -ENOMEM;
sd = &dec->sd;
@@ -233,7 +233,6 @@
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
- kfree(dec);
return err;
}
@@ -242,7 +241,6 @@
if (write_regs(sd, initial_registers) < 0) {
v4l2_err(client, "error initializing TW9903\n");
- kfree(dec);
return -EINVAL;
}
@@ -255,7 +253,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&to_state(sd)->hdl);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/tw9906.c b/drivers/media/i2c/tw9906.c
index accd79e..f6bef25 100644
--- a/drivers/media/i2c/tw9906.c
+++ b/drivers/media/i2c/tw9906.c
@@ -183,7 +183,7 @@
v4l_info(client, "chip found @ 0x%02x (%s)\n",
client->addr << 1, client->adapter->name);
- dec = kzalloc(sizeof(struct tw9906), GFP_KERNEL);
+ dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
if (dec == NULL)
return -ENOMEM;
sd = &dec->sd;
@@ -201,7 +201,6 @@
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
- kfree(dec);
return err;
}
@@ -210,7 +209,6 @@
if (write_regs(sd, initial_registers) < 0) {
v4l2_err(client, "error initializing TW9906\n");
- kfree(dec);
return -EINVAL;
}
@@ -223,7 +221,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&to_state(sd)->hdl);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/uda1342.c b/drivers/media/i2c/uda1342.c
index 3af4085..081786d 100644
--- a/drivers/media/i2c/uda1342.c
+++ b/drivers/media/i2c/uda1342.c
@@ -69,7 +69,7 @@
dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n",
client->addr, adapter->name);
- sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
if (sd == NULL)
return -ENOMEM;
@@ -89,7 +89,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(sd);
return 0;
}
diff --git a/drivers/media/i2c/upd64031a.c b/drivers/media/i2c/upd64031a.c
index f0a0921..d248e6a 100644
--- a/drivers/media/i2c/upd64031a.c
+++ b/drivers/media/i2c/upd64031a.c
@@ -27,7 +27,6 @@
#include <linux/videodev2.h>
#include <linux/slab.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/upd64031a.h>
/* --------------------- read registers functions define -------------------- */
@@ -147,13 +146,6 @@
return upd64031a_s_frequency(sd, NULL);
}
-static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64031A, 0);
-}
-
static int upd64031a_log_status(struct v4l2_subdev *sd)
{
v4l2_info(sd, "Status: SA00=0x%02x SA01=0x%02x\n",
@@ -164,12 +156,6 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = upd64031a_read(sd, reg->reg & 0xff);
reg->size = 1;
return 0;
@@ -177,12 +163,6 @@
static int upd64031a_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
upd64031a_write(sd, reg->reg & 0xff, reg->val & 0xff);
return 0;
}
@@ -192,7 +172,6 @@
static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
.log_status = upd64031a_log_status,
- .g_chip_ident = upd64031a_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = upd64031a_g_register,
.s_register = upd64031a_s_register,
@@ -230,7 +209,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct upd64031a_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -249,7 +228,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/upd64083.c b/drivers/media/i2c/upd64083.c
index 343e021..3a152ce 100644
--- a/drivers/media/i2c/upd64083.c
+++ b/drivers/media/i2c/upd64083.c
@@ -27,7 +27,6 @@
#include <linux/videodev2.h>
#include <linux/slab.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/upd64083.h>
MODULE_DESCRIPTION("uPD64083 driver");
@@ -122,12 +121,6 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = upd64083_read(sd, reg->reg & 0xff);
reg->size = 1;
return 0;
@@ -135,24 +128,11 @@
static int upd64083_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
upd64083_write(sd, reg->reg & 0xff, reg->val & 0xff);
return 0;
}
#endif
-static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64083, 0);
-}
-
static int upd64083_log_status(struct v4l2_subdev *sd)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -169,7 +149,6 @@
static const struct v4l2_subdev_core_ops upd64083_core_ops = {
.log_status = upd64083_log_status,
- .g_chip_ident = upd64083_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = upd64083_g_register,
.s_register = upd64083_s_register,
@@ -202,7 +181,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct upd64083_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -221,7 +200,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/vp27smpx.c b/drivers/media/i2c/vp27smpx.c
index e71f139..6a3a3ff 100644
--- a/drivers/media/i2c/vp27smpx.c
+++ b/drivers/media/i2c/vp27smpx.c
@@ -29,7 +29,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
MODULE_DESCRIPTION("vp27smpx driver");
MODULE_AUTHOR("Hans Verkuil");
@@ -112,13 +111,6 @@
return 0;
}
-static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VP27SMPX, 0);
-}
-
static int vp27smpx_log_status(struct v4l2_subdev *sd)
{
struct vp27smpx_state *state = to_state(sd);
@@ -132,7 +124,6 @@
static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
.log_status = vp27smpx_log_status,
- .g_chip_ident = vp27smpx_g_chip_ident,
.s_std = vp27smpx_s_std,
};
@@ -169,7 +160,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -186,7 +177,6 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/vpx3220.c b/drivers/media/i2c/vpx3220.c
index 2f67b4c..ece90df 100644
--- a/drivers/media/i2c/vpx3220.c
+++ b/drivers/media/i2c/vpx3220.c
@@ -27,7 +27,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
@@ -49,7 +48,6 @@
unsigned char reg[255];
v4l2_std_id norm;
- int ident;
int input;
int enable;
};
@@ -297,7 +295,7 @@
static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
{
int res = V4L2_IN_ST_NO_SIGNAL, status;
- v4l2_std_id std = 0;
+ v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
status = vpx3220_fp_read(sd, 0x0f3);
@@ -314,19 +312,21 @@
case 0x10:
case 0x14:
case 0x18:
- std = V4L2_STD_PAL;
+ std &= V4L2_STD_PAL;
break;
case 0x08:
- std = V4L2_STD_SECAM;
+ std &= V4L2_STD_SECAM;
break;
case 0x04:
case 0x0c:
case 0x1c:
- std = V4L2_STD_NTSC;
+ std &= V4L2_STD_NTSC;
break;
}
+ } else {
+ std = V4L2_STD_UNKNOWN;
}
if (pstd)
*pstd = std;
@@ -442,14 +442,6 @@
return -EINVAL;
}
-static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct vpx3220 *decoder = to_vpx3220(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
@@ -457,7 +449,6 @@
};
static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
- .g_chip_ident = vpx3220_g_chip_ident,
.init = vpx3220_init,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
@@ -499,7 +490,7 @@
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
- decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
+ decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
sd = &decoder->sd;
@@ -521,7 +512,6 @@
int err = decoder->hdl.error;
v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
return err;
}
v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -529,7 +519,6 @@
ver = i2c_smbus_read_byte_data(client, 0x00);
pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
i2c_smbus_read_byte_data(client, 0x01);
- decoder->ident = V4L2_IDENT_VPX3220A;
if (ver == 0xec) {
switch (pn) {
case 0x4680:
@@ -537,11 +526,9 @@
break;
case 0x4260:
name = "vpx3216b";
- decoder->ident = V4L2_IDENT_VPX3216B;
break;
case 0x4280:
name = "vpx3214c";
- decoder->ident = V4L2_IDENT_VPX3214C;
break;
}
}
@@ -566,7 +553,7 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&decoder->hdl);
- kfree(decoder);
+
return 0;
}
diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c
index f366fad..25bdd93 100644
--- a/drivers/media/i2c/vs6624.c
+++ b/drivers/media/i2c/vs6624.c
@@ -27,7 +27,6 @@
#include <linux/types.h>
#include <linux/videodev2.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
@@ -722,27 +721,9 @@
return 0;
}
-static int vs6624_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- int rev;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- rev = (vs6624_read(sd, VS6624_FW_VSN_MAJOR) << 8)
- | vs6624_read(sd, VS6624_FW_VSN_MINOR);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VS6624, rev);
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int vs6624_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->val = vs6624_read(sd, reg->reg & 0xffff);
reg->size = 1;
return 0;
@@ -750,12 +731,6 @@
static int vs6624_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (!v4l2_chip_match_i2c_client(client, ®->match))
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
vs6624_write(sd, reg->reg & 0xffff, reg->val & 0xff);
return 0;
}
@@ -766,7 +741,6 @@
};
static const struct v4l2_subdev_core_ops vs6624_core_ops = {
- .g_chip_ident = vs6624_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = vs6624_g_register,
.s_register = vs6624_s_register,
@@ -805,20 +779,18 @@
if (ce == NULL)
return -EINVAL;
- ret = gpio_request(*ce, "VS6624 Chip Enable");
+ ret = devm_gpio_request_one(&client->dev, *ce, GPIOF_OUT_INIT_HIGH,
+ "VS6624 Chip Enable");
if (ret) {
v4l_err(client, "failed to request GPIO %d\n", *ce);
return ret;
}
- gpio_direction_output(*ce, 1);
/* wait 100ms before any further i2c writes are performed */
mdelay(100);
- sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
- if (sensor == NULL) {
- gpio_free(*ce);
+ sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
+ if (sensor == NULL)
return -ENOMEM;
- }
sd = &sensor->sd;
v4l2_i2c_subdev_init(sd, client, &vs6624_ops);
@@ -866,30 +838,22 @@
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
- kfree(sensor);
- gpio_free(*ce);
return err;
}
/* initialize the hardware to the default control values */
ret = v4l2_ctrl_handler_setup(hdl);
- if (ret) {
+ if (ret)
v4l2_ctrl_handler_free(hdl);
- kfree(sensor);
- gpio_free(*ce);
- }
return ret;
}
static int vs6624_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct vs6624 *sensor = to_vs6624(sd);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- gpio_free(sensor->ce_pin);
- kfree(sensor);
return 0;
}
diff --git a/drivers/media/i2c/wm8739.c b/drivers/media/i2c/wm8739.c
index 3bb99e9..3be73f6 100644
--- a/drivers/media/i2c/wm8739.c
+++ b/drivers/media/i2c/wm8739.c
@@ -29,7 +29,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
MODULE_DESCRIPTION("wm8739 driver");
@@ -160,13 +159,6 @@
return 0;
}
-static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8739, 0);
-}
-
static int wm8739_log_status(struct v4l2_subdev *sd)
{
struct wm8739_state *state = to_state(sd);
@@ -184,7 +176,6 @@
static const struct v4l2_subdev_core_ops wm8739_core_ops = {
.log_status = wm8739_log_status,
- .g_chip_ident = wm8739_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -220,7 +211,7 @@
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct wm8739_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -237,7 +228,6 @@
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return err;
}
v4l2_ctrl_cluster(3, &state->volume);
@@ -271,7 +261,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/i2c/wm8775.c b/drivers/media/i2c/wm8775.c
index 27c27b4..3f584a7 100644
--- a/drivers/media/i2c/wm8775.c
+++ b/drivers/media/i2c/wm8775.c
@@ -33,7 +33,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/wm8775.h>
@@ -158,13 +157,6 @@
return -EINVAL;
}
-static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8775, 0);
-}
-
static int wm8775_log_status(struct v4l2_subdev *sd)
{
struct wm8775_state *state = to_state(sd);
@@ -188,7 +180,6 @@
static const struct v4l2_subdev_core_ops wm8775_core_ops = {
.log_status = wm8775_log_status,
- .g_chip_ident = wm8775_g_chip_ident,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -241,7 +232,7 @@
v4l_info(client, "chip found @ 0x%02x (%s)\n",
client->addr << 1, client->adapter->name);
- state = kzalloc(sizeof(struct wm8775_state), GFP_KERNEL);
+ state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (state == NULL)
return -ENOMEM;
sd = &state->sd;
@@ -261,7 +252,6 @@
err = state->hdl.error;
if (err) {
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return err;
}
@@ -319,7 +309,6 @@
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
- kfree(state);
return 0;
}
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 1957c0d..d5a7a13 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -142,6 +142,8 @@
for (p = 0; p < entity->num_pads; p++) {
struct media_pad_desc pad;
+
+ memset(&pad, 0, sizeof(pad));
media_device_kpad_to_upad(&entity->pads[p], &pad);
if (copy_to_user(&links->pads[p], &pad, sizeof(pad)))
return -EFAULT;
@@ -159,6 +161,7 @@
if (entity->links[l].source->entity != entity)
continue;
+ memset(&link, 0, sizeof(link));
media_device_kpad_to_upad(entity->links[l].source,
&link.source);
media_device_kpad_to_upad(entity->links[l].sink,
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index e1cd132..cb30ffb 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -429,6 +429,56 @@
}
EXPORT_SYMBOL_GPL(media_entity_create_link);
+void __media_entity_remove_links(struct media_entity *entity)
+{
+ unsigned int i;
+
+ for (i = 0; i < entity->num_links; i++) {
+ struct media_link *link = &entity->links[i];
+ struct media_entity *remote;
+ unsigned int r = 0;
+
+ if (link->source->entity == entity)
+ remote = link->sink->entity;
+ else
+ remote = link->source->entity;
+
+ while (r < remote->num_links) {
+ struct media_link *rlink = &remote->links[r];
+
+ if (rlink != link->reverse) {
+ r++;
+ continue;
+ }
+
+ if (link->source->entity == entity)
+ remote->num_backlinks--;
+
+ if (--remote->num_links == 0)
+ break;
+
+ /* Insert last entry in place of the dropped link. */
+ *rlink = remote->links[remote->num_links];
+ }
+ }
+
+ entity->num_links = 0;
+ entity->num_backlinks = 0;
+}
+EXPORT_SYMBOL_GPL(__media_entity_remove_links);
+
+void media_entity_remove_links(struct media_entity *entity)
+{
+ /* Do nothing if the entity is not registered. */
+ if (entity->parent == NULL)
+ return;
+
+ mutex_lock(&entity->parent->graph_mutex);
+ __media_entity_remove_links(entity);
+ mutex_unlock(&entity->parent->graph_mutex);
+}
+EXPORT_SYMBOL_GPL(media_entity_remove_links);
+
static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
{
int ret;
@@ -496,25 +546,17 @@
mdev = source->parent;
- if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) {
- ret = mdev->link_notify(link->source, link->sink,
- MEDIA_LNK_FL_ENABLED);
+ if (mdev->link_notify) {
+ ret = mdev->link_notify(link, flags,
+ MEDIA_DEV_NOTIFY_PRE_LINK_CH);
if (ret < 0)
return ret;
}
ret = __media_entity_setup_link_notify(link, flags);
- if (ret < 0)
- goto err;
- if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
- mdev->link_notify(link->source, link->sink, 0);
-
- return 0;
-
-err:
- if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
- mdev->link_notify(link->source, link->sink, 0);
+ if (mdev->link_notify)
+ mdev->link_notify(link, flags, MEDIA_DEV_NOTIFY_POST_LINK_CH);
return ret;
}
@@ -560,17 +602,16 @@
EXPORT_SYMBOL_GPL(media_entity_find_link);
/**
- * media_entity_remote_source - Find the source pad at the remote end of a link
- * @pad: Sink pad at the local end of the link
+ * media_entity_remote_pad - Find the pad at the remote end of a link
+ * @pad: Pad at the local end of the link
*
- * Search for a remote source pad connected to the given sink pad by iterating
- * over all links originating or terminating at that pad until an enabled link
- * is found.
+ * Search for a remote pad connected to the given pad by iterating over all
+ * links originating or terminating at that pad until an enabled link is found.
*
* Return a pointer to the pad at the remote end of the first found enabled
* link, or NULL if no enabled link has been found.
*/
-struct media_pad *media_entity_remote_source(struct media_pad *pad)
+struct media_pad *media_entity_remote_pad(struct media_pad *pad)
{
unsigned int i;
@@ -590,4 +631,4 @@
return NULL;
}
-EXPORT_SYMBOL_GPL(media_entity_remote_source);
+EXPORT_SYMBOL_GPL(media_entity_remote_pad);
diff --git a/drivers/media/parport/bw-qcam.c b/drivers/media/parport/bw-qcam.c
index 06231b8..d12bd33 100644
--- a/drivers/media/parport/bw-qcam.c
+++ b/drivers/media/parport/bw-qcam.c
@@ -687,6 +687,7 @@
parport_release(qcam->pdev);
mutex_unlock(&qcam->lock);
+ v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
if (len != size)
vb->state = VB2_BUF_STATE_ERROR;
vb2_set_plane_payload(vb, 0, len);
@@ -964,6 +965,7 @@
q->drv_priv = qcam;
q->ops = &qcam_video_qops;
q->mem_ops = &vb2_vmalloc_memops;
+ q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
err = vb2_queue_init(q);
if (err < 0) {
v4l2_err(v4l2_dev, "couldn't init vb2_queue for %s.\n", port->name);
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index d4e2ed3..53196f1 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -1,6 +1,7 @@
+if PCI && MEDIA_SUPPORT
+
menuconfig MEDIA_PCI_SUPPORT
bool "Media PCI Adapters"
- depends on PCI && MEDIA_SUPPORT
help
Enable media drivers for PCI/PCIe bus.
If you have such devices, say Y.
@@ -45,3 +46,4 @@
endif
endif #MEDIA_PCI_SUPPORT
+endif #PCI
diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c
index 44f8fb5..447afbd 100644
--- a/drivers/media/pci/b2c2/flexcop-pci.c
+++ b/drivers/media/pci/b2c2/flexcop-pci.c
@@ -432,18 +432,7 @@
.remove = flexcop_pci_remove,
};
-static int __init flexcop_pci_module_init(void)
-{
- return pci_register_driver(&flexcop_pci_driver);
-}
-
-static void __exit flexcop_pci_module_exit(void)
-{
- pci_unregister_driver(&flexcop_pci_driver);
-}
-
-module_init(flexcop_pci_module_init);
-module_exit(flexcop_pci_module_exit);
+module_pci_driver(flexcop_pci_driver);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_NAME);
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c
index b7dc921..e564aac 100644
--- a/drivers/media/pci/bt8xx/bttv-cards.c
+++ b/drivers/media/pci/bt8xx/bttv-cards.c
@@ -131,7 +131,7 @@
"[yet another chipset flaw workaround]");
MODULE_PARM_DESC(latency,"pci latency timer");
MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
-MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
+MODULE_PARM_DESC(pll, "specify installed crystal (0=none, 28=28 MHz, 35=35 MHz, 14=14 MHz)");
MODULE_PARM_DESC(tuner,"specify installed tuner type");
MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore");
MODULE_PARM_DESC(audiodev, "specify audio device:\n"
@@ -2705,7 +2705,7 @@
.has_radio = 1,
.has_remote = 1,
},
- [BTTV_BOARD_VD012] = {
+ [BTTV_BOARD_VD012] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012 (bt878)",
.video_inputs = 4,
@@ -2718,7 +2718,7 @@
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
- [BTTV_BOARD_VD012_X1] = {
+ [BTTV_BOARD_VD012_X1] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012-X1 (bt878)",
.video_inputs = 4,
@@ -2731,7 +2731,7 @@
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
- [BTTV_BOARD_VD012_X2] = {
+ [BTTV_BOARD_VD012_X2] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012-X2 (bt878)",
.video_inputs = 4,
@@ -2744,7 +2744,7 @@
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
- [BTTV_BOARD_GEOVISION_GV800S] = {
+ [BTTV_BOARD_GEOVISION_GV800S] = {
/* Bruno Christo <bchristo@inf.ufsm.br>
*
* GeoVision GV-800(S) has 4 Conexant Fusion 878A:
@@ -2771,7 +2771,7 @@
.no_tda7432 = 1,
.muxsel_hook = gv800s_muxsel,
},
- [BTTV_BOARD_GEOVISION_GV800S_SL] = {
+ [BTTV_BOARD_GEOVISION_GV800S_SL] = {
/* Bruno Christo <bchristo@inf.ufsm.br>
*
* GeoVision GV-800(S) has 4 Conexant Fusion 878A:
@@ -2808,6 +2808,7 @@
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
+ /* ---- card 0xa0---------------------------------- */
[BTTV_BOARD_TVT_TD3116] = {
.name = "Tongwei Video Technology TD-3116",
.video_inputs = 16,
@@ -2825,6 +2826,35 @@
.muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = TUNER_ABSENT,
},
+ [BTTV_BOARD_ADLINK_MPG24] = {
+ /* Adlink MPG24 */
+ .name = "Adlink MPG24",
+ .video_inputs = 1,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 2, 2, 2),
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_BT848_CAP_14] = {
+ .name = "Bt848 Capture 14MHz",
+ .video_inputs = 4,
+ .svhs = 2,
+ .muxsel = MUXSEL(2, 3, 1, 0),
+ .pll = PLL_14,
+ .tuner_type = TUNER_ABSENT,
+ },
+ [BTTV_BOARD_CYBERVISION_CV06] = {
+ .name = "CyberVision CV06 (SV)",
+ .video_inputs = 4,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ },
};
@@ -3390,6 +3420,10 @@
btv->pll.pll_ifreq=35468950;
btv->pll.pll_crystal=BT848_IFORM_XT1;
}
+ if (PLL_14 == bttv_tvcards[btv->c.type].pll) {
+ btv->pll.pll_ifreq = 14318181;
+ btv->pll.pll_crystal = BT848_IFORM_XT0;
+ }
/* insmod options can override */
switch (pll[btv->c.nr]) {
case 0: /* none */
@@ -3409,6 +3443,12 @@
btv->pll.pll_ofreq = 0;
btv->pll.pll_crystal = BT848_IFORM_XT1;
break;
+ case 3: /* 14 MHz */
+ case 14:
+ btv->pll.pll_ifreq = 14318181;
+ btv->pll.pll_ofreq = 0;
+ btv->pll.pll_crystal = BT848_IFORM_XT0;
+ break;
}
}
btv->pll.pll_current = -1;
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index e7d0884..c6532de 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -50,7 +50,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
#include <media/tvaudio.h>
#include <media/msp3400.h>
@@ -1761,9 +1760,9 @@
struct bttv *btv = fh->btv;
if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
- *id = V4L2_STD_625_50;
+ *id &= V4L2_STD_625_50;
else
- *id = V4L2_STD_525_60;
+ *id &= V4L2_STD_525_60;
return 0;
}
@@ -1907,28 +1906,6 @@
return 0;
}
-static int bttv_g_chip_ident(struct file *file, void *f, struct v4l2_dbg_chip_ident *chip)
-{
- struct bttv_fh *fh = f;
- struct bttv *btv = fh->btv;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(&chip->match)) {
- chip->ident = btv->id;
- if (chip->ident == PCI_DEVICE_ID_FUSION879)
- chip->ident = V4L2_IDENT_BT879;
- }
- return 0;
- }
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
- /* TODO: is this correct? */
- return bttv_call_all_err(btv, core, g_chip_ident, chip);
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int bttv_g_register(struct file *file, void *f,
struct v4l2_dbg_register *reg)
@@ -1936,16 +1913,6 @@
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (!v4l2_chip_match_host(®->match)) {
- /* TODO: subdev errors should not be ignored, this should become a
- subdev helper function. */
- bttv_call_all(btv, core, g_register, reg);
- return 0;
- }
-
/* bt848 has a 12-bit register space */
reg->reg &= 0xfff;
reg->val = btread(reg->reg);
@@ -1960,16 +1927,6 @@
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (!v4l2_chip_match_host(®->match)) {
- /* TODO: subdev errors should not be ignored, this should become a
- subdev helper function. */
- bttv_call_all(btv, core, s_register, reg);
- return 0;
- }
-
/* bt848 has a 12-bit register space */
btwrite(reg->val, reg->reg & 0xfff);
@@ -3209,7 +3166,6 @@
.vidioc_querystd = bttv_querystd,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = bttv_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = bttv_g_register,
.vidioc_s_register = bttv_s_register,
diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h
index 6139ce2..df578ef 100644
--- a/drivers/media/pci/bt8xx/bttv.h
+++ b/drivers/media/pci/bt8xx/bttv.h
@@ -185,6 +185,9 @@
#define BTTV_BOARD_PV183 0x9f
#define BTTV_BOARD_TVT_TD3116 0xa0
#define BTTV_BOARD_APOSONIC_WDVR 0xa1
+#define BTTV_BOARD_ADLINK_MPG24 0xa2
+#define BTTV_BOARD_BT848_CAP_14 0xa3
+#define BTTV_BOARD_CYBERVISION_CV06 0xa4
/* more card-specific defines */
#define PT2254_L_CHANNEL 0x10
@@ -232,6 +235,7 @@
#define PLL_NONE 0
#define PLL_28 1
#define PLL_35 2
+#define PLL_14 3
/* i2c audio flags */
unsigned int no_msp34xx:1;
diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c
index 38b1d64..c4890a4 100644
--- a/drivers/media/pci/cx18/cx18-av-core.c
+++ b/drivers/media/pci/cx18/cx18-av-core.c
@@ -22,7 +22,6 @@
* 02110-1301, USA.
*/
-#include <media/v4l2-chip-ident.h>
#include "cx18-driver.h"
#include "cx18-io.h"
#include "cx18-cards.h"
@@ -1231,35 +1230,14 @@
return 0;
}
-static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
-{
- return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
-}
-
-static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx18_av_state *state = to_cx18_av_state(sd);
-
- if (cx18_av_dbg_match(&chip->match)) {
- chip->ident = state->id;
- chip->revision = state->rev;
- }
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cx18_av_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
- if (!cx18_av_dbg_match(®->match))
- return -EINVAL;
if ((reg->reg & 0x3) != 0)
return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->size = 4;
reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
return 0;
@@ -1270,12 +1248,8 @@
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
- if (!cx18_av_dbg_match(®->match))
- return -EINVAL;
if ((reg->reg & 0x3) != 0)
return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
return 0;
}
@@ -1286,17 +1260,9 @@
};
static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
- .g_chip_ident = cx18_av_g_chip_ident,
.log_status = cx18_av_log_status,
.load_fw = cx18_av_load_fw,
.reset = cx18_av_reset,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
.s_std = cx18_av_s_std,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cx18_av_g_register,
@@ -1344,8 +1310,6 @@
int err;
state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
- state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
- ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
state->vid_input = CX18_AV_COMPOSITE7;
state->aud_input = CX18_AV_AUDIO8;
diff --git a/drivers/media/pci/cx18/cx18-av-core.h b/drivers/media/pci/cx18/cx18-av-core.h
index e9c69d9..4c559e8 100644
--- a/drivers/media/pci/cx18/cx18-av-core.h
+++ b/drivers/media/pci/cx18/cx18-av-core.h
@@ -104,7 +104,6 @@
enum cx18_av_audio_input aud_input;
u32 audclk_freq;
int audmode;
- u32 id;
u32 rev;
int is_initialized;
diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
index aee7b6d..1110bcb 100644
--- a/drivers/media/pci/cx18/cx18-ioctl.c
+++ b/drivers/media/pci/cx18/cx18-ioctl.c
@@ -39,7 +39,6 @@
#include "cx18-cards.h"
#include "cx18-av-core.h"
#include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
u16 cx18_service2vbi(int type)
{
@@ -362,73 +361,18 @@
return 0;
}
-static int cx18_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx18 *cx = fh2id(fh)->cx;
- int err = 0;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- switch (chip->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- switch (chip->match.addr) {
- case 0:
- chip->ident = V4L2_IDENT_CX23418;
- chip->revision = cx18_read_reg(cx, 0xC72028);
- break;
- case 1:
- /*
- * The A/V decoder is always present, but in the rare
- * case that the card doesn't have analog, we don't
- * use it. We find it w/o using the cx->sd_av pointer
- */
- cx18_call_hw(cx, CX18_HW_418_AV,
- core, g_chip_ident, chip);
- break;
- default:
- /*
- * Could return ident = V4L2_IDENT_UNKNOWN if we had
- * other host chips at higher addresses, but we don't
- */
- err = -EINVAL; /* per V4L2 spec */
- break;
- }
- break;
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
- cx18_call_all(cx, core, g_chip_ident, chip);
- break;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /*
- * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
- * to look if a chip is at the address with no driver. That's a
- * dangerous thing to do with EEPROMs anyway.
- */
- cx18_call_all(cx, core, g_chip_ident, chip);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cx18_g_register(struct file *file, void *fh,
struct v4l2_dbg_register *reg)
{
struct cx18 *cx = fh2id(fh)->cx;
- if (v4l2_chip_match_host(®->match)) {
- if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
- return -EINVAL;
- reg->size = 4;
- reg->val = cx18_read_enc(cx, reg->reg);
- return 0;
- }
- /* FIXME - errors shouldn't be ignored */
- cx18_call_all(cx, core, g_register, reg);
+ if (reg->reg & 0x3)
+ return -EINVAL;
+ if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
+ return -EINVAL;
+ reg->size = 4;
+ reg->val = cx18_read_enc(cx, reg->reg);
return 0;
}
@@ -437,14 +381,11 @@
{
struct cx18 *cx = fh2id(fh)->cx;
- if (v4l2_chip_match_host(®->match)) {
- if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
- return -EINVAL;
- cx18_write_enc(cx, reg->val, reg->reg);
- return 0;
- }
- /* FIXME - errors shouldn't be ignored */
- cx18_call_all(cx, core, s_register, reg);
+ if (reg->reg & 0x3)
+ return -EINVAL;
+ if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
+ return -EINVAL;
+ cx18_write_enc(cx, reg->val, reg->reg);
return 0;
}
#endif
@@ -1162,7 +1103,6 @@
.vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap,
.vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap,
.vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap,
- .vidioc_g_chip_ident = cx18_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = cx18_g_register,
.vidioc_s_register = cx18_s_register,
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index 6dea11a..e3fc2c7 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1217,8 +1217,7 @@
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- call_all(dev, core, g_std, id);
-
+ *id = dev->tvnorm;
return 0;
}
@@ -1661,7 +1660,6 @@
};
static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
- .vidioc_querystd = vidioc_g_std,
.vidioc_g_std = vidioc_g_std,
.vidioc_s_std = vidioc_s_std,
.vidioc_enum_input = vidioc_enum_input,
@@ -1690,8 +1688,8 @@
.vidioc_log_status = vidioc_log_status,
.vidioc_querymenu = vidioc_querymenu,
.vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_chip_ident = cx23885_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_chip_info = cx23885_g_chip_info,
.vidioc_g_register = cx23885_g_register,
.vidioc_s_register = cx23885_s_register,
#endif
@@ -1702,7 +1700,6 @@
.fops = &mpeg_fops,
.ioctl_ops = &mpeg_ioctl_ops,
.tvnorms = CX23885_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
};
void cx23885_417_unregister(struct cx23885_dev *dev)
@@ -1735,7 +1732,7 @@
*vfd = *template;
snprintf(vfd->name, sizeof(vfd->name), "%s (%s)",
cx23885_boards[tsport->dev->board].name, type);
- vfd->parent = &pci->dev;
+ vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
return vfd;
}
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.c b/drivers/media/pci/cx23885/cx23885-ioctl.c
index acdb6d5..271d69d 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.c
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.c
@@ -24,93 +24,21 @@
#include "cx23885.h"
#include "cx23885-ioctl.h"
-#include <media/v4l2-chip-ident.h>
-
-int cx23885_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+int cx23885_g_chip_info(struct file *file, void *fh,
+ struct v4l2_dbg_chip_info *chip)
{
struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
- int err = 0;
- u8 rev;
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- switch (chip->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- switch (chip->match.addr) {
- case 0:
- rev = cx_read(RDR_CFG2) & 0xff;
- switch (dev->pci->device) {
- case 0x8852:
- /* rev 0x04 could be '885 or '888. Pick '888. */
- if (rev == 0x04)
- chip->ident = V4L2_IDENT_CX23888;
- else
- chip->ident = V4L2_IDENT_CX23885;
- break;
- case 0x8880:
- if (rev == 0x0e || rev == 0x0f)
- chip->ident = V4L2_IDENT_CX23887;
- else
- chip->ident = V4L2_IDENT_CX23888;
- break;
- default:
- chip->ident = V4L2_IDENT_UNKNOWN;
- break;
- }
- chip->revision = (dev->pci->device << 16) | (rev << 8) |
- (dev->hwrevision & 0xff);
- break;
- case 1:
- if (dev->v4l_device != NULL) {
- chip->ident = V4L2_IDENT_CX23417;
- chip->revision = 0;
- }
- break;
- case 2:
- /*
- * The integrated IR controller on the CX23888 is
- * host chip 2. It may not be used/initialized or sd_ir
- * may be pointing at the cx25840 subdevice for the
- * IR controller on the CX23885. Thus we find it
- * without using the dev->sd_ir pointer.
- */
- call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,
- chip);
- break;
- default:
- err = -EINVAL; /* per V4L2 spec */
- break;
- }
- break;
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
- call_all(dev, core, g_chip_ident, chip);
- break;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /*
- * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
- * to look if a chip is at the address with no driver. That's a
- * dangerous thing to do with EEPROMs anyway.
- */
- call_all(dev, core, g_chip_ident, chip);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx23885_g_host_register(struct cx23885_dev *dev,
- struct v4l2_dbg_register *reg)
-{
- if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+ if (chip->match.addr > 1)
return -EINVAL;
-
- reg->size = 4;
- reg->val = cx_read(reg->reg);
+ if (chip->match.addr == 1) {
+ if (dev->v4l_device == NULL)
+ return -EINVAL;
+ strlcpy(chip->name, "cx23417", sizeof(chip->name));
+ } else {
+ strlcpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
+ }
return 0;
}
@@ -138,32 +66,16 @@
{
struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ if (reg->match.addr > 1)
+ return -EINVAL;
+ if (reg->match.addr)
+ return cx23417_g_register(dev, reg);
- if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
- switch (reg->match.addr) {
- case 0:
- return cx23885_g_host_register(dev, reg);
- case 1:
- return cx23417_g_register(dev, reg);
- default:
- break;
- }
- }
-
- /* FIXME - any error returns should not be ignored */
- call_all(dev, core, g_register, reg);
- return 0;
-}
-
-static int cx23885_s_host_register(struct cx23885_dev *dev,
- const struct v4l2_dbg_register *reg)
-{
if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
return -EINVAL;
- cx_write(reg->reg, reg->val);
+ reg->size = 4;
+ reg->val = cx_read(reg->reg);
return 0;
}
@@ -186,22 +98,15 @@
{
struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ if (reg->match.addr > 1)
+ return -EINVAL;
+ if (reg->match.addr)
+ return cx23417_s_register(dev, reg);
- if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
- switch (reg->match.addr) {
- case 0:
- return cx23885_s_host_register(dev, reg);
- case 1:
- return cx23417_s_register(dev, reg);
- default:
- break;
- }
- }
+ if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+ return -EINVAL;
- /* FIXME - any error returns should not be ignored */
- call_all(dev, core, s_register, reg);
+ cx_write(reg->reg, reg->val);
return 0;
}
#endif
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.h b/drivers/media/pci/cx23885/cx23885-ioctl.h
index a608096..92d9f07 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.h
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.h
@@ -24,8 +24,8 @@
#ifndef _CX23885_IOCTL_H_
#define _CX23885_IOCTL_H_
-int cx23885_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip);
+int cx23885_g_chip_info(struct file *file, void *fh,
+ struct v4l2_dbg_chip_info *chip);
#ifdef CONFIG_VIDEO_ADV_DEBUG
int cx23885_g_register(struct file *file, void *fh,
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ed08c89..e33d1a7 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -1254,8 +1254,7 @@
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
dprintk(1, "%s()\n", __func__);
- call_all(dev, core, g_std, id);
-
+ *id = dev->tvnorm;
return 0;
}
@@ -1743,7 +1742,6 @@
.vidioc_dqbuf = vidioc_dqbuf,
.vidioc_s_std = vidioc_s_std,
.vidioc_g_std = vidioc_g_std,
- .vidioc_querystd = vidioc_g_std,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
@@ -1757,8 +1755,8 @@
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_g_chip_ident = cx23885_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_chip_info = cx23885_g_chip_info,
.vidioc_g_register = cx23885_g_register,
.vidioc_s_register = cx23885_s_register,
#endif
@@ -1773,7 +1771,6 @@
.fops = &video_fops,
.ioctl_ops = &video_ioctl_ops,
.tvnorms = CX23885_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
};
static const struct v4l2_file_operations radio_fops = {
@@ -1822,7 +1819,7 @@
cx23885_vbi_template = cx23885_video_template;
strcpy(cx23885_vbi_template.name, "cx23885-vbi");
- dev->tvnorm = cx23885_video_template.current_norm;
+ dev->tvnorm = V4L2_STD_NTSC_M;
/* init video dma queues */
INIT_LIST_HEAD(&dev->vidq.active);
diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index fa672fe..2c951de 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
@@ -25,7 +25,6 @@
#include <linux/slab.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/rc-core.h>
#include "cx23885.h"
@@ -131,8 +130,6 @@
struct cx23888_ir_state {
struct v4l2_subdev sd;
struct cx23885_dev *dev;
- u32 id;
- u32 rev;
struct v4l2_subdev_ir_parameters rx_params;
struct mutex rx_params_lock;
@@ -1086,23 +1083,6 @@
return 0;
}
-static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match)
-{
- return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2;
-}
-
-static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct cx23888_ir_state *state = to_state(sd);
-
- if (cx23888_ir_dbg_match(&chip->match)) {
- chip->ident = state->id;
- chip->revision = state->rev;
- }
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cx23888_ir_g_register(struct v4l2_subdev *sd,
struct v4l2_dbg_register *reg)
@@ -1110,14 +1090,10 @@
struct cx23888_ir_state *state = to_state(sd);
u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
- if (!cx23888_ir_dbg_match(®->match))
- return -EINVAL;
if ((addr & 0x3) != 0)
return -EINVAL;
if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
reg->size = 4;
reg->val = cx23888_ir_read4(state->dev, addr);
return 0;
@@ -1129,21 +1105,16 @@
struct cx23888_ir_state *state = to_state(sd);
u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
- if (!cx23888_ir_dbg_match(®->match))
- return -EINVAL;
if ((addr & 0x3) != 0)
return -EINVAL;
if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
cx23888_ir_write4(state->dev, addr, reg->val);
return 0;
}
#endif
static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = {
- .g_chip_ident = cx23888_ir_g_chip_ident,
.log_status = cx23888_ir_log_status,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cx23888_ir_g_register,
@@ -1217,8 +1188,6 @@
return -ENOMEM;
state->dev = dev;
- state->id = V4L2_IDENT_CX23888_IR;
- state->rev = 0;
sd = &state->sd;
v4l2_subdev_init(sd, &cx23888_ir_controller_ops);
diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c
index a87a0e1..e18a7ac 100644
--- a/drivers/media/pci/cx88/cx88-cards.c
+++ b/drivers/media/pci/cx88/cx88-cards.c
@@ -744,7 +744,7 @@
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
/* Some variants use a tda9874 and so need the tvaudio module. */
- .audio_chip = V4L2_IDENT_TVAUDIO,
+ .audio_chip = CX88_AUDIO_TVAUDIO,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -976,7 +976,7 @@
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .audio_chip = V4L2_IDENT_WM8775,
+ .audio_chip = CX88_AUDIO_WM8775,
.i2sinputcntl = 2,
.input = {{
.type = CX88_VMUX_DVB,
@@ -1014,7 +1014,7 @@
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .audio_chip = V4L2_IDENT_WM8775,
+ .audio_chip = CX88_AUDIO_WM8775,
.input = {{
.type = CX88_VMUX_DVB,
.vmux = 0,
@@ -1376,7 +1376,7 @@
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .audio_chip = V4L2_IDENT_WM8775,
+ .audio_chip = CX88_AUDIO_WM8775,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -1461,7 +1461,7 @@
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .audio_chip = V4L2_IDENT_WM8775,
+ .audio_chip = CX88_AUDIO_WM8775,
/*
* gpio0 as reported by Mike Crash <mike AT mikecrash.com>
*/
@@ -1929,7 +1929,7 @@
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .audio_chip = V4L2_IDENT_WM8775,
+ .audio_chip = CX88_AUDIO_WM8775,
/*
* GPIO0 (WINTV2000)
*
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c
index c8f3dcc..ad59dc9 100644
--- a/drivers/media/pci/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -1034,7 +1034,14 @@
if (NULL == vfd)
return NULL;
*vfd = *template_;
+ /*
+ * The dev pointer of v4l2_device is NULL, instead we set the
+ * video_device dev_parent pointer to the correct PCI bus device.
+ * This driver is a rare example where there is one v4l2_device,
+ * but the video nodes have different parent (PCI) devices.
+ */
vfd->v4l2_dev = &core->v4l2_dev;
+ vfd->dev_parent = &pci->dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
core->name, type, core->board.name);
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index c7a9be1..ecf21d9 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -1353,26 +1353,14 @@
return cx88_set_freq(core, f);
}
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- if (!v4l2_chip_match_host(&chip->match))
- return -EINVAL;
- chip->revision = 0;
- chip->ident = V4L2_IDENT_UNKNOWN;
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int vidioc_g_register (struct file *file, void *fh,
struct v4l2_dbg_register *reg)
{
struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
/* cx2388x has a 24-bit register space */
- reg->val = cx_read(reg->reg & 0xffffff);
+ reg->val = cx_read(reg->reg & 0xfffffc);
reg->size = 4;
return 0;
}
@@ -1382,9 +1370,7 @@
{
struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
- cx_write(reg->reg & 0xffffff, reg->val);
+ cx_write(reg->reg & 0xfffffc, reg->val);
return 0;
}
#endif
@@ -1578,7 +1564,6 @@
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
@@ -1612,7 +1597,6 @@
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
@@ -1643,7 +1627,6 @@
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
@@ -1794,7 +1777,7 @@
/* load and configure helper modules */
- if (core->board.audio_chip == V4L2_IDENT_WM8775) {
+ if (core->board.audio_chip == CX88_AUDIO_WM8775) {
struct i2c_board_info wm8775_info = {
.type = "wm8775",
.addr = 0x36 >> 1,
@@ -1815,7 +1798,7 @@
}
}
- if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
+ if (core->board.audio_chip == CX88_AUDIO_TVAUDIO) {
/* This probes for a tda9874 as is used on some
Pixelview Ultra boards. */
v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index 51ce2c0..afe0eae 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -30,7 +30,6 @@
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
-#include <media/v4l2-chip-ident.h>
#include <media/cx2341x.h>
#include <media/videobuf-dvb.h>
#include <media/ir-kbd-i2c.h>
@@ -259,6 +258,11 @@
unsigned int audioroute:4;
};
+enum cx88_audio_chip {
+ CX88_AUDIO_WM8775,
+ CX88_AUDIO_TVAUDIO,
+};
+
struct cx88_board {
const char *name;
unsigned int tuner_type;
@@ -269,7 +273,7 @@
struct cx88_input input[MAX_CX88_INPUT];
struct cx88_input radio;
enum cx88_board_type mpeg;
- unsigned int audio_chip;
+ enum cx88_audio_chip audio_chip;
int num_frontends;
/* Used for I2S devices */
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index 026767b..ab797fe 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -1241,18 +1241,7 @@
.remove = dm1105_remove,
};
-static int __init dm1105_init(void)
-{
- return pci_register_driver(&dm1105_driver);
-}
-
-static void __exit dm1105_exit(void)
-{
- pci_unregister_driver(&dm1105_driver);
-}
-
-module_init(dm1105_init);
-module_exit(dm1105_exit);
+module_pci_driver(dm1105_driver);
MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
MODULE_DESCRIPTION("SDMC DM1105 DVB driver");
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index b809bc8..c08ae3e 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -58,7 +58,6 @@
#include <linux/dma-mapping.h>
#include <media/tveeprom.h>
#include <media/saa7115.h>
-#include <media/v4l2-chip-ident.h>
#include "tuner-xc2028.h"
/* If you have already X v4l cards, then set this to X. This way
@@ -968,15 +967,10 @@
}
if (hw & IVTV_HW_SAA711X) {
- struct v4l2_dbg_chip_ident v;
-
/* determine the exact saa711x model */
itv->hw_flags &= ~IVTV_HW_SAA711X;
- v.match.type = V4L2_CHIP_MATCH_I2C_DRIVER;
- strlcpy(v.match.name, "saa7115", sizeof(v.match.name));
- ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v);
- if (v.ident == V4L2_IDENT_SAA7114) {
+ if (strstr(itv->sd_video->name, "saa7114")) {
itv->hw_flags |= IVTV_HW_SAA7114;
/* VBI is not yet supported by the saa7114 driver. */
itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE);
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 9cbbce0..807b275 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -34,7 +34,6 @@
#include "ivtv-cards.h"
#include <media/saa7127.h>
#include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-event.h>
#include <linux/dvb/audio.h>
@@ -692,31 +691,13 @@
return ret;
}
-static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(&chip->match))
- chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
- return 0;
- }
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
- /* TODO: is this correct? */
- return ivtv_call_all_err(itv, core, g_chip_ident, chip);
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)
{
volatile u8 __iomem *reg_start;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ if (reg & 0x3)
+ return -EINVAL;
if (reg >= IVTV_REG_OFFSET && reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
reg_start = itv->reg_mem - IVTV_REG_OFFSET;
else if (itv->has_cx23415 && reg >= IVTV_DECODER_OFFSET &&
@@ -738,29 +719,16 @@
{
struct ivtv *itv = fh2id(fh)->itv;
- if (v4l2_chip_match_host(®->match)) {
- reg->size = 4;
- return ivtv_itvc(itv, true, reg->reg, ®->val);
- }
- /* TODO: subdev errors should not be ignored, this should become a
- subdev helper function. */
- ivtv_call_all(itv, core, g_register, reg);
- return 0;
+ reg->size = 4;
+ return ivtv_itvc(itv, true, reg->reg, ®->val);
}
static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
{
struct ivtv *itv = fh2id(fh)->itv;
+ u64 val = reg->val;
- if (v4l2_chip_match_host(®->match)) {
- u64 val = reg->val;
-
- return ivtv_itvc(itv, false, reg->reg, &val);
- }
- /* TODO: subdev errors should not be ignored, this should become a
- subdev helper function. */
- ivtv_call_all(itv, core, s_register, reg);
- return 0;
+ return ivtv_itvc(itv, false, reg->reg, &val);
}
#endif
@@ -1914,7 +1882,6 @@
.vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
.vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
.vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
- .vidioc_g_chip_ident = ivtv_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = ivtv_g_register,
.vidioc_s_register = ivtv_s_register,
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
index 6fe9fe5..104914a 100644
--- a/drivers/media/pci/mantis/hopper_cards.c
+++ b/drivers/media/pci/mantis/hopper_cards.c
@@ -260,18 +260,7 @@
.remove = hopper_pci_remove,
};
-static int hopper_init(void)
-{
- return pci_register_driver(&hopper_pci_driver);
-}
-
-static void hopper_exit(void)
-{
- return pci_unregister_driver(&hopper_pci_driver);
-}
-
-module_init(hopper_init);
-module_exit(hopper_exit);
+module_pci_driver(hopper_pci_driver);
MODULE_DESCRIPTION("HOPPER driver");
MODULE_AUTHOR("Manu Abraham");
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
index 932a0d7..801fc55 100644
--- a/drivers/media/pci/mantis/mantis_cards.c
+++ b/drivers/media/pci/mantis/mantis_cards.c
@@ -290,18 +290,7 @@
.remove = mantis_pci_remove,
};
-static int mantis_init(void)
-{
- return pci_register_driver(&mantis_pci_driver);
-}
-
-static void mantis_exit(void)
-{
- return pci_unregister_driver(&mantis_pci_driver);
-}
-
-module_init(mantis_init);
-module_exit(mantis_exit);
+module_pci_driver(mantis_pci_driver);
MODULE_DESCRIPTION("MANTIS driver");
MODULE_AUTHOR("Manu Abraham");
diff --git a/drivers/media/pci/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c
index 07aa887..07a2074 100644
--- a/drivers/media/pci/mantis/mantis_vp1041.c
+++ b/drivers/media/pci/mantis/mantis_vp1041.c
@@ -273,7 +273,7 @@
.demod_address = 0x68, /* 0xd0 >> 1 */
.xtal_freq = 27000000,
- .inversion = IQ_SWAP_ON, /* 1 */
+ .inversion = IQ_SWAP_ON,
.lo_clk = 76500000,
.hi_clk = 99000000,
diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c
index 2290fae..4938285 100644
--- a/drivers/media/pci/pluto2/pluto2.c
+++ b/drivers/media/pci/pluto2/pluto2.c
@@ -796,18 +796,7 @@
.remove = pluto2_remove,
};
-static int __init pluto2_init(void)
-{
- return pci_register_driver(&pluto2_driver);
-}
-
-static void __exit pluto2_exit(void)
-{
- pci_unregister_driver(&pluto2_driver);
-}
-
-module_init(pluto2_init);
-module_exit(pluto2_exit);
+module_pci_driver(pluto2_driver);
MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
MODULE_DESCRIPTION("Pluto2 driver");
diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index e921108..75ce142 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -1225,20 +1225,7 @@
.id_table = pt1_id_table,
};
-
-static int __init pt1_init(void)
-{
- return pci_register_driver(&pt1_driver);
-}
-
-
-static void __exit pt1_cleanup(void)
-{
- pci_unregister_driver(&pt1_driver);
-}
-
-module_init(pt1_init);
-module_exit(pt1_cleanup);
+module_pci_driver(pt1_driver);
MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver");
diff --git a/drivers/media/pci/saa7134/saa6752hs.c b/drivers/media/pci/saa7134/saa6752hs.c
index f147b05b..8ac4b1f 100644
--- a/drivers/media/pci/saa7134/saa6752hs.c
+++ b/drivers/media/pci/saa7134/saa6752hs.c
@@ -34,8 +34,8 @@
#include <linux/types.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
#include <linux/init.h>
#include <linux/crc32.h>
@@ -92,7 +92,12 @@
struct saa6752hs_state {
struct v4l2_subdev sd;
- int chip;
+ struct v4l2_ctrl_handler hdl;
+ struct { /* video bitrate mode control cluster */
+ struct v4l2_ctrl *video_bitrate_mode;
+ struct v4l2_ctrl *video_bitrate;
+ struct v4l2_ctrl *video_bitrate_peak;
+ };
u32 revision;
int has_ac3;
struct saa6752hs_mpeg_params params;
@@ -362,314 +367,70 @@
return 0;
}
-
-static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
- struct v4l2_ext_control *ctrl)
+static int saa6752hs_try_ctrl(struct v4l2_ctrl *ctrl)
{
+ struct saa6752hs_state *h =
+ container_of(ctrl->handler, struct saa6752hs_state, hdl);
+
switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- ctrl->value = params->ts_pid_pmt;
- break;
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- ctrl->value = params->ts_pid_audio;
- break;
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- ctrl->value = params->ts_pid_video;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- ctrl->value = params->ts_pid_pcr;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- ctrl->value = params->au_encoding;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- ctrl->value = params->au_l2_bitrate;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!has_ac3)
- return -EINVAL;
- ctrl->value = params->au_ac3_bitrate;
- break;
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- ctrl->value = params->vi_aspect;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- ctrl->value = params->vi_bitrate * 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- ctrl->value = params->vi_bitrate_peak * 1000;
- break;
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- ctrl->value = params->vi_bitrate_mode;
+ /* peak bitrate shall be >= normal bitrate */
+ if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+ h->video_bitrate_peak->val < h->video_bitrate->val)
+ h->video_bitrate_peak->val = h->video_bitrate->val;
break;
- default:
- return -EINVAL;
}
return 0;
}
-static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
- struct v4l2_ext_control *ctrl, int set)
+static int saa6752hs_s_ctrl(struct v4l2_ctrl *ctrl)
{
- int old = 0, new;
-
- new = ctrl->value;
- switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- old = params->ts_pid_pmt;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pmt = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- old = params->ts_pid_audio;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_audio = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- old = params->ts_pid_video;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_video = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- old = params->ts_pid_pcr;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pcr = new;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- old = params->au_encoding;
- if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
- (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
- return -ERANGE;
- params->au_encoding = new;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- old = params->au_l2_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
- params->au_l2_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!has_ac3)
- return -EINVAL;
- old = params->au_ac3_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
- params->au_ac3_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- old = params->vi_aspect;
- if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
- new != V4L2_MPEG_VIDEO_ASPECT_4x3)
- return -ERANGE;
- if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
- new = V4L2_MPEG_VIDEO_ASPECT_4x3;
- params->vi_aspect = new;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- old = params->vi_bitrate * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- old = params->vi_bitrate_peak * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate_peak = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- old = params->vi_bitrate_mode;
- params->vi_bitrate_mode = new;
- break;
- default:
- return -EINVAL;
- }
- ctrl->value = new;
- return 0;
-}
-
-
-static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
-{
- struct saa6752hs_state *h = to_state(sd);
+ struct saa6752hs_state *h =
+ container_of(ctrl->handler, struct saa6752hs_state, hdl);
struct saa6752hs_mpeg_params *params = &h->params;
- int err;
- switch (qctrl->id) {
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
-
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L2_BITRATE_256K,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
- V4L2_MPEG_AUDIO_L2_BITRATE_256K);
-
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!h->has_ac3)
- return -EINVAL;
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
- V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 1,
- V4L2_MPEG_AUDIO_AC3_BITRATE_256K);
-
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 1,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
-
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
-
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ASPECT_4x3,
- V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
- V4L2_MPEG_VIDEO_ASPECT_4x3);
-
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
- if (err == 0 &&
- params->vi_bitrate_mode ==
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
- qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return err;
-
+ switch (ctrl->id) {
case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 1,
- V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
-
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
-
- default:
break;
- }
- return -EINVAL;
-}
-
-static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
-{
- static const u32 mpeg_audio_encoding[] = {
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- V4L2_CTRL_MENU_IDS_END
- };
- static const u32 mpeg_audio_ac3_encoding[] = {
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- V4L2_MPEG_AUDIO_ENCODING_AC3,
- V4L2_CTRL_MENU_IDS_END
- };
- static u32 mpeg_audio_l2_bitrate[] = {
- V4L2_MPEG_AUDIO_L2_BITRATE_256K,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K,
- V4L2_CTRL_MENU_IDS_END
- };
- static u32 mpeg_audio_ac3_bitrate[] = {
- V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
- V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
- V4L2_CTRL_MENU_IDS_END
- };
- struct saa6752hs_state *h = to_state(sd);
- struct v4l2_queryctrl qctrl;
- int err;
-
- qctrl.id = qmenu->id;
- err = saa6752hs_queryctrl(sd, &qctrl);
- if (err)
- return err;
- switch (qmenu->id) {
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_menu_valid_items(qmenu,
- mpeg_audio_l2_bitrate);
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!h->has_ac3)
- return -EINVAL;
- return v4l2_ctrl_query_menu_valid_items(qmenu,
- mpeg_audio_ac3_bitrate);
+ case V4L2_CID_MPEG_STREAM_PID_PMT:
+ params->ts_pid_pmt = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ params->ts_pid_audio = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ params->ts_pid_video = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PCR:
+ params->ts_pid_pcr = ctrl->val;
+ break;
case V4L2_CID_MPEG_AUDIO_ENCODING:
- return v4l2_ctrl_query_menu_valid_items(qmenu,
- h->has_ac3 ? mpeg_audio_ac3_encoding :
- mpeg_audio_encoding);
+ params->au_encoding = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ params->au_l2_bitrate = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ params->au_ac3_bitrate = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ params->vi_aspect = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ params->vi_bitrate_mode = ctrl->val;
+ params->vi_bitrate = h->video_bitrate->val / 1000;
+ params->vi_bitrate_peak = h->video_bitrate_peak->val / 1000;
+ v4l2_ctrl_activate(h->video_bitrate_peak,
+ ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+ break;
+ default:
+ return -EINVAL;
}
- return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
+ return 0;
}
static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
@@ -793,58 +554,6 @@
return 0;
}
-static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
-{
- struct saa6752hs_state *h = to_state(sd);
- struct saa6752hs_mpeg_params params;
- int i;
-
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- params = h->params;
- for (i = 0; i < ctrls->count; i++) {
- int err = handle_ctrl(h->has_ac3, ¶ms, ctrls->controls + i, set);
-
- if (err) {
- ctrls->error_idx = i;
- return err;
- }
- }
- if (set)
- h->params = params;
- return 0;
-}
-
-static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
- return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
-}
-
-static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
- return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
-}
-
-static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
- struct saa6752hs_state *h = to_state(sd);
- int i;
-
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
-
- for (i = 0; i < ctrls->count; i++) {
- int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
-
- if (err) {
- ctrls->error_idx = i;
- return err;
- }
- }
- return 0;
-}
-
static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
{
struct saa6752hs_state *h = to_state(sd);
@@ -859,10 +568,36 @@
return 0;
}
+static int saa6752hs_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
+{
+ int dist_352, dist_480, dist_720;
+
+ f->code = V4L2_MBUS_FMT_FIXED;
+
+ dist_352 = abs(f->width - 352);
+ dist_480 = abs(f->width - 480);
+ dist_720 = abs(f->width - 720);
+ if (dist_720 < dist_480) {
+ f->width = 720;
+ f->height = 576;
+ } else if (dist_480 < dist_352) {
+ f->width = 480;
+ f->height = 576;
+ } else {
+ f->width = 352;
+ if (abs(f->height - 576) < abs(f->height - 288))
+ f->height = 576;
+ else
+ f->height = 288;
+ }
+ f->field = V4L2_FIELD_INTERLACED;
+ f->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ return 0;
+}
+
static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
{
struct saa6752hs_state *h = to_state(sd);
- int dist_352, dist_480, dist_720;
if (f->code != V4L2_MBUS_FMT_FIXED)
return -EINVAL;
@@ -879,30 +614,15 @@
D1 | 720x576 | 720x480
*/
- dist_352 = abs(f->width - 352);
- dist_480 = abs(f->width - 480);
- dist_720 = abs(f->width - 720);
- if (dist_720 < dist_480) {
- f->width = 720;
- f->height = 576;
+ saa6752hs_try_mbus_fmt(sd, f);
+ if (f->width == 720)
h->video_format = SAA6752HS_VF_D1;
- } else if (dist_480 < dist_352) {
- f->width = 480;
- f->height = 576;
+ else if (f->width == 480)
h->video_format = SAA6752HS_VF_2_3_D1;
- } else {
- f->width = 352;
- if (abs(f->height - 576) <
- abs(f->height - 288)) {
- f->height = 576;
- h->video_format = SAA6752HS_VF_1_2_D1;
- } else {
- f->height = 288;
- h->video_format = SAA6752HS_VF_SIF;
- }
- }
- f->field = V4L2_FIELD_INTERLACED;
- f->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ else if (f->height == 576)
+ h->video_format = SAA6752HS_VF_1_2_D1;
+ else
+ h->video_format = SAA6752HS_VF_SIF;
return 0;
}
@@ -914,30 +634,28 @@
return 0;
}
-static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct saa6752hs_state *h = to_state(sd);
-
- return v4l2_chip_ident_i2c_client(client,
- chip, h->chip, h->revision);
-}
-
/* ----------------------------------------------------------------------- */
+static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = {
+ .try_ctrl = saa6752hs_try_ctrl,
+ .s_ctrl = saa6752hs_s_ctrl,
+};
+
static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
- .g_chip_ident = saa6752hs_g_chip_ident,
.init = saa6752hs_init,
- .queryctrl = saa6752hs_queryctrl,
- .querymenu = saa6752hs_querymenu,
- .g_ext_ctrls = saa6752hs_g_ext_ctrls,
- .s_ext_ctrls = saa6752hs_s_ext_ctrls,
- .try_ext_ctrls = saa6752hs_try_ext_ctrls,
+ .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+ .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+ .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+ .g_ctrl = v4l2_subdev_g_ctrl,
+ .s_ctrl = v4l2_subdev_s_ctrl,
+ .queryctrl = v4l2_subdev_queryctrl,
+ .querymenu = v4l2_subdev_querymenu,
.s_std = saa6752hs_s_std,
};
static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
.s_mbus_fmt = saa6752hs_s_mbus_fmt,
+ .try_mbus_fmt = saa6752hs_try_mbus_fmt,
.g_mbus_fmt = saa6752hs_g_mbus_fmt,
};
@@ -951,6 +669,7 @@
{
struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
struct v4l2_subdev *sd;
+ struct v4l2_ctrl_handler *hdl;
u8 addr = 0x13;
u8 data[12];
@@ -963,15 +682,88 @@
i2c_master_send(client, &addr, 1);
i2c_master_recv(client, data, sizeof(data));
- h->chip = V4L2_IDENT_SAA6752HS;
h->revision = (data[8] << 8) | data[9];
h->has_ac3 = 0;
if (h->revision == 0x0206) {
- h->chip = V4L2_IDENT_SAA6752HS_AC3;
h->has_ac3 = 1;
- v4l_info(client, "support AC-3\n");
+ v4l_info(client, "supports AC-3\n");
}
h->params = param_defaults;
+
+ hdl = &h->hdl;
+ v4l2_ctrl_handler_init(hdl, 14);
+ v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_AUDIO_ENCODING,
+ h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ 0x0d, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
+
+ v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+ V4L2_MPEG_AUDIO_L2_BITRATE_384K,
+ ~((1 << V4L2_MPEG_AUDIO_L2_BITRATE_256K) |
+ (1 << V4L2_MPEG_AUDIO_L2_BITRATE_384K)),
+ V4L2_MPEG_AUDIO_L2_BITRATE_256K);
+
+ if (h->has_ac3)
+ v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
+ ~((1 << V4L2_MPEG_AUDIO_AC3_BITRATE_256K) |
+ (1 << V4L2_MPEG_AUDIO_AC3_BITRATE_384K)),
+ V4L2_MPEG_AUDIO_AC3_BITRATE_256K);
+
+ v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
+ ~(1 << V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000),
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+
+ v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_ENCODING,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
+ ~(1 << V4L2_MPEG_VIDEO_ENCODING_MPEG_2),
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
+
+ v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_ASPECT,
+ V4L2_MPEG_VIDEO_ASPECT_16x9, 0x01,
+ V4L2_MPEG_VIDEO_ASPECT_4x3);
+
+ h->video_bitrate_peak = v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+ 1000000, 27000000, 1000, 8000000);
+
+ v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_STREAM_TYPE,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
+ ~(1 << V4L2_MPEG_STREAM_TYPE_MPEG2_TS),
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
+
+ h->video_bitrate_mode = v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+ h->video_bitrate = v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_BITRATE, 1000000, 27000000, 1000, 6000000);
+ v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_STREAM_PID_PMT, 0, (1 << 14) - 1, 1, 16);
+ v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_STREAM_PID_AUDIO, 0, (1 << 14) - 1, 1, 260);
+ v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_STREAM_PID_VIDEO, 0, (1 << 14) - 1, 1, 256);
+ v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+ V4L2_CID_MPEG_STREAM_PID_PCR, 0, (1 << 14) - 1, 1, 259);
+ sd->ctrl_handler = hdl;
+ if (hdl->error) {
+ int err = hdl->error;
+
+ v4l2_ctrl_handler_free(hdl);
+ kfree(h);
+ return err;
+ }
+ v4l2_ctrl_cluster(3, &h->video_bitrate_mode);
+ v4l2_ctrl_handler_setup(hdl);
h->standard = 0; /* Assume 625 input lines */
return 0;
}
@@ -981,6 +773,7 @@
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
+ v4l2_ctrl_handler_free(&to_state(sd)->hdl);
kfree(to_state(sd));
return 0;
}
@@ -1002,11 +795,3 @@
};
module_i2c_driver(saa6752hs_driver);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
index 66a7081..3022eb2 100644
--- a/drivers/media/pci/saa7134/saa7134-empress.c
+++ b/drivers/media/pci/saa7134/saa7134-empress.c
@@ -28,7 +28,6 @@
#include <media/saa6752hs.h>
#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
/* ------------------------------------------------------------------ */
@@ -213,7 +212,7 @@
strlcpy(f->description, "MPEG TS", sizeof(f->description));
f->pixelformat = V4L2_PIX_FMT_MPEG;
-
+ f->flags = V4L2_FMT_FLAG_COMPRESSED;
return 0;
}
@@ -228,6 +227,8 @@
v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.priv = 0;
return 0;
}
@@ -244,6 +245,8 @@
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.priv = 0;
return 0;
}
@@ -252,9 +255,16 @@
struct v4l2_format *f)
{
struct saa7134_dev *dev = file->private_data;
+ struct v4l2_mbus_framefmt mbus_fmt;
+
+ v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
+ saa_call_all(dev, video, try_mbus_fmt, &mbus_fmt);
+ v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.priv = 0;
return 0;
}
@@ -413,21 +423,6 @@
return saa_call_empress(dev, core, querymenu, c);
}
-static int empress_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct saa7134_dev *dev = file->private_data;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
- !strcmp(chip->match.name, "saa6752hs"))
- return saa_call_empress(dev, core, g_chip_ident, chip);
- if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR)
- return saa_call_empress(dev, core, g_chip_ident, chip);
- return -EINVAL;
-}
-
static int empress_s_std(struct file *file, void *priv, v4l2_std_id id)
{
struct saa7134_dev *dev = file->private_data;
@@ -475,7 +470,6 @@
.vidioc_querymenu = empress_querymenu,
.vidioc_g_ctrl = empress_g_ctrl,
.vidioc_s_ctrl = empress_s_ctrl,
- .vidioc_g_chip_ident = empress_g_chip_ident,
.vidioc_s_std = empress_s_std,
.vidioc_g_std = empress_g_std,
};
@@ -488,7 +482,6 @@
.ioctl_ops = &ts_ioctl_ops,
.tvnorms = SAA7134_NORMS,
- .current_norm = V4L2_STD_PAL,
};
static void empress_signal_update(struct work_struct *work)
@@ -518,7 +511,7 @@
if (NULL == dev->empress_dev)
return -ENOMEM;
*(dev->empress_dev) = saa7134_empress_template;
- dev->empress_dev->parent = &dev->pci->dev;
+ dev->empress_dev->v4l2_dev = &dev->v4l2_dev;
dev->empress_dev->release = video_device_release;
snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
"%s empress (%s)", dev->name,
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index cc40938..e12bbd8 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -825,20 +825,22 @@
return 0;
}
-static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
+static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win, bool try)
{
enum v4l2_field field;
int maxw, maxh;
- if (NULL == dev->ovbuf.base)
+ if (!try && (dev->ovbuf.base == NULL || dev->ovfmt == NULL))
return -EINVAL;
- if (NULL == dev->ovfmt)
- return -EINVAL;
- if (win->w.width < 48 || win->w.height < 32)
- return -EINVAL;
- if (win->clipcount > 2048)
- return -EINVAL;
+ if (win->w.width < 48)
+ win->w.width = 48;
+ if (win->w.height < 32)
+ win->w.height = 32;
+ if (win->clipcount > 8)
+ win->clipcount = 8;
+ win->chromakey = 0;
+ win->global_alpha = 0;
field = win->field;
maxw = dev->crop_current.width;
maxh = dev->crop_current.height;
@@ -853,10 +855,9 @@
case V4L2_FIELD_BOTTOM:
maxh = maxh / 2;
break;
- case V4L2_FIELD_INTERLACED:
- break;
default:
- return -EINVAL;
+ field = V4L2_FIELD_INTERLACED;
+ break;
}
win->field = field;
@@ -872,20 +873,20 @@
unsigned long base,control,bpl;
int err;
- err = verify_preview(dev,&fh->win);
+ err = verify_preview(dev, &dev->win, false);
if (0 != err)
return err;
- dev->ovfield = fh->win.field;
+ dev->ovfield = dev->win.field;
dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
- fh->win.w.width,fh->win.w.height,
- fh->win.w.left,fh->win.w.top,
- dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
+ dev->win.w.width, dev->win.w.height,
+ dev->win.w.left, dev->win.w.top,
+ dev->ovfmt->name, v4l2_field_names[dev->ovfield]);
/* setup window + clipping */
- set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
+ set_size(dev, TASK_B, dev->win.w.width, dev->win.w.height,
V4L2_FIELD_HAS_BOTH(dev->ovfield));
- setup_clipping(dev,fh->clips,fh->nclips,
+ setup_clipping(dev, dev->clips, dev->nclips,
V4L2_FIELD_HAS_BOTH(dev->ovfield));
if (dev->ovfmt->yuv)
saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
@@ -895,8 +896,8 @@
/* dma: setup channel 1 (= Video Task B) */
base = (unsigned long)dev->ovbuf.base;
- base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
- base += dev->ovfmt->depth/8 * fh->win.w.left;
+ base += dev->ovbuf.fmt.bytesperline * dev->win.w.top;
+ base += dev->ovfmt->depth/8 * dev->win.w.left;
bpl = dev->ovbuf.fmt.bytesperline;
control = SAA7134_RS_CONTROL_BURST_16;
if (dev->ovfmt->bswap)
@@ -1024,38 +1025,38 @@
int err;
/* sanity checks */
- if (NULL == fh->fmt)
+ if (NULL == dev->fmt)
return -EINVAL;
- if (fh->width < 48 ||
- fh->height < 32 ||
- fh->width/4 > dev->crop_current.width ||
- fh->height/4 > dev->crop_current.height ||
- fh->width > dev->crop_bounds.width ||
- fh->height > dev->crop_bounds.height)
+ if (dev->width < 48 ||
+ dev->height < 32 ||
+ dev->width/4 > dev->crop_current.width ||
+ dev->height/4 > dev->crop_current.height ||
+ dev->width > dev->crop_bounds.width ||
+ dev->height > dev->crop_bounds.height)
return -EINVAL;
- size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+ size = (dev->width * dev->height * dev->fmt->depth) >> 3;
if (0 != buf->vb.baddr && buf->vb.bsize < size)
return -EINVAL;
dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
- vb->i,fh->width,fh->height,size,v4l2_field_names[field],
- fh->fmt->name);
- if (buf->vb.width != fh->width ||
- buf->vb.height != fh->height ||
+ vb->i, dev->width, dev->height, size, v4l2_field_names[field],
+ dev->fmt->name);
+ if (buf->vb.width != dev->width ||
+ buf->vb.height != dev->height ||
buf->vb.size != size ||
buf->vb.field != field ||
- buf->fmt != fh->fmt) {
+ buf->fmt != dev->fmt) {
saa7134_dma_free(q,buf);
}
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
- buf->vb.width = fh->width;
- buf->vb.height = fh->height;
+ buf->vb.width = dev->width;
+ buf->vb.height = dev->height;
buf->vb.size = size;
buf->vb.field = field;
- buf->fmt = fh->fmt;
+ buf->fmt = dev->fmt;
buf->pt = &fh->pt_cap;
dev->video_q.curr = NULL;
@@ -1082,8 +1083,9 @@
buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
{
struct saa7134_fh *fh = q->priv_data;
+ struct saa7134_dev *dev = fh->dev;
- *size = fh->fmt->depth * fh->width * fh->height >> 3;
+ *size = dev->fmt->depth * dev->width * dev->height >> 3;
if (0 == *count)
*count = gbuffers;
*count = saa7134_buffer_count(*size,*count);
@@ -1287,15 +1289,17 @@
/* ------------------------------------------------------------------ */
-static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
+static struct videobuf_queue *saa7134_queue(struct file *file)
{
- struct videobuf_queue* q = NULL;
+ struct video_device *vdev = video_devdata(file);
+ struct saa7134_fh *fh = file->private_data;
+ struct videobuf_queue *q = NULL;
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ switch (vdev->vfl_type) {
+ case VFL_TYPE_GRABBER:
q = &fh->cap;
break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case VFL_TYPE_VBI:
q = &fh->vbi;
break;
default:
@@ -1304,12 +1308,14 @@
return q;
}
-static int saa7134_resource(struct saa7134_fh *fh)
+static int saa7134_resource(struct file *file)
{
- if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ struct video_device *vdev = video_devdata(file);
+
+ if (vdev->vfl_type == VFL_TYPE_GRABBER)
return RESOURCE_VIDEO;
- if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ if (vdev->vfl_type == VFL_TYPE_VBI)
return RESOURCE_VBI;
BUG();
@@ -1321,23 +1327,6 @@
struct video_device *vdev = video_devdata(file);
struct saa7134_dev *dev = video_drvdata(file);
struct saa7134_fh *fh;
- enum v4l2_buf_type type = 0;
- int radio = 0;
-
- switch (vdev->vfl_type) {
- case VFL_TYPE_GRABBER:
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- case VFL_TYPE_VBI:
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- case VFL_TYPE_RADIO:
- radio = 1;
- break;
- }
-
- dprintk("open dev=%s radio=%d type=%s\n", video_device_node_name(vdev),
- radio, v4l2_type_names[type]);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
@@ -1347,11 +1336,6 @@
v4l2_fh_init(&fh->fh, vdev);
file->private_data = fh;
fh->dev = dev;
- fh->radio = radio;
- fh->type = type;
- fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
- fh->width = 720;
- fh->height = 576;
videobuf_queue_sg_init(&fh->cap, &video_qops,
&dev->pci->dev, &dev->slock,
@@ -1368,7 +1352,7 @@
saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
- if (fh->radio) {
+ if (vdev->vfl_type == VFL_TYPE_RADIO) {
/* switch to radio mode */
saa7134_tvaudio_setinput(dev,&card(dev).radio);
saa_call_all(dev, tuner, s_radio);
@@ -1384,19 +1368,20 @@
static ssize_t
video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
+ struct video_device *vdev = video_devdata(file);
struct saa7134_fh *fh = file->private_data;
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ switch (vdev->vfl_type) {
+ case VFL_TYPE_GRABBER:
if (res_locked(fh->dev,RESOURCE_VIDEO))
return -EBUSY;
- return videobuf_read_one(saa7134_queue(fh),
+ return videobuf_read_one(saa7134_queue(file),
data, count, ppos,
file->f_flags & O_NONBLOCK);
- case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case VFL_TYPE_VBI:
if (!res_get(fh->dev,fh,RESOURCE_VBI))
return -EBUSY;
- return videobuf_read_stream(saa7134_queue(fh),
+ return videobuf_read_stream(saa7134_queue(file),
data, count, ppos, 1,
file->f_flags & O_NONBLOCK);
break;
@@ -1409,11 +1394,12 @@
static unsigned int
video_poll(struct file *file, struct poll_table_struct *wait)
{
+ struct video_device *vdev = video_devdata(file);
struct saa7134_fh *fh = file->private_data;
struct videobuf_buffer *buf = NULL;
unsigned int rc = 0;
- if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
+ if (vdev->vfl_type == VFL_TYPE_VBI)
return videobuf_poll_stream(file, &fh->vbi, wait);
if (res_check(fh,RESOURCE_VIDEO)) {
@@ -1451,6 +1437,7 @@
static int video_release(struct file *file)
{
+ struct video_device *vdev = video_devdata(file);
struct saa7134_fh *fh = file->private_data;
struct saa7134_dev *dev = fh->dev;
struct saa6588_command cmd;
@@ -1489,7 +1476,7 @@
saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
saa_call_all(dev, core, s_power, 0);
- if (fh->radio)
+ if (vdev->vfl_type == VFL_TYPE_RADIO)
saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
/* free stuff */
@@ -1507,9 +1494,7 @@
static int video_mmap(struct file *file, struct vm_area_struct * vma)
{
- struct saa7134_fh *fh = file->private_data;
-
- return videobuf_mmap_mapper(saa7134_queue(fh), vma);
+ return videobuf_mmap_mapper(saa7134_queue(file), vma);
}
static ssize_t radio_read(struct file *file, char __user *data,
@@ -1570,15 +1555,18 @@
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
+ struct saa7134_dev *dev = fh->dev;
- f->fmt.pix.width = fh->width;
- f->fmt.pix.height = fh->height;
+ f->fmt.pix.width = dev->width;
+ f->fmt.pix.height = dev->height;
f->fmt.pix.field = fh->cap.field;
- f->fmt.pix.pixelformat = fh->fmt->fourcc;
+ f->fmt.pix.pixelformat = dev->fmt->fourcc;
f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fh->fmt->depth) >> 3;
+ (f->fmt.pix.width * dev->fmt->depth) >> 3;
f->fmt.pix.sizeimage =
f->fmt.pix.height * f->fmt.pix.bytesperline;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ f->fmt.pix.priv = 0;
return 0;
}
@@ -1586,14 +1574,33 @@
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
+ struct saa7134_dev *dev = fh->dev;
+ struct v4l2_clip __user *clips = f->fmt.win.clips;
+ u32 clipcount = f->fmt.win.clipcount;
+ int err = 0;
+ int i;
if (saa7134_no_overlay > 0) {
printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
return -EINVAL;
}
- f->fmt.win = fh->win;
+ mutex_lock(&dev->lock);
+ f->fmt.win = dev->win;
+ f->fmt.win.clips = clips;
+ if (clips == NULL)
+ clipcount = 0;
+ if (dev->nclips < clipcount)
+ clipcount = dev->nclips;
+ f->fmt.win.clipcount = clipcount;
- return 0;
+ for (i = 0; !err && i < clipcount; i++) {
+ if (copy_to_user(&f->fmt.win.clips[i].c, &dev->clips[i].c,
+ sizeof(struct v4l2_rect)))
+ err = -EFAULT;
+ }
+ mutex_unlock(&dev->lock);
+
+ return err;
}
static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
@@ -1623,10 +1630,9 @@
case V4L2_FIELD_BOTTOM:
maxh = maxh / 2;
break;
- case V4L2_FIELD_INTERLACED:
- break;
default:
- return -EINVAL;
+ field = V4L2_FIELD_INTERLACED;
+ break;
}
f->fmt.pix.field = field;
@@ -1643,6 +1649,8 @@
(f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage =
f->fmt.pix.height * f->fmt.pix.bytesperline;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ f->fmt.pix.priv = 0;
return 0;
}
@@ -1658,22 +1666,25 @@
return -EINVAL;
}
- return verify_preview(dev, &f->fmt.win);
+ if (f->fmt.win.clips == NULL)
+ f->fmt.win.clipcount = 0;
+ return verify_preview(dev, &f->fmt.win, true);
}
static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
+ struct saa7134_dev *dev = fh->dev;
int err;
err = saa7134_try_fmt_vid_cap(file, priv, f);
if (0 != err)
return err;
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
+ dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ dev->width = f->fmt.pix.width;
+ dev->height = f->fmt.pix.height;
fh->cap.field = f->fmt.pix.field;
return 0;
}
@@ -1690,20 +1701,19 @@
printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
return -EINVAL;
}
- err = verify_preview(dev, &f->fmt.win);
+ if (f->fmt.win.clips == NULL)
+ f->fmt.win.clipcount = 0;
+ err = verify_preview(dev, &f->fmt.win, true);
if (0 != err)
return err;
mutex_lock(&dev->lock);
- fh->win = f->fmt.win;
- fh->nclips = f->fmt.win.clipcount;
+ dev->win = f->fmt.win;
+ dev->nclips = f->fmt.win.clipcount;
- if (fh->nclips > 8)
- fh->nclips = 8;
-
- if (copy_from_user(fh->clips, f->fmt.win.clips,
- sizeof(struct v4l2_clip)*fh->nclips)) {
+ if (copy_from_user(dev->clips, f->fmt.win.clips,
+ sizeof(struct v4l2_clip) * dev->nclips)) {
mutex_unlock(&dev->lock);
return -EFAULT;
}
@@ -2057,7 +2067,6 @@
if (0 != f->tuner)
return -EINVAL;
- f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
saa_call_all(dev, tuner, g_frequency, f);
return 0;
@@ -2071,10 +2080,6 @@
if (0 != f->tuner)
return -EINVAL;
- if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
- if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
- return -EINVAL;
mutex_lock(&dev->lock);
saa_call_all(dev, tuner, s_frequency, f);
@@ -2186,27 +2191,23 @@
static int saa7134_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p)
{
- struct saa7134_fh *fh = priv;
- return videobuf_reqbufs(saa7134_queue(fh), p);
+ return videobuf_reqbufs(saa7134_queue(file), p);
}
static int saa7134_querybuf(struct file *file, void *priv,
struct v4l2_buffer *b)
{
- struct saa7134_fh *fh = priv;
- return videobuf_querybuf(saa7134_queue(fh), b);
+ return videobuf_querybuf(saa7134_queue(file), b);
}
static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
- struct saa7134_fh *fh = priv;
- return videobuf_qbuf(saa7134_queue(fh), b);
+ return videobuf_qbuf(saa7134_queue(file), b);
}
static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
- struct saa7134_fh *fh = priv;
- return videobuf_dqbuf(saa7134_queue(fh), b,
+ return videobuf_dqbuf(saa7134_queue(file), b,
file->f_flags & O_NONBLOCK);
}
@@ -2215,7 +2216,7 @@
{
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
- int res = saa7134_resource(fh);
+ int res = saa7134_resource(file);
if (!res_get(dev, fh, res))
return -EBUSY;
@@ -2227,11 +2228,11 @@
* Unfortunately, I lack register-level documentation to check the
* Linux FIFO setup and confirm the perfect value.
*/
- pm_qos_add_request(&fh->qos_request,
+ pm_qos_add_request(&dev->qos_request,
PM_QOS_CPU_DMA_LATENCY,
20);
- return videobuf_streamon(saa7134_queue(fh));
+ return videobuf_streamon(saa7134_queue(file));
}
static int saa7134_streamoff(struct file *file, void *priv,
@@ -2240,11 +2241,11 @@
int err;
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
- int res = saa7134_resource(fh);
+ int res = saa7134_resource(file);
- pm_qos_remove_request(&fh->qos_request);
+ pm_qos_remove_request(&dev->qos_request);
- err = videobuf_streamoff(saa7134_queue(fh));
+ err = videobuf_streamoff(saa7134_queue(file));
if (err < 0)
return err;
res_free(dev, fh, res);
@@ -2258,9 +2259,7 @@
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
- reg->val = saa_readb(reg->reg);
+ reg->val = saa_readb(reg->reg & 0xffffff);
reg->size = 1;
return 0;
}
@@ -2271,9 +2270,7 @@
struct saa7134_fh *fh = priv;
struct saa7134_dev *dev = fh->dev;
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
- saa_writeb(reg->reg&0xffffff, reg->val);
+ saa_writeb(reg->reg & 0xffffff, reg->val);
return 0;
}
#endif
@@ -2287,9 +2284,7 @@
if (0 != t->index)
return -EINVAL;
- memset(t, 0, sizeof(*t));
strcpy(t->name, "Radio");
- t->type = V4L2_TUNER_RADIO;
saa_call_all(dev, tuner, g_tuner, t);
t->audmode &= V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO;
@@ -2443,7 +2438,6 @@
.fops = &video_fops,
.ioctl_ops = &video_ioctl_ops,
.tvnorms = SAA7134_NORMS,
- .current_norm = V4L2_STD_PAL,
};
struct video_device saa7134_radio_template = {
@@ -2480,6 +2474,16 @@
dev->video_q.timeout.function = saa7134_buffer_timeout;
dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
dev->video_q.dev = dev;
+ dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
+ dev->width = 720;
+ dev->height = 576;
+ dev->win.w.width = dev->width;
+ dev->win.w.height = dev->height;
+ dev->win.field = V4L2_FIELD_INTERLACED;
+ dev->ovbuf.fmt.width = dev->width;
+ dev->ovbuf.fmt.height = dev->height;
+ dev->ovbuf.fmt.pixelformat = dev->fmt->fourcc;
+ dev->ovbuf.fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
if (saa7134_boards[dev->board].video_out)
saa7134_videoport_init(dev);
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index d2ad16c..8d1453a 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -471,19 +471,9 @@
struct saa7134_fh {
struct v4l2_fh fh;
struct saa7134_dev *dev;
- unsigned int radio;
- enum v4l2_buf_type type;
unsigned int resources;
- struct pm_qos_request qos_request;
-
- /* video overlay */
- struct v4l2_window win;
- struct v4l2_clip clips[8];
- unsigned int nclips;
/* video capture */
- struct saa7134_format *fmt;
- unsigned int width,height;
struct videobuf_queue cap;
struct saa7134_pgtable pt_cap;
@@ -592,12 +582,19 @@
struct saa7134_format *ovfmt;
unsigned int ovenable;
enum v4l2_field ovfield;
+ struct v4l2_window win;
+ struct v4l2_clip clips[8];
+ unsigned int nclips;
+
/* video+ts+vbi capture */
struct saa7134_dmaqueue video_q;
struct saa7134_dmaqueue vbi_q;
unsigned int video_fieldcount;
unsigned int vbi_fieldcount;
+ struct saa7134_format *fmt;
+ unsigned int width, height;
+ struct pm_qos_request qos_request;
/* various v4l controls */
struct saa7134_tvnorm *tvnorm; /* video */
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c
index 71e8bea..33abe33 100644
--- a/drivers/media/pci/saa7146/mxb.c
+++ b/drivers/media/pci/saa7146/mxb.c
@@ -669,14 +669,10 @@
{
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (v4l2_chip_match_host(®->match)) {
- reg->val = saa7146_read(dev, reg->reg);
- reg->size = 4;
- return 0;
- }
- call_all(dev, core, g_register, reg);
+ if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
+ return -EINVAL;
+ reg->val = saa7146_read(dev, reg->reg);
+ reg->size = 4;
return 0;
}
@@ -684,13 +680,10 @@
{
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (v4l2_chip_match_host(®->match)) {
- saa7146_write(dev, reg->reg, reg->val);
- return 0;
- }
- return call_all(dev, core, s_register, reg);
+ if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
+ return -EINVAL;
+ saa7146_write(dev, reg->reg, reg->val);
+ return 0;
}
#endif
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index 7618fda..d37ee37 100644
--- a/drivers/media/pci/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -1196,6 +1196,12 @@
if (NULL == dev)
return -ENOMEM;
+ err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+ if (err < 0) {
+ dev_err(&pci_dev->dev, "v4l2_device_register failed\n");
+ goto fail_free;
+ }
+
/* pci init */
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
@@ -1367,6 +1373,7 @@
fail_irq:
saa7164_dev_unregister(dev);
fail_free:
+ v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev);
return err;
}
@@ -1439,6 +1446,7 @@
mutex_unlock(&devlist);
saa7164_dev_unregister(dev);
+ v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev);
}
diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c
index 0b74fb2..9266965 100644
--- a/drivers/media/pci/saa7164/saa7164-encoder.c
+++ b/drivers/media/pci/saa7164/saa7164-encoder.c
@@ -228,6 +228,7 @@
return -EINVAL;
port->encodernorm = saa7164_tvnorms[i];
+ port->std = id;
/* Update the audio decoder while is not running in
* auto detect mode.
@@ -239,6 +240,15 @@
return 0;
}
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+ struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_port *port = fh->port;
+
+ *id = port->std;
+ return 0;
+}
+
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *i)
{
@@ -1288,46 +1298,9 @@
.unlocked_ioctl = video_ioctl2,
};
-static int saa7164_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
- struct saa7164_dev *dev = port->dev;
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int saa7164_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
- struct saa7164_dev *dev = port->dev;
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- return 0;
-}
-
-static int saa7164_s_register(struct file *file, void *fh,
- const struct v4l2_dbg_register *reg)
-{
- struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
- struct saa7164_dev *dev = port->dev;
- dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- return 0;
-}
-#endif
-
static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
.vidioc_s_std = vidioc_s_std,
+ .vidioc_g_std = vidioc_g_std,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
@@ -1346,11 +1319,6 @@
.vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
.vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_chip_ident = saa7164_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = saa7164_g_register,
- .vidioc_s_register = saa7164_s_register,
-#endif
};
static struct video_device saa7164_mpeg_template = {
@@ -1359,7 +1327,6 @@
.ioctl_ops = &mpeg_ioctl_ops,
.minor = -1,
.tvnorms = SAA7164_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
};
static struct video_device *saa7164_encoder_alloc(
@@ -1381,7 +1348,7 @@
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
type, saa7164_boards[dev->board].name);
- vfd->parent = &pci->dev;
+ vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
return vfd;
}
@@ -1426,6 +1393,7 @@
port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
port->encoder_params.refdist = 1;
port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE;
+ port->std = V4L2_STD_NTSC_M;
if (port->encodernorm.id & V4L2_STD_525_60)
port->height = 480;
diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c
index da224eb..6e025fe 100644
--- a/drivers/media/pci/saa7164/saa7164-vbi.c
+++ b/drivers/media/pci/saa7164/saa7164-vbi.c
@@ -200,6 +200,7 @@
return -EINVAL;
port->encodernorm = saa7164_tvnorms[i];
+ port->std = id;
/* Update the audio decoder while is not running in
* auto detect mode.
@@ -211,6 +212,15 @@
return 0;
}
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+ struct saa7164_encoder_fh *fh = file->private_data;
+ struct saa7164_port *port = fh->port;
+
+ *id = port->std;
+ return 0;
+}
+
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *i)
{
@@ -1236,6 +1246,7 @@
static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
.vidioc_s_std = vidioc_s_std,
+ .vidioc_g_std = vidioc_g_std,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
@@ -1254,15 +1265,6 @@
.vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
.vidioc_queryctrl = vidioc_queryctrl,
-#if 0
- .vidioc_g_chip_ident = saa7164_g_chip_ident,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-#if 0
- .vidioc_g_register = saa7164_g_register,
- .vidioc_s_register = saa7164_s_register,
-#endif
-#endif
.vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt,
.vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt,
.vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt,
@@ -1274,7 +1276,6 @@
.ioctl_ops = &vbi_ioctl_ops,
.minor = -1,
.tvnorms = SAA7164_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
};
static struct video_device *saa7164_vbi_alloc(
@@ -1296,7 +1297,7 @@
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
type, saa7164_boards[dev->board].name);
- vfd->parent = &pci->dev;
+ vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
return vfd;
}
@@ -1333,6 +1334,7 @@
goto failed;
}
+ port->std = V4L2_STD_NTSC_M;
video_set_drvdata(port->v4l_device, port);
result = video_register_device(port->v4l_device,
VFL_TYPE_VBI, -1);
diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h
index 437284e..8b29e89 100644
--- a/drivers/media/pci/saa7164/saa7164.h
+++ b/drivers/media/pci/saa7164/saa7164.h
@@ -63,7 +63,7 @@
#include <dmxdev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-device.h>
#include "saa7164-reg.h"
#include "saa7164-types.h"
@@ -376,6 +376,7 @@
/* Encoder */
/* Defaults established in saa7164-encoder.c */
struct saa7164_tvnorm encodernorm;
+ v4l2_std_id std;
u32 height;
u32 width;
u32 freq;
@@ -427,6 +428,8 @@
struct list_head devlist;
atomic_t refcount;
+ struct v4l2_device v4l2_dev;
+
/* pci stuff */
struct pci_dev *pci;
unsigned char pci_rev, pci_lat;
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index 7005695..77edc11 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -1047,7 +1047,8 @@
ret = sta2x11_vip_init_controls(vip);
if (ret)
goto free_mem;
- if (v4l2_device_register(&pdev->dev, &vip->v4l2_dev))
+ ret = v4l2_device_register(&pdev->dev, &vip->v4l2_dev);
+ if (ret)
goto free_mem;
dev_dbg(&pdev->dev, "BAR #0 at 0x%lx 0x%lx irq %d\n",
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
index 1f8b1bb..0ba3875 100644
--- a/drivers/media/pci/ttpci/budget-av.c
+++ b/drivers/media/pci/ttpci/budget-av.c
@@ -1128,7 +1128,7 @@
// .ts_pfbit_toggle = STB0899_MPEG_NORMAL, /* DirecTV, MPEG toggling seq */
.xtal_freq = 27000000,
- .inversion = IQ_SWAP_OFF, /* 1 */
+ .inversion = IQ_SWAP_OFF,
.lo_clk = 76500000,
.hi_clk = 90000000,
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 98e5241..0acf920 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -1280,7 +1280,7 @@
.demod_address = 0x68,
.xtal_freq = 27000000,
- .inversion = IQ_SWAP_ON, /* 1 */
+ .inversion = IQ_SWAP_ON,
.lo_clk = 76500000,
.hi_clk = 99000000,
diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c
index bb53d24..923d59a 100644
--- a/drivers/media/pci/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -1050,7 +1050,7 @@
* Now add the template and register the device unit.
*/
memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
- zr->video_dev->parent = &zr->pci_dev->dev;
+ zr->video_dev->v4l2_dev = &zr->v4l2_dev;
strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
/* It's not a mem2mem device, but you can both capture and output from
one and the same device. This should really be split up into two
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c
index d133c30..e7e9840 100644
--- a/drivers/media/pci/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -1456,29 +1456,6 @@
return -EINVAL;
}
- if (norm == V4L2_STD_ALL) {
- unsigned int status = 0;
- v4l2_std_id std = 0;
-
- decoder_call(zr, video, querystd, &std);
- decoder_call(zr, core, s_std, std);
-
- /* let changes come into effect */
- ssleep(2);
-
- decoder_call(zr, video, g_input_status, &status);
- if (status & V4L2_IN_ST_NO_SIGNAL) {
- dprintk(1,
- KERN_ERR
- "%s: %s - no norm detected\n",
- ZR_DEVNAME(zr), __func__);
- /* reset norm */
- decoder_call(zr, core, s_std, zr->norm);
- return -EIO;
- }
-
- norm = std;
- }
if (norm & V4L2_STD_SECAM)
zr->timing = zr->card.tvn[2];
else if (norm & V4L2_STD_NTSC)
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 25eaf61..08de865 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -36,7 +36,7 @@
config VIDEO_SH_VOU
tristate "SuperH VOU video output driver"
depends on MEDIA_CAMERA_SUPPORT
- depends on VIDEO_DEV && ARCH_SHMOBILE
+ depends on VIDEO_DEV && ARCH_SHMOBILE && I2C
select VIDEOBUF_DMA_CONTIG
help
Support for the Video Output Unit (VOU) on SuperH SoCs.
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c
index 0e55b08..7f838c6 100644
--- a/drivers/media/platform/blackfin/bfin_capture.c
+++ b/drivers/media/platform/blackfin/bfin_capture.c
@@ -32,7 +32,6 @@
#include <linux/time.h>
#include <linux/types.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -649,18 +648,30 @@
return 0;
}
+static int bcap_enum_dv_timings(struct file *file, void *priv,
+ struct v4l2_enum_dv_timings *timings)
+{
+ struct bcap_device *bcap_dev = video_drvdata(file);
+
+ return v4l2_subdev_call(bcap_dev->sd, video,
+ enum_dv_timings, timings);
+}
+
+static int bcap_query_dv_timings(struct file *file, void *priv,
+ struct v4l2_dv_timings *timings)
+{
+ struct bcap_device *bcap_dev = video_drvdata(file);
+
+ return v4l2_subdev_call(bcap_dev->sd, video,
+ query_dv_timings, timings);
+}
+
static int bcap_g_dv_timings(struct file *file, void *priv,
struct v4l2_dv_timings *timings)
{
struct bcap_device *bcap_dev = video_drvdata(file);
- int ret;
- ret = v4l2_subdev_call(bcap_dev->sd, video,
- g_dv_timings, timings);
- if (ret < 0)
- return ret;
-
- bcap_dev->dv_timings = *timings;
+ *timings = bcap_dev->dv_timings;
return 0;
}
@@ -864,41 +875,6 @@
return v4l2_subdev_call(bcap_dev->sd, video, s_parm, a);
}
-static int bcap_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- return v4l2_subdev_call(bcap_dev->sd, core,
- g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int bcap_dbg_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return v4l2_subdev_call(bcap_dev->sd, core,
- g_register, reg);
-}
-
-static int bcap_dbg_s_register(struct file *file, void *priv,
- const struct v4l2_dbg_register *reg)
-{
- struct bcap_device *bcap_dev = video_drvdata(file);
-
- return v4l2_subdev_call(bcap_dev->sd, core,
- s_register, reg);
-}
-#endif
-
static int bcap_log_status(struct file *file, void *priv)
{
struct bcap_device *bcap_dev = video_drvdata(file);
@@ -921,6 +897,8 @@
.vidioc_g_std = bcap_g_std,
.vidioc_s_dv_timings = bcap_s_dv_timings,
.vidioc_g_dv_timings = bcap_g_dv_timings,
+ .vidioc_query_dv_timings = bcap_query_dv_timings,
+ .vidioc_enum_dv_timings = bcap_enum_dv_timings,
.vidioc_reqbufs = bcap_reqbufs,
.vidioc_querybuf = bcap_querybuf,
.vidioc_qbuf = bcap_qbuf,
@@ -929,11 +907,6 @@
.vidioc_streamoff = bcap_streamoff,
.vidioc_g_parm = bcap_g_parm,
.vidioc_s_parm = bcap_s_parm,
- .vidioc_g_chip_ident = bcap_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = bcap_dbg_g_register,
- .vidioc_s_register = bcap_dbg_s_register,
-#endif
.vidioc_log_status = bcap_log_status,
};
@@ -960,7 +933,7 @@
int ret;
config = pdev->dev.platform_data;
- if (!config) {
+ if (!config || !config->num_inputs) {
v4l2_err(pdev->dev.driver, "Unable to get board config\n");
return -ENODEV;
}
@@ -1031,7 +1004,9 @@
q->mem_ops = &vb2_dma_contig_memops;
q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- vb2_queue_init(q);
+ ret = vb2_queue_init(q);
+ if (ret)
+ goto err_free_handler;
mutex_init(&bcap_dev->mutex);
init_completion(&bcap_dev->comp);
@@ -1067,11 +1042,6 @@
NULL);
if (bcap_dev->sd) {
int i;
- if (!config->num_inputs) {
- v4l2_err(&bcap_dev->v4l2_dev,
- "Unable to work without input\n");
- goto err_unreg_vdev;
- }
/* update tvnorms from the sub devices */
for (i = 0; i < config->num_inputs; i++)
@@ -1079,6 +1049,7 @@
} else {
v4l2_err(&bcap_dev->v4l2_dev,
"Unable to register sub device\n");
+ ret = -ENODEV;
goto err_unreg_vdev;
}
diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c
index 01b5b50..15e9c2b 100644
--- a/drivers/media/platform/blackfin/ppi.c
+++ b/drivers/media/platform/blackfin/ppi.c
@@ -266,6 +266,18 @@
bfin_write32(®->vcnt, params->height);
if (params->int_mask)
bfin_write32(®->imsk, params->int_mask & 0xFF);
+ if (ppi->ppi_control & PORT_DIR) {
+ u32 hsync_width, vsync_width, vsync_period;
+
+ hsync_width = params->hsync
+ * params->bpp / params->dlen;
+ vsync_width = params->vsync * samples_per_line;
+ vsync_period = samples_per_line * params->frame;
+ bfin_write32(®->fs1_wlhb, hsync_width);
+ bfin_write32(®->fs1_paspl, samples_per_line);
+ bfin_write32(®->fs2_wlvb, vsync_width);
+ bfin_write32(®->fs2_palpf, vsync_period);
+ }
break;
}
default:
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
index 9d1481a..df4ada88 100644
--- a/drivers/media/platform/coda.c
+++ b/drivers/media/platform/coda.c
@@ -49,16 +49,14 @@
#define CODA_MAX_FRAMEBUFFERS 2
-#define MAX_W 720
-#define MAX_H 576
-#define CODA_MAX_FRAME_SIZE 0x90000
+#define MAX_W 8192
+#define MAX_H 8192
+#define CODA_MAX_FRAME_SIZE 0x100000
#define FMO_SLICE_SAVE_BUF_SIZE (32)
#define CODA_DEFAULT_GAMMA 4096
#define MIN_W 176
#define MIN_H 144
-#define MAX_W 720
-#define MAX_H 576
#define S_ALIGN 1 /* multiple of 2 */
#define W_ALIGN 1 /* multiple of 2 */
@@ -67,7 +65,7 @@
#define fh_to_ctx(__fh) container_of(__fh, struct coda_ctx, fh)
static int coda_debug;
-module_param(coda_debug, int, 0);
+module_param(coda_debug, int, 0644);
MODULE_PARM_DESC(coda_debug, "Debug level (0-1)");
enum {
@@ -75,11 +73,6 @@
V4L2_M2M_DST = 1,
};
-enum coda_fmt_type {
- CODA_FMT_ENC,
- CODA_FMT_RAW,
-};
-
enum coda_inst_type {
CODA_INST_ENCODER,
CODA_INST_DECODER,
@@ -93,14 +86,21 @@
struct coda_fmt {
char *name;
u32 fourcc;
- enum coda_fmt_type type;
+};
+
+struct coda_codec {
+ u32 mode;
+ u32 src_fourcc;
+ u32 dst_fourcc;
+ u32 max_w;
+ u32 max_h;
};
struct coda_devtype {
char *firmware;
enum coda_product product;
- struct coda_fmt *formats;
- unsigned int num_formats;
+ struct coda_codec *codecs;
+ unsigned int num_codecs;
size_t workbuf_size;
};
@@ -109,7 +109,7 @@
unsigned int width;
unsigned int height;
unsigned int sizeimage;
- struct coda_fmt *fmt;
+ unsigned int fourcc;
};
struct coda_aux_buf {
@@ -137,12 +137,12 @@
spinlock_t irqlock;
struct mutex dev_mutex;
+ struct mutex coda_mutex;
struct v4l2_m2m_dev *m2m_dev;
struct vb2_alloc_ctx *alloc_ctx;
struct list_head instances;
unsigned long instance_mask;
struct delayed_work timeout;
- struct completion done;
};
struct coda_params {
@@ -164,11 +164,12 @@
struct coda_dev *dev;
struct list_head list;
int aborting;
- int rawstreamon;
- int compstreamon;
+ int streamon_out;
+ int streamon_cap;
u32 isequence;
struct coda_q_data q_data[2];
enum coda_inst_type inst_type;
+ struct coda_codec *codec;
enum v4l2_colorspace colorspace;
struct coda_params params;
struct v4l2_m2m_ctx *m2m_ctx;
@@ -257,62 +258,89 @@
}
/*
- * Add one array of supported formats for each version of Coda:
- * i.MX27 -> codadx6
- * i.MX51 -> coda7
- * i.MX6 -> coda960
+ * Array of all formats supported by any version of Coda:
*/
-static struct coda_fmt codadx6_formats[] = {
+static struct coda_fmt coda_formats[] = {
{
- .name = "YUV 4:2:0 Planar",
+ .name = "YUV 4:2:0 Planar, YCbCr",
.fourcc = V4L2_PIX_FMT_YUV420,
- .type = CODA_FMT_RAW,
+ },
+ {
+ .name = "YUV 4:2:0 Planar, YCrCb",
+ .fourcc = V4L2_PIX_FMT_YVU420,
},
{
.name = "H264 Encoded Stream",
.fourcc = V4L2_PIX_FMT_H264,
- .type = CODA_FMT_ENC,
},
{
.name = "MPEG4 Encoded Stream",
.fourcc = V4L2_PIX_FMT_MPEG4,
- .type = CODA_FMT_ENC,
},
};
-static struct coda_fmt coda7_formats[] = {
- {
- .name = "YUV 4:2:0 Planar",
- .fourcc = V4L2_PIX_FMT_YUV420,
- .type = CODA_FMT_RAW,
- },
- {
- .name = "H264 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_H264,
- .type = CODA_FMT_ENC,
- },
- {
- .name = "MPEG4 Encoded Stream",
- .fourcc = V4L2_PIX_FMT_MPEG4,
- .type = CODA_FMT_ENC,
- },
+#define CODA_CODEC(mode, src_fourcc, dst_fourcc, max_w, max_h) \
+ { mode, src_fourcc, dst_fourcc, max_w, max_h }
+
+/*
+ * Arrays of codecs supported by each given version of Coda:
+ * i.MX27 -> codadx6
+ * i.MX5x -> coda7
+ * i.MX6 -> coda960
+ * Use V4L2_PIX_FMT_YUV420 as placeholder for all supported YUV 4:2:0 variants
+ */
+static struct coda_codec codadx6_codecs[] = {
+ CODA_CODEC(CODADX6_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 720, 576),
+ CODA_CODEC(CODADX6_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 720, 576),
};
-static struct coda_fmt *find_format(struct coda_dev *dev, struct v4l2_format *f)
+static struct coda_codec coda7_codecs[] = {
+ CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1280, 720),
+ CODA_CODEC(CODA7_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1280, 720),
+};
+
+static bool coda_format_is_yuv(u32 fourcc)
{
- struct coda_fmt *formats = dev->devtype->formats;
- int num_formats = dev->devtype->num_formats;
- unsigned int k;
+ switch (fourcc) {
+ case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
+ return true;
+ default:
+ return false;
+ }
+}
- for (k = 0; k < num_formats; k++) {
- if (formats[k].fourcc == f->fmt.pix.pixelformat)
+/*
+ * Normalize all supported YUV 4:2:0 formats to the value used in the codec
+ * tables.
+ */
+static u32 coda_format_normalize_yuv(u32 fourcc)
+{
+ return coda_format_is_yuv(fourcc) ? V4L2_PIX_FMT_YUV420 : fourcc;
+}
+
+static struct coda_codec *coda_find_codec(struct coda_dev *dev, int src_fourcc,
+ int dst_fourcc)
+{
+ struct coda_codec *codecs = dev->devtype->codecs;
+ int num_codecs = dev->devtype->num_codecs;
+ int k;
+
+ src_fourcc = coda_format_normalize_yuv(src_fourcc);
+ dst_fourcc = coda_format_normalize_yuv(dst_fourcc);
+ if (src_fourcc == dst_fourcc)
+ return NULL;
+
+ for (k = 0; k < num_codecs; k++) {
+ if (codecs[k].src_fourcc == src_fourcc &&
+ codecs[k].dst_fourcc == dst_fourcc)
break;
}
- if (k == num_formats)
+ if (k == num_codecs)
return NULL;
- return &formats[k];
+ return &codecs[k];
}
/*
@@ -323,7 +351,7 @@
{
strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver));
strlcpy(cap->card, CODA_NAME, sizeof(cap->card));
- strlcpy(cap->bus_info, CODA_NAME, sizeof(cap->bus_info));
+ strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info));
/*
* This is only a mem-to-mem video device. The capture and output
* device capability flags are left only for backward compatibility
@@ -337,17 +365,34 @@
}
static int enum_fmt(void *priv, struct v4l2_fmtdesc *f,
- enum coda_fmt_type type)
+ enum v4l2_buf_type type)
{
struct coda_ctx *ctx = fh_to_ctx(priv);
- struct coda_dev *dev = ctx->dev;
- struct coda_fmt *formats = dev->devtype->formats;
+ struct coda_codec *codecs = ctx->dev->devtype->codecs;
+ struct coda_fmt *formats = coda_formats;
struct coda_fmt *fmt;
- int num_formats = dev->devtype->num_formats;
- int i, num = 0;
+ int num_codecs = ctx->dev->devtype->num_codecs;
+ int num_formats = ARRAY_SIZE(coda_formats);
+ int i, k, num = 0;
for (i = 0; i < num_formats; i++) {
- if (formats[i].type == type) {
+ /* Both uncompressed formats are always supported */
+ if (coda_format_is_yuv(formats[i].fourcc)) {
+ if (num == f->index)
+ break;
+ ++num;
+ continue;
+ }
+ /* Compressed formats may be supported, check the codec list */
+ for (k = 0; k < num_codecs; k++) {
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ formats[i].fourcc == codecs[k].dst_fourcc)
+ break;
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ formats[i].fourcc == codecs[k].src_fourcc)
+ break;
+ }
+ if (k < num_codecs) {
if (num == f->index)
break;
++num;
@@ -368,13 +413,13 @@
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- return enum_fmt(priv, f, CODA_FMT_ENC);
+ return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE);
}
static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- return enum_fmt(priv, f, CODA_FMT_RAW);
+ return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT);
}
static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
@@ -390,10 +435,10 @@
q_data = get_q_data(ctx, f->type);
f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.pixelformat = q_data->fmt->fourcc;
+ f->fmt.pix.pixelformat = q_data->fourcc;
f->fmt.pix.width = q_data->width;
f->fmt.pix.height = q_data->height;
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
+ if (coda_format_is_yuv(f->fmt.pix.pixelformat))
f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
else /* encoded formats h.264/mpeg4 */
f->fmt.pix.bytesperline = 0;
@@ -404,8 +449,9 @@
return 0;
}
-static int vidioc_try_fmt(struct coda_dev *dev, struct v4l2_format *f)
+static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f)
{
+ unsigned int max_w, max_h;
enum v4l2_field field;
field = f->fmt.pix.field;
@@ -418,12 +464,21 @@
* if any of the dimensions is unsupported */
f->fmt.pix.field = field;
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
- v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
- W_ALIGN, &f->fmt.pix.height,
- MIN_H, MAX_H, H_ALIGN, S_ALIGN);
- f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
- f->fmt.pix.sizeimage = f->fmt.pix.width *
+ if (codec) {
+ max_w = codec->max_w;
+ max_h = codec->max_h;
+ } else {
+ max_w = MAX_W;
+ max_h = MAX_H;
+ }
+ v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w,
+ W_ALIGN, &f->fmt.pix.height,
+ MIN_H, max_h, H_ALIGN, S_ALIGN);
+
+ if (coda_format_is_yuv(f->fmt.pix.pixelformat)) {
+ /* Frame stride must be multiple of 8 */
+ f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8);
+ f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
f->fmt.pix.height * 3 / 2;
} else { /*encoded formats h.264/mpeg4 */
f->fmt.pix.bytesperline = 0;
@@ -436,57 +491,38 @@
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- int ret;
- struct coda_fmt *fmt;
struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_codec *codec = NULL;
- fmt = find_format(ctx->dev, f);
- /*
- * Since decoding support is not implemented yet do not allow
- * CODA_FMT_RAW formats in the capture interface.
- */
- if (!fmt || !(fmt->type == CODA_FMT_ENC))
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
+ /* Determine codec by the encoded format */
+ codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420,
+ f->fmt.pix.pixelformat);
f->fmt.pix.colorspace = ctx->colorspace;
- ret = vidioc_try_fmt(ctx->dev, f);
- if (ret < 0)
- return ret;
-
- return 0;
+ return vidioc_try_fmt(codec, f);
}
static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
struct coda_ctx *ctx = fh_to_ctx(priv);
- struct coda_fmt *fmt;
- int ret;
+ struct coda_codec *codec;
- fmt = find_format(ctx->dev, f);
- /*
- * Since decoding support is not implemented yet do not allow
- * CODA_FMT formats in the capture interface.
- */
- if (!fmt || !(fmt->type == CODA_FMT_RAW))
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+ /* Determine codec by encoded format, returns NULL if raw or invalid */
+ codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat,
+ V4L2_PIX_FMT_YUV420);
if (!f->fmt.pix.colorspace)
f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
- ret = vidioc_try_fmt(ctx->dev, f);
- if (ret < 0)
- return ret;
-
- return 0;
+ return vidioc_try_fmt(codec, f);
}
static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
{
struct coda_q_data *q_data;
struct vb2_queue *vq;
- int ret;
vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
if (!vq)
@@ -501,18 +537,14 @@
return -EBUSY;
}
- ret = vidioc_try_fmt(ctx->dev, f);
- if (ret)
- return ret;
-
- q_data->fmt = find_format(ctx->dev, f);
+ q_data->fourcc = f->fmt.pix.pixelformat;
q_data->width = f->fmt.pix.width;
q_data->height = f->fmt.pix.height;
q_data->sizeimage = f->fmt.pix.sizeimage;
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"Setting format for type %d, wxh: %dx%d, fmt: %d\n",
- f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
+ f->type, q_data->width, q_data->height, q_data->fourcc);
return 0;
}
@@ -520,13 +552,14 @@
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
int ret;
ret = vidioc_try_fmt_vid_cap(file, priv, f);
if (ret)
return ret;
- return vidioc_s_fmt(fh_to_ctx(priv), f);
+ return vidioc_s_fmt(ctx, f);
}
static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
@@ -569,6 +602,14 @@
return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
}
+static int vidioc_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+ struct coda_ctx *ctx = fh_to_ctx(priv);
+
+ return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
+}
+
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
struct coda_ctx *ctx = fh_to_ctx(priv);
@@ -617,6 +658,7 @@
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
+ .vidioc_expbuf = vidioc_expbuf,
.vidioc_dqbuf = vidioc_dqbuf,
.vidioc_create_bufs = vidioc_create_bufs,
@@ -639,11 +681,13 @@
u32 pic_stream_buffer_addr, pic_stream_buffer_size;
u32 dst_fourcc;
+ mutex_lock(&dev->coda_mutex);
+
src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- dst_fourcc = q_data_dst->fmt->fourcc;
+ dst_fourcc = q_data_dst->fourcc;
src_buf->v4l2_buf.sequence = ctx->isequence;
dst_buf->v4l2_buf.sequence = ctx->isequence;
@@ -725,9 +769,20 @@
picture_y = vb2_dma_contig_plane_dma_addr(src_buf, 0);
- picture_cb = picture_y + q_data_src->width * q_data_src->height;
- picture_cr = picture_cb + q_data_src->width / 2 *
- q_data_src->height / 2;
+ switch (q_data_src->fourcc) {
+ case V4L2_PIX_FMT_YVU420:
+ /* Switch Cb and Cr for YVU420 format */
+ picture_cr = picture_y + q_data_src->width * q_data_src->height;
+ picture_cb = picture_cr + q_data_src->width / 2 *
+ q_data_src->height / 2;
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ default:
+ picture_cb = picture_y + q_data_src->width * q_data_src->height;
+ picture_cr = picture_cb + q_data_src->width / 2 *
+ q_data_src->height / 2;
+ break;
+ }
coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
@@ -748,7 +803,6 @@
/* 1 second timeout in case CODA locks up */
schedule_delayed_work(&dev->timeout, HZ);
- INIT_COMPLETION(dev->done);
coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
}
@@ -767,6 +821,12 @@
return 0;
}
+ if (ctx->aborting) {
+ v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+ "not ready: aborting\n");
+ return 0;
+ }
+
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"job ready\n");
return 1;
@@ -775,14 +835,11 @@
static void coda_job_abort(void *priv)
{
struct coda_ctx *ctx = priv;
- struct coda_dev *dev = ctx->dev;
ctx->aborting = 1;
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"Aborting task\n");
-
- v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
}
static void coda_lock(void *m2m_priv)
@@ -809,7 +866,12 @@
static void set_default_params(struct coda_ctx *ctx)
{
- struct coda_dev *dev = ctx->dev;
+ int max_w;
+ int max_h;
+
+ ctx->codec = &ctx->dev->devtype->codecs[0];
+ max_w = ctx->codec->max_w;
+ max_h = ctx->codec->max_h;
ctx->params.codec_mode = CODA_MODE_INVALID;
ctx->colorspace = V4L2_COLORSPACE_REC709;
@@ -817,13 +879,13 @@
ctx->aborting = 0;
/* Default formats for output and input queues */
- ctx->q_data[V4L2_M2M_SRC].fmt = &dev->devtype->formats[0];
- ctx->q_data[V4L2_M2M_DST].fmt = &dev->devtype->formats[1];
- ctx->q_data[V4L2_M2M_SRC].width = MAX_W;
- ctx->q_data[V4L2_M2M_SRC].height = MAX_H;
- ctx->q_data[V4L2_M2M_SRC].sizeimage = (MAX_W * MAX_H * 3) / 2;
- ctx->q_data[V4L2_M2M_DST].width = MAX_W;
- ctx->q_data[V4L2_M2M_DST].height = MAX_H;
+ ctx->q_data[V4L2_M2M_SRC].fourcc = ctx->codec->src_fourcc;
+ ctx->q_data[V4L2_M2M_DST].fourcc = ctx->codec->dst_fourcc;
+ ctx->q_data[V4L2_M2M_SRC].width = max_w;
+ ctx->q_data[V4L2_M2M_SRC].height = max_h;
+ ctx->q_data[V4L2_M2M_SRC].sizeimage = (max_w * max_h * 3) / 2;
+ ctx->q_data[V4L2_M2M_DST].width = max_w;
+ ctx->q_data[V4L2_M2M_DST].height = max_h;
ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
}
@@ -868,8 +930,6 @@
return -EINVAL;
}
- vb2_set_plane_payload(vb, 0, q_data->sizeimage);
-
return 0;
}
@@ -906,21 +966,34 @@
}
}
+static void coda_parabuf_write(struct coda_ctx *ctx, int index, u32 value)
+{
+ struct coda_dev *dev = ctx->dev;
+ u32 *p = ctx->parabuf.vaddr;
+
+ if (dev->devtype->product == CODA_DX6)
+ p[index] = value;
+ else
+ p[index ^ 1] = value;
+}
+
static int coda_alloc_framebuffers(struct coda_ctx *ctx, struct coda_q_data *q_data, u32 fourcc)
{
struct coda_dev *dev = ctx->dev;
int height = q_data->height;
- int width = q_data->width;
- u32 *p;
+ dma_addr_t paddr;
+ int ysize;
int i;
+ ysize = round_up(q_data->width, 8) * height;
+
/* Allocate frame buffers */
ctx->num_internal_frames = CODA_MAX_FRAMEBUFFERS;
for (i = 0; i < ctx->num_internal_frames; i++) {
ctx->internal_frames[i].size = q_data->sizeimage;
if (fourcc == V4L2_PIX_FMT_H264 && dev->devtype->product != CODA_DX6)
- ctx->internal_frames[i].size += width / 2 * height / 2;
+ ctx->internal_frames[i].size += ysize/4;
ctx->internal_frames[i].vaddr = dma_alloc_coherent(
&dev->plat_dev->dev, ctx->internal_frames[i].size,
&ctx->internal_frames[i].paddr, GFP_KERNEL);
@@ -931,32 +1004,14 @@
}
/* Register frame buffers in the parameter buffer */
- p = ctx->parabuf.vaddr;
+ for (i = 0; i < ctx->num_internal_frames; i++) {
+ paddr = ctx->internal_frames[i].paddr;
+ coda_parabuf_write(ctx, i * 3 + 0, paddr); /* Y */
+ coda_parabuf_write(ctx, i * 3 + 1, paddr + ysize); /* Cb */
+ coda_parabuf_write(ctx, i * 3 + 2, paddr + ysize + ysize/4); /* Cr */
- if (dev->devtype->product == CODA_DX6) {
- for (i = 0; i < ctx->num_internal_frames; i++) {
- p[i * 3] = ctx->internal_frames[i].paddr; /* Y */
- p[i * 3 + 1] = p[i * 3] + width * height; /* Cb */
- p[i * 3 + 2] = p[i * 3 + 1] + width / 2 * height / 2; /* Cr */
- }
- } else {
- for (i = 0; i < ctx->num_internal_frames; i += 2) {
- p[i * 3 + 1] = ctx->internal_frames[i].paddr; /* Y */
- p[i * 3] = p[i * 3 + 1] + width * height; /* Cb */
- p[i * 3 + 3] = p[i * 3] + (width / 2) * (height / 2); /* Cr */
-
- if (fourcc == V4L2_PIX_FMT_H264)
- p[96 + i + 1] = p[i * 3 + 3] + (width / 2) * (height / 2);
-
- if (i + 1 < ctx->num_internal_frames) {
- p[i * 3 + 2] = ctx->internal_frames[i+1].paddr; /* Y */
- p[i * 3 + 5] = p[i * 3 + 2] + width * height ; /* Cb */
- p[i * 3 + 4] = p[i * 3 + 5] + (width / 2) * (height / 2); /* Cr */
-
- if (fourcc == V4L2_PIX_FMT_H264)
- p[96 + i] = p[i * 3 + 4] + (width / 2) * (height / 2);
- }
- }
+ if (dev->devtype->product != CODA_DX6 && fourcc == V4L2_PIX_FMT_H264)
+ coda_parabuf_write(ctx, 96 + i, ctx->internal_frames[i].paddr + ysize + ysize/4 + ysize/4);
}
return 0;
@@ -980,6 +1035,28 @@
return nal_size;
}
+static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
+ int header_code, u8 *header, int *size)
+{
+ struct coda_dev *dev = ctx->dev;
+ int ret;
+
+ coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0),
+ CODA_CMD_ENC_HEADER_BB_START);
+ coda_write(dev, vb2_plane_size(buf, 0), CODA_CMD_ENC_HEADER_BB_SIZE);
+ coda_write(dev, header_code, CODA_CMD_ENC_HEADER_CODE);
+ ret = coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER);
+ if (ret < 0) {
+ v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
+ return ret;
+ }
+ *size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
+ coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+ memcpy(header, vb2_plane_vaddr(buf, 0), *size);
+
+ return 0;
+}
+
static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct coda_ctx *ctx = vb2_get_drv_priv(q);
@@ -990,43 +1067,38 @@
struct vb2_buffer *buf;
u32 dst_fourcc;
u32 value;
- int ret;
+ int ret = 0;
if (count < 1)
return -EINVAL;
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- ctx->rawstreamon = 1;
+ ctx->streamon_out = 1;
else
- ctx->compstreamon = 1;
-
- /* Don't start the coda unless both queues are on */
- if (!(ctx->rawstreamon & ctx->compstreamon))
- return 0;
-
- if (coda_isbusy(dev))
- if (wait_for_completion_interruptible_timeout(&dev->done, HZ) <= 0)
- return -EBUSY;
-
- ctx->gopcounter = ctx->params.gop_size - 1;
+ ctx->streamon_cap = 1;
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ if (ctx->streamon_out) {
+ if (coda_format_is_yuv(q_data_src->fourcc))
+ ctx->inst_type = CODA_INST_ENCODER;
+ else
+ ctx->inst_type = CODA_INST_DECODER;
+ }
+
+ /* Don't start the coda unless both queues are on */
+ if (!(ctx->streamon_out & ctx->streamon_cap))
+ return 0;
+
+ ctx->gopcounter = ctx->params.gop_size - 1;
buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
bitstream_size = q_data_dst->sizeimage;
- dst_fourcc = q_data_dst->fmt->fourcc;
+ dst_fourcc = q_data_dst->fourcc;
- /* Find out whether coda must encode or decode */
- if (q_data_src->fmt->type == CODA_FMT_RAW &&
- q_data_dst->fmt->type == CODA_FMT_ENC) {
- ctx->inst_type = CODA_INST_ENCODER;
- } else if (q_data_src->fmt->type == CODA_FMT_ENC &&
- q_data_dst->fmt->type == CODA_FMT_RAW) {
- ctx->inst_type = CODA_INST_DECODER;
- v4l2_err(v4l2_dev, "decoding not supported.\n");
- return -EINVAL;
- } else {
+ ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
+ q_data_dst->fourcc);
+ if (!ctx->codec) {
v4l2_err(v4l2_dev, "couldn't tell instance type.\n");
return -EINVAL;
}
@@ -1035,6 +1107,9 @@
v4l2_err(v4l2_dev, "coda is not initialized.\n");
return -EFAULT;
}
+
+ mutex_lock(&dev->coda_mutex);
+
coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
coda_write(dev, bitstream_buf, CODA_REG_BIT_RD_PTR(ctx->idx));
coda_write(dev, bitstream_buf, CODA_REG_BIT_WR_PTR(ctx->idx));
@@ -1057,38 +1132,31 @@
switch (dev->devtype->product) {
case CODA_DX6:
value = (q_data_src->width & CODADX6_PICWIDTH_MASK) << CODADX6_PICWIDTH_OFFSET;
+ value |= (q_data_src->height & CODADX6_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
break;
default:
value = (q_data_src->width & CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET;
+ value |= (q_data_src->height & CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
}
- value |= (q_data_src->height & CODA_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE);
coda_write(dev, ctx->params.framerate,
CODA_CMD_ENC_SEQ_SRC_F_RATE);
+ ctx->params.codec_mode = ctx->codec->mode;
switch (dst_fourcc) {
case V4L2_PIX_FMT_MPEG4:
- if (dev->devtype->product == CODA_DX6)
- ctx->params.codec_mode = CODADX6_MODE_ENCODE_MP4;
- else
- ctx->params.codec_mode = CODA7_MODE_ENCODE_MP4;
-
coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
coda_write(dev, 0, CODA_CMD_ENC_SEQ_MP4_PARA);
break;
case V4L2_PIX_FMT_H264:
- if (dev->devtype->product == CODA_DX6)
- ctx->params.codec_mode = CODADX6_MODE_ENCODE_H264;
- else
- ctx->params.codec_mode = CODA7_MODE_ENCODE_H264;
-
coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
coda_write(dev, 0, CODA_CMD_ENC_SEQ_264_PARA);
break;
default:
v4l2_err(v4l2_dev,
"dst format (0x%08x) invalid.\n", dst_fourcc);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
switch (ctx->params.slice_mode) {
@@ -1129,8 +1197,14 @@
value = (CODA_DEFAULT_GAMMA & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET;
coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_GAMMA);
- value = (CODA_DEFAULT_GAMMA > 0) << CODA_OPTION_GAMMA_OFFSET;
- value |= (0 & CODA_OPTION_SLICEREPORT_MASK) << CODA_OPTION_SLICEREPORT_OFFSET;
+ if (CODA_DEFAULT_GAMMA > 0) {
+ if (dev->devtype->product == CODA_DX6)
+ value = 1 << CODADX6_OPTION_GAMMA_OFFSET;
+ else
+ value = 1 << CODA7_OPTION_GAMMA_OFFSET;
+ } else {
+ value = 0;
+ }
coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
if (dst_fourcc == V4L2_PIX_FMT_H264) {
@@ -1145,17 +1219,23 @@
}
}
- if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
+ ret = coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT);
+ if (ret < 0) {
v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT timeout\n");
- return -ETIMEDOUT;
+ goto out;
}
- if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0)
- return -EFAULT;
+ if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0) {
+ v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT failed\n");
+ ret = -EFAULT;
+ goto out;
+ }
ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ v4l2_err(v4l2_dev, "failed to allocate framebuffers\n");
+ goto out;
+ }
coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM);
coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
@@ -1167,9 +1247,10 @@
coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
}
- if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
+ ret = coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF);
+ if (ret < 0) {
v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
- return -ETIMEDOUT;
+ goto out;
}
/* Save stream headers */
@@ -1180,33 +1261,22 @@
* Get SPS in the first frame and copy it to an
* intermediate buffer.
*/
- coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
- coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
- coda_write(dev, CODA_HEADER_H264_SPS, CODA_CMD_ENC_HEADER_CODE);
- if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
- v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
- return -ETIMEDOUT;
- }
- ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
- coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
- memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
- ctx->vpu_header_size[0]);
+ ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_SPS,
+ &ctx->vpu_header[0][0],
+ &ctx->vpu_header_size[0]);
+ if (ret < 0)
+ goto out;
/*
* Get PPS in the first frame and copy it to an
* intermediate buffer.
*/
- coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
- coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
- coda_write(dev, CODA_HEADER_H264_PPS, CODA_CMD_ENC_HEADER_CODE);
- if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
- v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
- return -ETIMEDOUT;
- }
- ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
- coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
- memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
- ctx->vpu_header_size[1]);
+ ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_PPS,
+ &ctx->vpu_header[1][0],
+ &ctx->vpu_header_size[1]);
+ if (ret < 0)
+ goto out;
+
/*
* Length of H.264 headers is variable and thus it might not be
* aligned for the coda to append the encoded frame. In that is
@@ -1222,48 +1292,32 @@
* Get VOS in the first frame and copy it to an
* intermediate buffer
*/
- coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
- coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
- coda_write(dev, CODA_HEADER_MP4V_VOS, CODA_CMD_ENC_HEADER_CODE);
- if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
- v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
- return -ETIMEDOUT;
- }
- ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
- coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
- memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
- ctx->vpu_header_size[0]);
+ ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOS,
+ &ctx->vpu_header[0][0],
+ &ctx->vpu_header_size[0]);
+ if (ret < 0)
+ goto out;
- coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
- coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
- coda_write(dev, CODA_HEADER_MP4V_VIS, CODA_CMD_ENC_HEADER_CODE);
- if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
- v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
- return -ETIMEDOUT;
- }
- ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
- coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
- memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
- ctx->vpu_header_size[1]);
+ ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VIS,
+ &ctx->vpu_header[1][0],
+ &ctx->vpu_header_size[1]);
+ if (ret < 0)
+ goto out;
- coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
- coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
- coda_write(dev, CODA_HEADER_MP4V_VOL, CODA_CMD_ENC_HEADER_CODE);
- if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
- v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
- return -ETIMEDOUT;
- }
- ctx->vpu_header_size[2] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
- coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
- memcpy(&ctx->vpu_header[2][0], vb2_plane_vaddr(buf, 0),
- ctx->vpu_header_size[2]);
+ ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOL,
+ &ctx->vpu_header[2][0],
+ &ctx->vpu_header_size[2]);
+ if (ret < 0)
+ goto out;
break;
default:
/* No more formats need to save headers at the moment */
break;
}
- return 0;
+out:
+ mutex_unlock(&dev->coda_mutex);
+ return ret;
}
static int coda_stop_streaming(struct vb2_queue *q)
@@ -1274,26 +1328,20 @@
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"%s: output\n", __func__);
- ctx->rawstreamon = 0;
+ ctx->streamon_out = 0;
} else {
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"%s: capture\n", __func__);
- ctx->compstreamon = 0;
+ ctx->streamon_cap = 0;
}
/* Don't stop the coda unless both queues are off */
- if (ctx->rawstreamon || ctx->compstreamon)
+ if (ctx->streamon_out || ctx->streamon_cap)
return 0;
- if (coda_isbusy(dev)) {
- if (wait_for_completion_interruptible_timeout(&dev->done, HZ) <= 0) {
- v4l2_warn(&dev->v4l2_dev,
- "%s: timeout, sending SEQ_END anyway\n", __func__);
- }
- }
-
cancel_delayed_work(&dev->timeout);
+ mutex_lock(&dev->coda_mutex);
v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
"%s: sent command 'SEQ_END' to coda\n", __func__);
if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) {
@@ -1301,6 +1349,7 @@
"CODA_COMMAND_SEQ_END failed\n");
return -ETIMEDOUT;
}
+ mutex_unlock(&dev->coda_mutex);
coda_free_framebuffers(ctx);
@@ -1431,7 +1480,7 @@
int ret;
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
src_vq->drv_priv = ctx;
src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
src_vq->ops = &coda_qops;
@@ -1443,7 +1492,7 @@
return ret;
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+ dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
dst_vq->drv_priv = ctx;
dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
dst_vq->ops = &coda_qops;
@@ -1484,7 +1533,7 @@
ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
&coda_queue_init);
if (IS_ERR(ctx->m2m_ctx)) {
- int ret = PTR_ERR(ctx->m2m_ctx);
+ ret = PTR_ERR(ctx->m2m_ctx);
v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n",
__func__, ret);
@@ -1596,12 +1645,14 @@
ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
if (ctx == NULL) {
v4l2_err(&dev->v4l2_dev, "Instance released before the end of transaction\n");
+ mutex_unlock(&dev->coda_mutex);
return IRQ_HANDLED;
}
if (ctx->aborting) {
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"task has been aborted\n");
+ mutex_unlock(&dev->coda_mutex);
return IRQ_HANDLED;
}
@@ -1611,8 +1662,6 @@
return IRQ_NONE;
}
- complete(&dev->done);
-
src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
@@ -1660,6 +1709,8 @@
(dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ?
"KEYFRAME" : "PFRAME");
+ mutex_unlock(&dev->coda_mutex);
+
v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
return IRQ_HANDLED;
@@ -1671,12 +1722,7 @@
struct coda_dev *dev = container_of(to_delayed_work(work),
struct coda_dev, timeout);
- if (completion_done(&dev->done))
- return;
-
- complete(&dev->done);
-
- v4l2_err(&dev->v4l2_dev, "CODA PIC_RUN timeout, stopping all streams\n");
+ dev_err(&dev->plat_dev->dev, "CODA PIC_RUN timeout, stopping all streams\n");
mutex_lock(&dev->dev_mutex);
list_for_each_entry(ctx, &dev->instances, list) {
@@ -1684,6 +1730,10 @@
v4l2_m2m_streamoff(NULL, ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
}
mutex_unlock(&dev->dev_mutex);
+
+ mutex_unlock(&dev->coda_mutex);
+ ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
+ v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
}
static u32 coda_supported_firmwares[] = {
@@ -1748,6 +1798,10 @@
}
}
+ /* Clear registers */
+ for (i = 0; i < 64; i++)
+ coda_write(dev, 0, CODA_REG_BIT_CODE_BUF_ADDR + i * 4);
+
/* Tell the BIT where to find everything it needs */
coda_write(dev, dev->workbuf.paddr,
CODA_REG_BIT_WORK_BUF_ADDR);
@@ -1911,16 +1965,16 @@
static const struct coda_devtype coda_devdata[] = {
[CODA_IMX27] = {
- .firmware = "v4l-codadx6-imx27.bin",
- .product = CODA_DX6,
- .formats = codadx6_formats,
- .num_formats = ARRAY_SIZE(codadx6_formats),
+ .firmware = "v4l-codadx6-imx27.bin",
+ .product = CODA_DX6,
+ .codecs = codadx6_codecs,
+ .num_codecs = ARRAY_SIZE(codadx6_codecs),
},
[CODA_IMX53] = {
- .firmware = "v4l-coda7541-imx53.bin",
- .product = CODA_7541,
- .formats = coda7_formats,
- .num_formats = ARRAY_SIZE(coda7_formats),
+ .firmware = "v4l-coda7541-imx53.bin",
+ .product = CODA_7541,
+ .codecs = coda7_codecs,
+ .num_codecs = ARRAY_SIZE(coda7_codecs),
},
};
@@ -1962,8 +2016,6 @@
spin_lock_init(&dev->irqlock);
INIT_LIST_HEAD(&dev->instances);
INIT_DELAYED_WORK(&dev->timeout, coda_timeout);
- init_completion(&dev->done);
- complete(&dev->done);
dev->plat_dev = pdev;
dev->clk_per = devm_clk_get(&pdev->dev, "per");
@@ -1985,17 +2037,9 @@
return -ENOENT;
}
- if (devm_request_mem_region(&pdev->dev, res->start,
- resource_size(res), CODA_NAME) == NULL) {
- dev_err(&pdev->dev, "failed to request memory region\n");
- return -ENOENT;
- }
- dev->regs_base = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (!dev->regs_base) {
- dev_err(&pdev->dev, "failed to ioremap address region\n");
- return -ENOENT;
- }
+ dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dev->regs_base))
+ return PTR_ERR(dev->regs_base);
/* IRQ */
irq = platform_get_irq(pdev, 0);
@@ -2025,6 +2069,7 @@
return ret;
mutex_init(&dev->dev_mutex);
+ mutex_init(&dev->coda_mutex);
pdev_id = of_id ? of_id->data : platform_get_device_id(pdev);
diff --git a/drivers/media/platform/coda.h b/drivers/media/platform/coda.h
index f3f5e43..ace0bf0 100644
--- a/drivers/media/platform/coda.h
+++ b/drivers/media/platform/coda.h
@@ -96,16 +96,12 @@
#define CODA_CMD_ENC_SEQ_BB_START 0x180
#define CODA_CMD_ENC_SEQ_BB_SIZE 0x184
#define CODA_CMD_ENC_SEQ_OPTION 0x188
-#define CODA_OPTION_GAMMA_OFFSET 7
-#define CODA_OPTION_GAMMA_MASK 0x01
+#define CODA7_OPTION_GAMMA_OFFSET 8
+#define CODADX6_OPTION_GAMMA_OFFSET 7
#define CODA_OPTION_LIMITQP_OFFSET 6
-#define CODA_OPTION_LIMITQP_MASK 0x01
#define CODA_OPTION_RCINTRAQP_OFFSET 5
-#define CODA_OPTION_RCINTRAQP_MASK 0x01
#define CODA_OPTION_FMO_OFFSET 4
-#define CODA_OPTION_FMO_MASK 0x01
#define CODA_OPTION_SLICEREPORT_OFFSET 1
-#define CODA_OPTION_SLICEREPORT_MASK 0x01
#define CODA_CMD_ENC_SEQ_COD_STD 0x18c
#define CODA_STD_MPEG4 0
#define CODA_STD_H263 1
@@ -117,7 +113,8 @@
#define CODADX6_PICWIDTH_OFFSET 10
#define CODADX6_PICWIDTH_MASK 0x3ff
#define CODA_PICHEIGHT_OFFSET 0
-#define CODA_PICHEIGHT_MASK 0x3ff
+#define CODADX6_PICHEIGHT_MASK 0x3ff
+#define CODA7_PICHEIGHT_MASK 0xffff
#define CODA_CMD_ENC_SEQ_SRC_F_RATE 0x194
#define CODA_CMD_ENC_SEQ_MP4_PARA 0x198
#define CODA_MP4PARAM_VERID_OFFSET 6
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index d0b375c..e180ff72 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -944,7 +944,7 @@
cfg->interlaced = vpbe_dev->current_timings.interlaced;
if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
- cfg->pixfmt = PIXFMT_YCbCrI;
+ cfg->pixfmt = PIXFMT_YCBCRI;
/* Change of the default pixel format for both video windows */
if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
@@ -1593,31 +1593,6 @@
return 0;
}
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vpbe_display_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
-{
- struct v4l2_dbg_match *match = ®->match;
- struct vpbe_fh *fh = file->private_data;
- struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
- if (match->type >= 2) {
- v4l2_subdev_call(vpbe_dev->venc,
- core,
- g_register,
- reg);
- }
-
- return 0;
-}
-
-static int vpbe_display_s_register(struct file *file, void *priv,
- const struct v4l2_dbg_register *reg)
-{
- return 0;
-}
-#endif
-
/* vpbe capture ioctl operations */
static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
.vidioc_querycap = vpbe_display_querycap,
@@ -1644,10 +1619,6 @@
.vidioc_s_dv_timings = vpbe_display_s_dv_timings,
.vidioc_g_dv_timings = vpbe_display_g_dv_timings,
.vidioc_enum_dv_timings = vpbe_display_enum_dv_timings,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vpbe_display_g_register,
- .vidioc_s_register = vpbe_display_s_register,
-#endif
};
static struct v4l2_file_operations vpbe_fops = {
diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c
index 396a51c..6ed82e8 100644
--- a/drivers/media/platform/davinci/vpbe_osd.c
+++ b/drivers/media/platform/davinci/vpbe_osd.c
@@ -119,7 +119,7 @@
#define is_rgb_pixfmt(pixfmt) \
(((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888))
#define is_yc_pixfmt(pixfmt) \
- (((pixfmt) == PIXFMT_YCbCrI) || ((pixfmt) == PIXFMT_YCrCbI) || \
+ (((pixfmt) == PIXFMT_YCBCRI) || ((pixfmt) == PIXFMT_YCRCBI) || \
((pixfmt) == PIXFMT_NV12))
#define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
#define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
@@ -360,8 +360,8 @@
osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
OSD_TRANSPVALL);
break;
- case PIXFMT_YCbCrI:
- case PIXFMT_YCrCbI:
+ case PIXFMT_YCBCRI:
+ case PIXFMT_YCRCBI:
if (sd->vpbe_type == VPBE_VERSION_3)
osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
OSD_TRANSPVALU);
@@ -813,8 +813,8 @@
if (osd->vpbe_type == VPBE_VERSION_1)
bad_config = !is_vid_win(layer);
break;
- case PIXFMT_YCbCrI:
- case PIXFMT_YCrCbI:
+ case PIXFMT_YCBCRI:
+ case PIXFMT_YCRCBI:
bad_config = !is_vid_win(layer);
break;
case PIXFMT_RGB888:
@@ -950,9 +950,9 @@
* The caller must ensure that all windows using YC pixfmt use the same
* Cb/Cr order.
*/
- if (pixfmt == PIXFMT_YCbCrI)
+ if (pixfmt == PIXFMT_YCBCRI)
osd_clear(sd, OSD_MODE_CS, OSD_MODE);
- else if (pixfmt == PIXFMT_YCrCbI)
+ else if (pixfmt == PIXFMT_YCRCBI)
osd_set(sd, OSD_MODE_CS, OSD_MODE);
}
@@ -981,8 +981,8 @@
winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
_osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
break;
- case PIXFMT_YCbCrI:
- case PIXFMT_YCrCbI:
+ case PIXFMT_YCBCRI:
+ case PIXFMT_YCRCBI:
winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
break;
default:
@@ -1128,8 +1128,8 @@
_osd_enable_rgb888_pixblend(sd,
OSDWIN_OSD1);
break;
- case PIXFMT_YCbCrI:
- case PIXFMT_YCrCbI:
+ case PIXFMT_YCBCRI:
+ case PIXFMT_YCRCBI:
winmd |=
(3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
break;
@@ -1508,7 +1508,7 @@
_osd_init(osd);
/* set default Cb/Cr order */
- osd->yc_pixfmt = PIXFMT_YCbCrI;
+ osd->yc_pixfmt = PIXFMT_YCBCRI;
if (osd->vpbe_type == VPBE_VERSION_3) {
/*
diff --git a/drivers/media/platform/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c
index ea82a8b..cd08e52 100644
--- a/drivers/media/platform/davinci/vpif.c
+++ b/drivers/media/platform/davinci/vpif.c
@@ -17,30 +17,26 @@
* GNU General Public License for more details.
*/
+#include <linux/err.h>
#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/err.h>
#include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
#include <linux/v4l2-dv-timings.h>
-#include <mach/hardware.h>
-
#include "vpif.h"
MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
MODULE_LICENSE("GPL");
-#define VPIF_CH0_MAX_MODES (22)
-#define VPIF_CH1_MAX_MODES (02)
-#define VPIF_CH2_MAX_MODES (15)
-#define VPIF_CH3_MAX_MODES (02)
+#define VPIF_CH0_MAX_MODES 22
+#define VPIF_CH1_MAX_MODES 2
+#define VPIF_CH2_MAX_MODES 15
+#define VPIF_CH3_MAX_MODES 2
-static resource_size_t res_len;
-static struct resource *res;
spinlock_t vpif_lock;
void __iomem *vpif_base;
@@ -423,23 +419,12 @@
static int vpif_probe(struct platform_device *pdev)
{
- int status = 0;
+ static struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENOENT;
-
- res_len = resource_size(res);
-
- res = request_mem_region(res->start, res_len, res->name);
- if (!res)
- return -EBUSY;
-
- vpif_base = ioremap(res->start, res_len);
- if (!vpif_base) {
- status = -EBUSY;
- goto fail;
- }
+ vpif_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(vpif_base))
+ return PTR_ERR(vpif_base);
pm_runtime_enable(&pdev->dev);
pm_runtime_get(&pdev->dev);
@@ -447,17 +432,11 @@
spin_lock_init(&vpif_lock);
dev_info(&pdev->dev, "vpif probe success\n");
return 0;
-
-fail:
- release_mem_region(res->start, res_len);
- return status;
}
static int vpif_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- iounmap(vpif_base);
- release_mem_region(res->start, res_len);
return 0;
}
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 5f98df1..5514175 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -18,28 +18,16 @@
* TODO : add support for VBI & HBI data service
* add static buffer allocation
*/
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-#include "vpif_capture.h"
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-ioctl.h>
+
#include "vpif.h"
+#include "vpif_capture.h"
MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
MODULE_LICENSE("GPL");
@@ -1874,66 +1862,6 @@
}
/*
- * vpif_g_chip_ident() - Identify the chip
- * @file: file ptr
- * @priv: file handle
- * @chip: chip identity
- *
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
- vpif_dbg(2, debug, "match_type is invalid.\n");
- return -EINVAL;
- }
-
- return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
- g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * vpif_dbg_g_register() - Read register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be read
- *
- * Debugging only
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_dbg_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg){
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(ch->sd, core, g_register, reg);
-}
-
-/*
- * vpif_dbg_s_register() - Write to register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be modified
- *
- * Debugging only
- * Returns zero or -EINVAL if write operations fails.
- */
-static int vpif_dbg_s_register(struct file *file, void *priv,
- const struct v4l2_dbg_register *reg)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(ch->sd, core, s_register, reg);
-}
-#endif
-
-/*
* vpif_log_status() - Status information
* @file: file ptr
* @priv: file handle
@@ -1974,11 +1902,6 @@
.vidioc_query_dv_timings = vpif_query_dv_timings,
.vidioc_s_dv_timings = vpif_s_dv_timings,
.vidioc_g_dv_timings = vpif_g_dv_timings,
- .vidioc_g_chip_ident = vpif_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vpif_dbg_g_register,
- .vidioc_s_register = vpif_dbg_s_register,
-#endif
.vidioc_log_status = vpif_log_status,
};
@@ -2092,16 +2015,13 @@
}
while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
- for (i = res->start; i <= res->end; i++) {
- if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
- "VPIF_Capture", (void *)
- (&vpif_obj.dev[res_idx]->channel_id))) {
- err = -EBUSY;
- for (j = 0; j < i; j++)
- free_irq(j, (void *)
- (&vpif_obj.dev[res_idx]->channel_id));
- goto vpif_int_err;
- }
+ err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
+ IRQF_SHARED, "VPIF_Capture",
+ (void *)(&vpif_obj.dev[res_idx]->
+ channel_id));
+ if (err) {
+ err = -EINVAL;
+ goto vpif_unregister;
}
res_idx++;
}
@@ -2117,7 +2037,7 @@
video_device_release(ch->video_dev);
}
err = -ENOMEM;
- goto vpif_int_err;
+ goto vpif_unregister;
}
/* Initialize field of video device */
@@ -2170,6 +2090,7 @@
if (!vpif_obj.sd[i]) {
vpif_err("Error registering v4l2 subdevice\n");
+ err = -ENODEV;
goto probe_subdev_out;
}
v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
@@ -2217,13 +2138,9 @@
/* Note: does nothing if ch->video_dev == NULL */
video_device_release(ch->video_dev);
}
-vpif_int_err:
+vpif_unregister:
v4l2_device_unregister(&vpif_obj.v4l2_dev);
- for (i = 0; i < res_idx; i++) {
- res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
- for (j = res->start; j <= res->end; j++)
- free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
- }
+
return err;
}
@@ -2235,17 +2152,19 @@
*/
static int vpif_remove(struct platform_device *device)
{
- int i;
struct channel_obj *ch;
+ int i;
v4l2_device_unregister(&vpif_obj.v4l2_dev);
+ kfree(vpif_obj.sd);
/* un-register device */
for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
/* Get the pointer to the channel object */
ch = vpif_obj.dev[i];
/* Unregister video device */
video_unregister_device(ch->video_dev);
+ kfree(vpif_obj.dev[i]);
}
return 0;
}
@@ -2336,47 +2255,4 @@
.remove = vpif_remove,
};
-/**
- * vpif_init: initialize the vpif driver
- *
- * This function registers device and driver to the kernel, requests irq
- * handler and allocates memory
- * for channel objects
- */
-static __init int vpif_init(void)
-{
- return platform_driver_register(&vpif_driver);
-}
-
-/**
- * vpif_cleanup : This function clean up the vpif capture resources
- *
- * This will un-registers device and driver to the kernel, frees
- * requested irq handler and de-allocates memory allocated for channel
- * objects.
- */
-static void vpif_cleanup(void)
-{
- struct platform_device *pdev;
- struct resource *res;
- int irq_num;
- int i = 0;
-
- pdev = container_of(vpif_dev, struct platform_device, dev);
- while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
- for (irq_num = res->start; irq_num <= res->end; irq_num++)
- free_irq(irq_num,
- (void *)(&vpif_obj.dev[i]->channel_id));
- i++;
- }
-
- platform_driver_unregister(&vpif_driver);
-
- kfree(vpif_obj.sd);
- for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
- kfree(vpif_obj.dev[i]);
-}
-
-/* Function for module initialization and cleanup */
-module_init(vpif_init);
-module_exit(vpif_cleanup);
+module_platform_driver(vpif_driver);
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
index 3d3c1e5..0ebb312 100644
--- a/drivers/media/platform/davinci/vpif_capture.h
+++ b/drivers/media/platform/davinci/vpif_capture.h
@@ -22,11 +22,8 @@
#ifdef __KERNEL__
/* Header files */
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
#include <media/videobuf2-dma-contig.h>
-#include <media/davinci/vpif_types.h>
+#include <media/v4l2-device.h>
#include "vpif.h"
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 1b3fb5c..e6e5736 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -14,33 +14,15 @@
* GNU General Public License for more details.
*/
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/i2c.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/io.h>
#include <linux/slab.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-
-#include <media/adv7343.h>
-#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
-#include "vpif_display.h"
#include "vpif.h"
+#include "vpif_display.h"
MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
MODULE_LICENSE("GPL");
@@ -1518,66 +1500,6 @@
}
/*
- * vpif_g_chip_ident() - Identify the chip
- * @file: file ptr
- * @priv: file handle
- * @chip: chip identity
- *
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
- vpif_dbg(2, debug, "match_type is invalid.\n");
- return -EINVAL;
- }
-
- return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
- g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * vpif_dbg_g_register() - Read register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be read
- *
- * Debugging only
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_dbg_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg){
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(ch->sd, core, g_register, reg);
-}
-
-/*
- * vpif_dbg_s_register() - Write to register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be modified
- *
- * Debugging only
- * Returns zero or -EINVAL if write operations fails.
- */
-static int vpif_dbg_s_register(struct file *file, void *priv,
- const struct v4l2_dbg_register *reg)
-{
- struct vpif_fh *fh = priv;
- struct channel_obj *ch = fh->channel;
-
- return v4l2_subdev_call(ch->sd, core, s_register, reg);
-}
-#endif
-
-/*
* vpif_log_status() - Status information
* @file: file ptr
* @priv: file handle
@@ -1616,11 +1538,6 @@
.vidioc_enum_dv_timings = vpif_enum_dv_timings,
.vidioc_s_dv_timings = vpif_s_dv_timings,
.vidioc_g_dv_timings = vpif_g_dv_timings,
- .vidioc_g_chip_ident = vpif_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = vpif_dbg_g_register,
- .vidioc_s_register = vpif_dbg_s_register,
-#endif
.vidioc_log_status = vpif_log_status,
};
@@ -1734,16 +1651,14 @@
}
while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
- for (i = res->start; i <= res->end; i++) {
- if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
- "VPIF_Display", (void *)
- (&vpif_obj.dev[res_idx]->channel_id))) {
- err = -EBUSY;
- for (j = 0; j < i; j++)
- free_irq(j, (void *)
- (&vpif_obj.dev[res_idx]->channel_id));
- goto vpif_int_err;
- }
+ err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
+ IRQF_SHARED, "VPIF_Display",
+ (void *)(&vpif_obj.dev[res_idx]->
+ channel_id));
+ if (err) {
+ err = -EINVAL;
+ vpif_err("VPIF IRQ request failed\n");
+ goto vpif_unregister;
}
res_idx++;
}
@@ -1760,7 +1675,7 @@
video_device_release(ch->video_dev);
}
err = -ENOMEM;
- goto vpif_int_err;
+ goto vpif_unregister;
}
/* Initialize field of video device */
@@ -1813,6 +1728,7 @@
NULL);
if (!vpif_obj.sd[i]) {
vpif_err("Error registering v4l2 subdevice\n");
+ err = -ENODEV;
goto probe_subdev_out;
}
@@ -1893,14 +1809,8 @@
/* Note: does nothing if ch->video_dev == NULL */
video_device_release(ch->video_dev);
}
-vpif_int_err:
+vpif_unregister:
v4l2_device_unregister(&vpif_obj.v4l2_dev);
- vpif_err("VPIF IRQ request failed\n");
- for (i = 0; i < res_idx; i++) {
- res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
- for (j = res->start; j <= res->end; j++)
- free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
- }
return err;
}
@@ -1915,6 +1825,7 @@
v4l2_device_unregister(&vpif_obj.v4l2_dev);
+ kfree(vpif_obj.sd);
/* un-register device */
for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
/* Get the pointer to the channel object */
@@ -1923,6 +1834,7 @@
video_unregister_device(ch->video_dev);
ch->video_dev = NULL;
+ kfree(vpif_obj.dev[i]);
}
return 0;
@@ -2008,37 +1920,4 @@
.remove = vpif_remove,
};
-static __init int vpif_init(void)
-{
- return platform_driver_register(&vpif_driver);
-}
-
-/*
- * vpif_cleanup: This function un-registers device and driver to the kernel,
- * frees requested irq handler and de-allocates memory allocated for channel
- * objects.
- */
-static void vpif_cleanup(void)
-{
- struct platform_device *pdev;
- struct resource *res;
- int irq_num;
- int i = 0;
-
- pdev = container_of(vpif_dev, struct platform_device, dev);
-
- while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
- for (irq_num = res->start; irq_num <= res->end; irq_num++)
- free_irq(irq_num,
- (void *)(&vpif_obj.dev[i]->channel_id));
- i++;
- }
-
- platform_driver_unregister(&vpif_driver);
- kfree(vpif_obj.sd);
- for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
- kfree(vpif_obj.dev[i]);
-}
-
-module_init(vpif_init);
-module_exit(vpif_cleanup);
+module_platform_driver(vpif_driver);
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
index a5a18f7..5d87fc8 100644
--- a/drivers/media/platform/davinci/vpif_display.h
+++ b/drivers/media/platform/davinci/vpif_display.h
@@ -17,11 +17,8 @@
#define DAVINCIHD_DISPLAY_H
/* Header files */
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
#include <media/videobuf2-dma-contig.h>
-#include <media/davinci/vpif_types.h>
+#include <media/v4l2-device.h>
#include "vpif.h"
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index 33b5ffc..559fab2 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -988,7 +988,7 @@
if (pdev->dev.of_node) {
const struct of_device_id *match;
- match = of_match_node(of_match_ptr(exynos_gsc_match),
+ match = of_match_node(exynos_gsc_match,
pdev->dev.of_node);
if (match)
driver_data = (struct gsc_driverdata *)match->data;
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index 436a62a..53ad0f0 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -9,12 +9,16 @@
if VIDEO_SAMSUNG_EXYNOS4_IS
+config VIDEO_EXYNOS4_IS_COMMON
+ tristate
+
config VIDEO_S5P_FIMC
tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
depends on I2C
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
select MFD_SYSCON if OF
+ select VIDEO_EXYNOS4_IS_COMMON
help
This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
interface and video postprocessor (FIMC) devices.
@@ -39,6 +43,7 @@
tristate "EXYNOS FIMC-LITE camera interface driver"
depends on I2C
select VIDEOBUF2_DMA_CONTIG
+ select VIDEO_EXYNOS4_IS_COMMON
help
This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
host interface.
diff --git a/drivers/media/platform/exynos4-is/Makefile b/drivers/media/platform/exynos4-is/Makefile
index f25f463..c2ff29b 100644
--- a/drivers/media/platform/exynos4-is/Makefile
+++ b/drivers/media/platform/exynos4-is/Makefile
@@ -1,10 +1,13 @@
s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o media-dev.o
exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
+s5p-csis-objs := mipi-csis.o
+exynos4-is-common-objs := common.o
+
exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o
exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o
-s5p-csis-objs := mipi-csis.o
obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o
obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE) += exynos-fimc-lite.o
obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS) += exynos-fimc-is.o
obj-$(CONFIG_VIDEO_S5P_FIMC) += s5p-fimc.o
+obj-$(CONFIG_VIDEO_EXYNOS4_IS_COMMON) += exynos4-is-common.o
diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c
new file mode 100644
index 0000000..0ec210b
--- /dev/null
+++ b/drivers/media/platform/exynos4-is/common.c
@@ -0,0 +1,53 @@
+/*
+ * Samsung S5P/EXYNOS4 SoC Camera Subsystem driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <media/s5p_fimc.h>
+#include "common.h"
+
+/* Called with the media graph mutex held or entity->stream_count > 0. */
+struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
+{
+ struct media_pad *pad = &entity->pads[0];
+ struct v4l2_subdev *sd;
+
+ while (pad->flags & MEDIA_PAD_FL_SINK) {
+ /* source pad */
+ pad = media_entity_remote_pad(pad);
+ if (pad == NULL ||
+ media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+ break;
+
+ sd = media_entity_to_v4l2_subdev(pad->entity);
+
+ if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
+ sd->grp_id == GRP_ID_SENSOR)
+ return sd;
+ /* sink pad */
+ pad = &sd->entity.pads[0];
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(fimc_find_remote_sensor);
+
+void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
+ unsigned int caps)
+{
+ strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
+ strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
+ snprintf(cap->bus_info, sizeof(cap->bus_info),
+ "platform:%s", dev_name(dev));
+ cap->device_caps = caps;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+}
+EXPORT_SYMBOL(__fimc_vidioc_querycap);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/exynos4-is/common.h b/drivers/media/platform/exynos4-is/common.h
new file mode 100644
index 0000000..75b9c71
--- /dev/null
+++ b/drivers/media/platform/exynos4-is/common.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/videodev2.h>
+#include <media/media-entity.h>
+#include <media/v4l2-subdev.h>
+
+struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity);
+void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
+ unsigned int caps);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 528f413..fb27ff7 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -27,9 +27,10 @@
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
-#include "media-dev.h"
+#include "common.h"
#include "fimc-core.h"
#include "fimc-reg.h"
+#include "media-dev.h"
static int fimc_capture_hw_init(struct fimc_dev *fimc)
{
@@ -119,8 +120,7 @@
spin_unlock_irqrestore(&fimc->slock, flags);
if (streaming)
- return fimc_pipeline_call(fimc, set_stream,
- &fimc->pipeline, 0);
+ return fimc_pipeline_call(&cap->ve, set_stream, 0);
else
return 0;
}
@@ -178,8 +178,9 @@
void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
{
- struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
struct fimc_vid_cap *cap = &fimc->vid_cap;
+ struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe);
+ struct v4l2_subdev *csis = p->subdevs[IDX_CSIS];
struct fimc_frame *f = &cap->ctx->d_frame;
struct fimc_vid_buffer *v_buf;
struct timeval *tv;
@@ -287,8 +288,7 @@
fimc_activate_capture(ctx);
if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- return fimc_pipeline_call(fimc, set_stream,
- &fimc->pipeline, 1);
+ return fimc_pipeline_call(&vid_cap->ve, set_stream, 1);
}
return 0;
@@ -312,7 +312,7 @@
int ret = fimc_stop_capture(fimc, suspend);
if (ret)
return ret;
- return fimc_pipeline_call(fimc, close, &fimc->pipeline);
+ return fimc_pipeline_call(&fimc->vid_cap.ve, close);
}
static void buffer_queue(struct vb2_buffer *vb);
@@ -320,6 +320,7 @@
int fimc_capture_resume(struct fimc_dev *fimc)
{
struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
+ struct exynos_video_entity *ve = &vid_cap->ve;
struct fimc_vid_buffer *buf;
int i;
@@ -328,8 +329,7 @@
INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
vid_cap->buf_index = 0;
- fimc_pipeline_call(fimc, open, &fimc->pipeline,
- &vid_cap->vfd.entity, false);
+ fimc_pipeline_call(ve, open, &ve->vdev.entity, false);
fimc_capture_hw_init(fimc);
clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
@@ -397,7 +397,7 @@
unsigned long size = ctx->d_frame.payload[i];
if (vb2_plane_size(vb, i) < size) {
- v4l2_err(&ctx->fimc_dev->vid_cap.vfd,
+ v4l2_err(&ctx->fimc_dev->vid_cap.ve.vdev,
"User buffer too small (%ld < %ld)\n",
vb2_plane_size(vb, i), size);
return -EINVAL;
@@ -415,6 +415,7 @@
struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct fimc_dev *fimc = ctx->fimc_dev;
struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
+ struct exynos_video_entity *ve = &vid_cap->ve;
unsigned long flags;
int min_bufs;
@@ -452,9 +453,9 @@
if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
return;
- ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1);
+ ret = fimc_pipeline_call(ve, set_stream, 1);
if (ret < 0)
- v4l2_err(&vid_cap->vfd, "stream on failed: %d\n", ret);
+ v4l2_err(&ve->vdev, "stream on failed: %d\n", ret);
return;
}
spin_unlock_irqrestore(&fimc->slock, flags);
@@ -470,44 +471,17 @@
.stop_streaming = stop_streaming,
};
-/**
- * fimc_capture_ctrls_create - initialize the control handler
- * Initialize the capture video node control handler and fill it
- * with the FIMC controls. Inherit any sensor's controls if the
- * 'user_subdev_api' flag is false (default behaviour).
- * This function need to be called with the graph mutex held.
- */
-int fimc_capture_ctrls_create(struct fimc_dev *fimc)
-{
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
- int ret;
-
- if (WARN_ON(vid_cap->ctx == NULL))
- return -ENXIO;
- if (vid_cap->ctx->ctrls.ready)
- return 0;
-
- ret = fimc_ctrls_create(vid_cap->ctx);
-
- if (ret || vid_cap->user_subdev_api || !sensor ||
- !vid_cap->ctx->ctrls.ready)
- return ret;
-
- return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
- sensor->ctrl_handler, NULL);
-}
-
static int fimc_capture_set_default_format(struct fimc_dev *fimc);
static int fimc_capture_open(struct file *file)
{
struct fimc_dev *fimc = video_drvdata(file);
+ struct fimc_vid_cap *vc = &fimc->vid_cap;
+ struct exynos_video_entity *ve = &vc->ve;
int ret = -EBUSY;
dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
- fimc_md_graph_lock(fimc);
mutex_lock(&fimc->lock);
if (fimc_m2m_active(fimc))
@@ -520,31 +494,42 @@
ret = v4l2_fh_open(file);
if (ret) {
- pm_runtime_put(&fimc->pdev->dev);
+ pm_runtime_put_sync(&fimc->pdev->dev);
goto unlock;
}
if (v4l2_fh_is_singular_file(file)) {
- ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
- &fimc->vid_cap.vfd.entity, true);
+ fimc_md_graph_lock(ve);
- if (!ret && !fimc->vid_cap.user_subdev_api)
+ ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true);
+
+ if (ret == 0 && vc->user_subdev_api && vc->inh_sensor_ctrls) {
+ /*
+ * Recreate controls of the the video node to drop
+ * any controls inherited from the sensor subdev.
+ */
+ fimc_ctrls_delete(vc->ctx);
+
+ ret = fimc_ctrls_create(vc->ctx);
+ if (ret == 0)
+ vc->inh_sensor_ctrls = false;
+ }
+ if (ret == 0)
+ ve->vdev.entity.use_count++;
+
+ fimc_md_graph_unlock(ve);
+
+ if (ret == 0)
ret = fimc_capture_set_default_format(fimc);
- if (!ret)
- ret = fimc_capture_ctrls_create(fimc);
-
if (ret < 0) {
clear_bit(ST_CAPT_BUSY, &fimc->state);
pm_runtime_put_sync(&fimc->pdev->dev);
v4l2_fh_release(file);
- } else {
- fimc->vid_cap.refcnt++;
}
}
unlock:
mutex_unlock(&fimc->lock);
- fimc_md_graph_unlock(fimc);
return ret;
}
@@ -552,30 +537,31 @@
{
struct fimc_dev *fimc = video_drvdata(file);
struct fimc_vid_cap *vc = &fimc->vid_cap;
+ bool close = v4l2_fh_is_singular_file(file);
int ret;
dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
mutex_lock(&fimc->lock);
- if (v4l2_fh_is_singular_file(file)) {
- if (vc->streaming) {
- media_entity_pipeline_stop(&vc->vfd.entity);
- vc->streaming = false;
- }
- clear_bit(ST_CAPT_BUSY, &fimc->state);
- fimc_stop_capture(fimc, false);
- fimc_pipeline_call(fimc, close, &fimc->pipeline);
- clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
- fimc->vid_cap.refcnt--;
+ if (close && vc->streaming) {
+ media_entity_pipeline_stop(&vc->ve.vdev.entity);
+ vc->streaming = false;
}
- pm_runtime_put(&fimc->pdev->dev);
-
- if (v4l2_fh_is_singular_file(file))
- fimc_ctrls_delete(fimc->vid_cap.ctx);
-
ret = vb2_fop_release(file);
+
+ if (close) {
+ clear_bit(ST_CAPT_BUSY, &fimc->state);
+ fimc_pipeline_call(&vc->ve, close);
+ clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
+
+ fimc_md_graph_lock(&vc->ve);
+ vc->ve.vdev.entity.use_count--;
+ fimc_md_graph_unlock(&vc->ve);
+ }
+
+ pm_runtime_put_sync(&fimc->pdev->dev);
mutex_unlock(&fimc->lock);
return ret;
@@ -773,7 +759,7 @@
struct media_pad *pad = &me->pads[0];
while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) {
- pad = media_entity_remote_source(pad);
+ pad = media_entity_remote_pad(pad);
if (!pad)
break;
me = pad->entity;
@@ -797,7 +783,8 @@
bool set)
{
struct fimc_dev *fimc = ctx->fimc_dev;
- struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
+ struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
+ struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
struct v4l2_subdev_format sfmt;
struct v4l2_mbus_framefmt *mf = &sfmt.format;
struct media_entity *me;
@@ -845,7 +832,7 @@
return ret;
}
- pad = media_entity_remote_source(&me->pads[sfmt.pad]);
+ pad = media_entity_remote_pad(&me->pads[sfmt.pad]);
if (!pad)
return -EINVAL;
me = pad->entity;
@@ -929,57 +916,101 @@
return 0;
}
-static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
+/*
+ * Try or set format on the fimc.X.capture video node and additionally
+ * on the whole pipeline if @try is false.
+ * Locking: the caller must _not_ hold the graph mutex.
+ */
+static int __video_try_or_set_format(struct fimc_dev *fimc,
+ struct v4l2_format *f, bool try,
+ struct fimc_fmt **inp_fmt,
+ struct fimc_fmt **out_fmt)
{
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_mbus_framefmt mf;
- struct fimc_fmt *ffmt = NULL;
+ struct fimc_vid_cap *vc = &fimc->vid_cap;
+ struct exynos_video_entity *ve = &vc->ve;
+ struct fimc_ctx *ctx = vc->ctx;
+ unsigned int width = 0, height = 0;
int ret = 0;
- fimc_md_graph_lock(fimc);
- mutex_lock(&fimc->lock);
-
+ /* Pre-configure format at the camera input interface, for JPEG only */
if (fimc_jpeg_fourcc(pix->pixelformat)) {
fimc_capture_try_format(ctx, &pix->width, &pix->height,
NULL, &pix->pixelformat,
FIMC_SD_PAD_SINK_CAM);
- ctx->s_frame.f_width = pix->width;
- ctx->s_frame.f_height = pix->height;
- }
- ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SOURCE);
- if (!ffmt) {
- ret = -EINVAL;
- goto unlock;
+ if (try) {
+ width = pix->width;
+ height = pix->height;
+ } else {
+ ctx->s_frame.f_width = pix->width;
+ ctx->s_frame.f_height = pix->height;
+ }
}
- if (!fimc->vid_cap.user_subdev_api) {
- mf.width = pix->width;
- mf.height = pix->height;
- mf.code = ffmt->mbus_code;
- fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
- pix->width = mf.width;
- pix->height = mf.height;
- if (ffmt)
- pix->pixelformat = ffmt->fourcc;
+ /* Try the format at the scaler and the DMA output */
+ *out_fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
+ NULL, &pix->pixelformat,
+ FIMC_SD_PAD_SOURCE);
+ if (*out_fmt == NULL)
+ return -EINVAL;
+
+ /* Restore image width/height for JPEG (no resizing supported). */
+ if (try && fimc_jpeg_fourcc(pix->pixelformat)) {
+ pix->width = width;
+ pix->height = height;
}
- fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
+ /* Try to match format at the host and the sensor */
+ if (!vc->user_subdev_api) {
+ struct v4l2_mbus_framefmt mbus_fmt;
+ struct v4l2_mbus_framefmt *mf;
- if (ffmt->flags & FMT_FLAGS_COMPRESSED)
- fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
- pix->plane_fmt, ffmt->memplanes, true);
-unlock:
- mutex_unlock(&fimc->lock);
- fimc_md_graph_unlock(fimc);
+ mf = try ? &mbus_fmt : &fimc->vid_cap.ci_fmt;
+
+ mf->code = (*out_fmt)->mbus_code;
+ mf->width = pix->width;
+ mf->height = pix->height;
+
+ fimc_md_graph_lock(ve);
+ ret = fimc_pipeline_try_format(ctx, mf, inp_fmt, try);
+ fimc_md_graph_unlock(ve);
+
+ if (ret < 0)
+ return ret;
+
+ pix->width = mf->width;
+ pix->height = mf->height;
+ }
+
+ fimc_adjust_mplane_format(*out_fmt, pix->width, pix->height, pix);
+
+ if ((*out_fmt)->flags & FMT_FLAGS_COMPRESSED) {
+ struct v4l2_subdev *sensor;
+
+ fimc_md_graph_lock(ve);
+
+ sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
+ if (sensor)
+ fimc_get_sensor_frame_desc(sensor, pix->plane_fmt,
+ (*out_fmt)->memplanes, try);
+ else
+ ret = -EPIPE;
+
+ fimc_md_graph_unlock(ve);
+ }
return ret;
}
+static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct fimc_dev *fimc = video_drvdata(file);
+ struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL;
+
+ return __video_try_or_set_format(fimc, f, true, &inp_fmt, &out_fmt);
+}
+
static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
enum fimc_color_fmt color)
{
@@ -997,57 +1028,23 @@
static int __fimc_capture_set_format(struct fimc_dev *fimc,
struct v4l2_format *f)
{
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
+ struct fimc_vid_cap *vc = &fimc->vid_cap;
+ struct fimc_ctx *ctx = vc->ctx;
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.ci_fmt;
struct fimc_frame *ff = &ctx->d_frame;
- struct fimc_fmt *s_fmt = NULL;
+ struct fimc_fmt *inp_fmt = NULL;
int ret, i;
if (vb2_is_busy(&fimc->vid_cap.vbq))
return -EBUSY;
- /* Pre-configure format at camera interface input, for JPEG only */
- if (fimc_jpeg_fourcc(pix->pixelformat)) {
- fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SINK_CAM);
- ctx->s_frame.f_width = pix->width;
- ctx->s_frame.f_height = pix->height;
- }
- /* Try the format at the scaler and the DMA output */
- ff->fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SOURCE);
- if (!ff->fmt)
- return -EINVAL;
+ ret = __video_try_or_set_format(fimc, f, false, &inp_fmt, &ff->fmt);
+ if (ret < 0)
+ return ret;
/* Update RGB Alpha control state and value range */
fimc_alpha_ctrl_update(ctx);
- /* Try to match format at the host and the sensor */
- if (!fimc->vid_cap.user_subdev_api) {
- mf->code = ff->fmt->mbus_code;
- mf->width = pix->width;
- mf->height = pix->height;
- ret = fimc_pipeline_try_format(ctx, mf, &s_fmt, true);
- if (ret)
- return ret;
-
- pix->width = mf->width;
- pix->height = mf->height;
- }
-
- fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
-
- if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) {
- ret = fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
- pix->plane_fmt, ff->fmt->memplanes,
- true);
- if (ret < 0)
- return ret;
- }
-
for (i = 0; i < ff->fmt->memplanes; i++) {
ff->bytesperline[i] = pix->plane_fmt[i].bytesperline;
ff->payload[i] = pix->plane_fmt[i].sizeimage;
@@ -1061,8 +1058,8 @@
fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color);
/* Reset cropping and set format at the camera interface input */
- if (!fimc->vid_cap.user_subdev_api) {
- ctx->s_frame.fmt = s_fmt;
+ if (!vc->user_subdev_api) {
+ ctx->s_frame.fmt = inp_fmt;
set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
}
@@ -1074,37 +1071,28 @@
struct v4l2_format *f)
{
struct fimc_dev *fimc = video_drvdata(file);
- int ret;
- fimc_md_graph_lock(fimc);
- mutex_lock(&fimc->lock);
- /*
- * The graph is walked within __fimc_capture_set_format() to set
- * the format at subdevs thus the graph mutex needs to be held at
- * this point and acquired before the video mutex, to avoid AB-BA
- * deadlock when fimc_md_link_notify() is called by other thread.
- * Ideally the graph walking and setting format at the whole pipeline
- * should be removed from this driver and handled in userspace only.
- */
- ret = __fimc_capture_set_format(fimc, f);
-
- mutex_unlock(&fimc->lock);
- fimc_md_graph_unlock(fimc);
- return ret;
+ return __fimc_capture_set_format(fimc, f);
}
static int fimc_cap_enum_input(struct file *file, void *priv,
struct v4l2_input *i)
{
struct fimc_dev *fimc = video_drvdata(file);
- struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
+ struct exynos_video_entity *ve = &fimc->vid_cap.ve;
+ struct v4l2_subdev *sd;
if (i->index != 0)
return -EINVAL;
i->type = V4L2_INPUT_TYPE_CAMERA;
+ fimc_md_graph_lock(ve);
+ sd = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
+ fimc_md_graph_unlock(ve);
+
if (sd)
strlcpy(i->name, sd->name, sizeof(i->name));
+
return 0;
}
@@ -1130,6 +1118,7 @@
struct v4l2_subdev_format sink_fmt, src_fmt;
struct fimc_vid_cap *vc = &fimc->vid_cap;
struct v4l2_subdev *sd = &vc->subdev;
+ struct fimc_pipeline *p = to_fimc_pipeline(vc->ve.pipe);
struct media_pad *sink_pad, *src_pad;
int i, ret;
@@ -1146,7 +1135,7 @@
if (p->flags & MEDIA_PAD_FL_SINK) {
sink_pad = p;
- src_pad = media_entity_remote_source(sink_pad);
+ src_pad = media_entity_remote_pad(sink_pad);
if (src_pad)
break;
}
@@ -1183,7 +1172,7 @@
src_fmt.format.code != sink_fmt.format.code)
return -EPIPE;
- if (sd == fimc->pipeline.subdevs[IDX_SENSOR] &&
+ if (sd == p->subdevs[IDX_SENSOR] &&
fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
struct fimc_frame *frame = &vc->ctx->d_frame;
@@ -1207,9 +1196,8 @@
enum v4l2_buf_type type)
{
struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_pipeline *p = &fimc->pipeline;
struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct media_entity *entity = &vc->vfd.entity;
+ struct media_entity *entity = &vc->ve.vdev.entity;
struct fimc_source_info *si = NULL;
struct v4l2_subdev *sd;
int ret;
@@ -1217,11 +1205,11 @@
if (fimc_capture_active(fimc))
return -EBUSY;
- ret = media_entity_pipeline_start(entity, p->m_pipeline);
+ ret = media_entity_pipeline_start(entity, &vc->ve.pipe->mp);
if (ret < 0)
return ret;
- sd = p->subdevs[IDX_SENSOR];
+ sd = __fimc_md_get_subdev(vc->ve.pipe, IDX_SENSOR);
if (sd)
si = v4l2_get_subdev_hostdata(sd);
@@ -1259,14 +1247,15 @@
enum v4l2_buf_type type)
{
struct fimc_dev *fimc = video_drvdata(file);
+ struct fimc_vid_cap *vc = &fimc->vid_cap;
int ret;
ret = vb2_ioctl_streamoff(file, priv, type);
if (ret < 0)
return ret;
- media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity);
- fimc->vid_cap.streaming = false;
+ media_entity_pipeline_stop(&vc->ve.vdev.entity);
+ vc->streaming = false;
return 0;
}
@@ -1405,6 +1394,8 @@
{
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
+ struct fimc_vid_cap *vc = &fimc->vid_cap;
+ struct v4l2_subdev *sensor;
if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
return -EINVAL;
@@ -1416,15 +1407,26 @@
local->entity->name, remote->entity->name, flags,
fimc->vid_cap.input);
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (fimc->vid_cap.input != 0)
- return -EBUSY;
- fimc->vid_cap.input = sd->grp_id;
+ if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+ fimc->vid_cap.input = 0;
return 0;
}
- fimc->vid_cap.input = 0;
- return 0;
+ if (vc->input != 0)
+ return -EBUSY;
+
+ vc->input = sd->grp_id;
+
+ if (vc->user_subdev_api || vc->inh_sensor_ctrls)
+ return 0;
+
+ /* Inherit V4L2 controls from the image sensor subdev. */
+ sensor = fimc_find_remote_sensor(&vc->subdev.entity);
+ if (sensor == NULL)
+ return 0;
+
+ return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler,
+ sensor->ctrl_handler, NULL);
}
static const struct media_entity_operations fimc_sd_media_ops = {
@@ -1720,8 +1722,8 @@
struct v4l2_format fmt = {
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
.fmt.pix_mp = {
- .width = 640,
- .height = 480,
+ .width = FIMC_DEFAULT_WIDTH,
+ .height = FIMC_DEFAULT_HEIGHT,
.pixelformat = V4L2_PIX_FMT_YUYV,
.field = V4L2_FIELD_NONE,
.colorspace = V4L2_COLORSPACE_JPEG,
@@ -1735,10 +1737,11 @@
static int fimc_register_capture_device(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev)
{
- struct video_device *vfd = &fimc->vid_cap.vfd;
+ struct video_device *vfd = &fimc->vid_cap.ve.vdev;
struct vb2_queue *q = &fimc->vid_cap.vbq;
struct fimc_ctx *ctx;
struct fimc_vid_cap *vid_cap;
+ struct fimc_fmt *fmt;
int ret = -ENOMEM;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -1784,22 +1787,34 @@
ret = vb2_queue_init(q);
if (ret)
- goto err_ent;
+ goto err_free_ctx;
+
+ /* Default format configuration */
+ fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
+ vid_cap->ci_fmt.width = FIMC_DEFAULT_WIDTH;
+ vid_cap->ci_fmt.height = FIMC_DEFAULT_HEIGHT;
+ vid_cap->ci_fmt.code = fmt->mbus_code;
+
+ ctx->s_frame.width = FIMC_DEFAULT_WIDTH;
+ ctx->s_frame.height = FIMC_DEFAULT_HEIGHT;
+ ctx->s_frame.fmt = fmt;
+
+ fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_WRITEBACK, 0);
+ vid_cap->wb_fmt = vid_cap->ci_fmt;
+ vid_cap->wb_fmt.code = fmt->mbus_code;
vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
if (ret)
- goto err_ent;
- /*
- * For proper order of acquiring/releasing the video
- * and the graph mutex.
- */
- v4l2_disable_ioctl_locking(vfd, VIDIOC_TRY_FMT);
- v4l2_disable_ioctl_locking(vfd, VIDIOC_S_FMT);
+ goto err_free_ctx;
+
+ ret = fimc_ctrls_create(ctx);
+ if (ret)
+ goto err_me_cleanup;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret)
- goto err_vd;
+ goto err_ctrl_free;
v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
vfd->name, video_device_node_name(vfd));
@@ -1807,9 +1822,11 @@
vfd->ctrl_handler = &ctx->ctrls.handler;
return 0;
-err_vd:
+err_ctrl_free:
+ fimc_ctrls_delete(ctx);
+err_me_cleanup:
media_entity_cleanup(&vfd->entity);
-err_ent:
+err_free_ctx:
kfree(ctx);
return ret;
}
@@ -1826,12 +1843,12 @@
if (ret)
return ret;
- fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
+ fimc->vid_cap.ve.pipe = v4l2_get_subdev_hostdata(sd);
ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
if (ret) {
fimc_unregister_m2m_device(fimc);
- fimc->pipeline_ops = NULL;
+ fimc->vid_cap.ve.pipe = NULL;
}
return ret;
@@ -1840,19 +1857,26 @@
static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
{
struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
+ struct video_device *vdev;
if (fimc == NULL)
return;
- fimc_unregister_m2m_device(fimc);
+ mutex_lock(&fimc->lock);
- if (video_is_registered(&fimc->vid_cap.vfd)) {
- video_unregister_device(&fimc->vid_cap.vfd);
- media_entity_cleanup(&fimc->vid_cap.vfd.entity);
- fimc->pipeline_ops = NULL;
+ fimc_unregister_m2m_device(fimc);
+ vdev = &fimc->vid_cap.ve.vdev;
+
+ if (video_is_registered(vdev)) {
+ video_unregister_device(vdev);
+ media_entity_cleanup(&vdev->entity);
+ fimc_ctrls_delete(fimc->vid_cap.ctx);
+ fimc->vid_cap.ve.pipe = NULL;
}
kfree(fimc->vid_cap.ctx);
fimc->vid_cap.ctx = NULL;
+
+ mutex_unlock(&fimc->lock);
}
static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index 379a5e9..6489c51 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -213,17 +213,6 @@
return &fimc_formats[index];
}
-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
- unsigned int caps)
-{
- strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
- strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
- snprintf(cap->bus_info, sizeof(cap->bus_info),
- "platform:%s", dev_name(dev));
- cap->device_caps = caps;
- cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-}
-
int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
int dw, int dh, int rotation)
{
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
index 539a3f7..3d376fa 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/exynos4-is/fimc-core.h
@@ -48,6 +48,8 @@
#define FIMC_DEF_MIN_SIZE 16
#define FIMC_DEF_HEIGHT_ALIGN 2
#define FIMC_DEF_HOR_OFFS_ALIGN 1
+#define FIMC_DEFAULT_WIDTH 640
+#define FIMC_DEFAULT_HEIGHT 480
/* indices to the clocks array */
enum {
@@ -283,8 +285,8 @@
/**
* struct fimc_vid_cap - camera capture device information
* @ctx: hardware context data
- * @vfd: video device node for camera capture mode
* @subdev: subdev exposing the FIMC processing block
+ * @ve: exynos video device entity structure
* @vd_pad: fimc video capture node pad
* @sd_pads: fimc video processing block pads
* @ci_fmt: image format at the FIMC camera input (and the scaler output)
@@ -298,15 +300,16 @@
* @frame_count: the frame counter for statistics
* @reqbufs_count: the number of buffers requested in REQBUFS ioctl
* @input_index: input (camera sensor) index
- * @refcnt: driver's private reference counter
* @input: capture input type, grp_id of the attached subdev
* @user_subdev_api: true if subdevs are not configured by the host driver
+ * @inh_sensor_ctrls: a flag indicating v4l2 controls are inherited from
+ * an image sensor subdev
*/
struct fimc_vid_cap {
struct fimc_ctx *ctx;
struct vb2_alloc_ctx *alloc_ctx;
- struct video_device vfd;
struct v4l2_subdev subdev;
+ struct exynos_video_entity ve;
struct media_pad vd_pad;
struct media_pad sd_pads[FIMC_SD_PADS_NUM];
struct v4l2_mbus_framefmt ci_fmt;
@@ -321,9 +324,9 @@
unsigned int reqbufs_count;
bool streaming;
int input_index;
- int refcnt;
u32 input;
bool user_subdev_api;
+ bool inh_sensor_ctrls;
};
/**
@@ -434,8 +437,6 @@
struct fimc_vid_cap vid_cap;
unsigned long state;
struct vb2_alloc_ctx *alloc_ctx;
- struct fimc_pipeline pipeline;
- const struct fimc_pipeline_ops *pipeline_ops;
};
/**
@@ -620,8 +621,6 @@
/* fimc-core.c */
int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
struct v4l2_fmtdesc *f);
-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
- unsigned int caps);
int fimc_ctrls_create(struct fimc_ctx *ctx);
void fimc_ctrls_delete(struct fimc_ctx *ctx);
void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
index c397777..617a798 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
@@ -96,7 +96,7 @@
return clk_prepare_enable(isp_i2c->clock);
}
-UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
+static UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
fimc_is_i2c_resume, NULL);
static const struct of_device_id fimc_is_i2c_of_match[] = {
diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.c b/drivers/media/platform/exynos4-is/fimc-is-param.c
index 53fe2a2..c7e7f69 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-param.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-param.c
@@ -38,7 +38,7 @@
memcpy(dst, src, FIMC_IS_PARAM_MAX_SIZE);
}
-void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
+static void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
{
struct param_global_shotmode *dst, *src;
@@ -47,7 +47,7 @@
__hw_param_copy(dst, src);
}
-void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
+static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
{
struct param_sensor_framerate *dst, *src;
@@ -168,8 +168,8 @@
unsigned int count;
spin_lock_irqsave(&is->slock, flags);
- count = hweight32(config->p_region_index1);
- count += hweight32(config->p_region_index2);
+ count = hweight32(config->p_region_index[0]);
+ count += hweight32(config->p_region_index[1]);
spin_unlock_irqrestore(&is->slock, flags);
return count;
@@ -177,31 +177,30 @@
int __is_hw_update_params(struct fimc_is *is)
{
- unsigned long *p_index1, *p_index2;
+ unsigned long *p_index;
int i, id, ret = 0;
id = is->config_index;
- p_index1 = &is->config[id].p_region_index1;
- p_index2 = &is->config[id].p_region_index2;
+ p_index = &is->config[id].p_region_index[0];
- if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index1))
+ if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index))
__fimc_is_hw_update_param_global_shotmode(is);
- if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index1))
+ if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index))
__fimc_is_hw_update_param_sensor_framerate(is);
for (i = PARAM_ISP_CONTROL; i < PARAM_DRC_CONTROL; i++) {
- if (test_bit(i, p_index1))
+ if (test_bit(i, p_index))
ret = __fimc_is_hw_update_param(is, i);
}
for (i = PARAM_DRC_CONTROL; i < PARAM_SCALERC_CONTROL; i++) {
- if (test_bit(i, p_index1))
+ if (test_bit(i, p_index))
ret = __fimc_is_hw_update_param(is, i);
}
for (i = PARAM_FD_CONTROL; i <= PARAM_FD_CONFIG; i++) {
- if (test_bit((i - 32), p_index2))
+ if (test_bit(i, p_index))
ret = __fimc_is_hw_update_param(is, i);
}
@@ -243,7 +242,7 @@
fd->otf_input.height = mf->height;
if (test_bit(PARAM_ISP_OTF_INPUT,
- &is->config[index].p_region_index1))
+ &is->config[index].p_region_index[0]))
return;
/* Update field */
@@ -368,7 +367,7 @@
unsigned long *p_index;
struct isp_param *isp;
- p_index = &is->config[index].p_region_index1;
+ p_index = &is->config[index].p_region_index[0];
isp = &is->config[index].isp;
switch (cmd) {
@@ -415,7 +414,7 @@
struct isp_param *isp;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index1;
+ p_index = &is->config[index].p_region_index[0];
isp = &is->config[index].isp;
switch (id) {
@@ -476,7 +475,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->control.cmd = val;
@@ -491,7 +490,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.max_number = val;
@@ -511,7 +510,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.roll_angle = val;
@@ -531,7 +530,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.yaw_angle = val;
@@ -551,7 +550,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.smile_mode = val;
@@ -571,7 +570,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.blink_mode = val;
@@ -591,7 +590,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.eye_detect = val;
@@ -611,7 +610,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.mouth_detect = val;
@@ -631,7 +630,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.orientation = val;
@@ -651,7 +650,7 @@
struct fd_param *fd;
unsigned long *p_index;
- p_index = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[1];
fd = &is->config[index].fd;
fd->config.orientation_value = val;
@@ -672,7 +671,7 @@
struct isp_param *isp;
struct drc_param *drc;
struct fd_param *fd;
- unsigned long *p_index1, *p_index2;
+ unsigned long *p_index;
unsigned int index;
index = is->config_index;
@@ -681,8 +680,7 @@
isp = &is->config[index].isp;
drc = &is->config[index].drc;
fd = &is->config[index].fd;
- p_index1 = &is->config[index].p_region_index1;
- p_index2 = &is->config[index].p_region_index2;
+ p_index = &is->config[index].p_region_index[0];
/* Global */
global->shotmode.cmd = 1;
@@ -695,7 +693,7 @@
fimc_is_set_param_bit(is, PARAM_ISP_CONTROL);
isp->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_ISP_OTF_INPUT, p_index1)) {
+ if (!test_bit(PARAM_ISP_OTF_INPUT, p_index)) {
isp->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
isp->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT);
@@ -738,20 +736,20 @@
isp->aa.target = ISP_AA_TARGET_AE | ISP_AA_TARGET_AWB;
fimc_is_set_param_bit(is, PARAM_ISP_AA);
- if (!test_bit(PARAM_ISP_FLASH, p_index1))
+ if (!test_bit(PARAM_ISP_FLASH, p_index))
__is_set_isp_flash(is, ISP_FLASH_COMMAND_DISABLE,
ISP_FLASH_REDEYE_DISABLE);
- if (!test_bit(PARAM_ISP_AWB, p_index1))
+ if (!test_bit(PARAM_ISP_AWB, p_index))
__is_set_isp_awb(is, ISP_AWB_COMMAND_AUTO, 0);
- if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index1))
+ if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index))
__is_set_isp_effect(is, ISP_IMAGE_EFFECT_DISABLE);
- if (!test_bit(PARAM_ISP_ISO, p_index1))
+ if (!test_bit(PARAM_ISP_ISO, p_index))
__is_set_isp_iso(is, ISP_ISO_COMMAND_AUTO, 0);
- if (!test_bit(PARAM_ISP_ADJUST, p_index1)) {
+ if (!test_bit(PARAM_ISP_ADJUST, p_index)) {
__is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_CONTRAST, 0);
__is_set_isp_adjust(is,
ISP_ADJUST_COMMAND_MANUAL_SATURATION, 0);
@@ -762,7 +760,7 @@
__is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_HUE, 0);
}
- if (!test_bit(PARAM_ISP_METERING, p_index1)) {
+ if (!test_bit(PARAM_ISP_METERING, p_index)) {
__is_set_isp_metering(is, 0, ISP_METERING_COMMAND_CENTER);
__is_set_isp_metering(is, 1, 0);
__is_set_isp_metering(is, 2, 0);
@@ -770,11 +768,11 @@
__is_set_isp_metering(is, 4, 0);
}
- if (!test_bit(PARAM_ISP_AFC, p_index1))
+ if (!test_bit(PARAM_ISP_AFC, p_index))
__is_set_isp_afc(is, ISP_AFC_COMMAND_AUTO, 0);
isp->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index1)) {
+ if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index)) {
isp->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
isp->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
fimc_is_set_param_bit(is, PARAM_ISP_OTF_OUTPUT);
@@ -784,7 +782,7 @@
isp->otf_output.order = 0;
isp->otf_output.err = OTF_OUTPUT_ERROR_NONE;
- if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index1)) {
+ if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index)) {
isp->dma1_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
isp->dma1_output.width = 0;
isp->dma1_output.height = 0;
@@ -800,7 +798,7 @@
fimc_is_set_param_bit(is, PARAM_ISP_DMA1_OUTPUT);
}
- if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index1)) {
+ if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index)) {
isp->dma2_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
isp->dma2_output.width = 0;
isp->dma2_output.height = 0;
@@ -817,7 +815,7 @@
}
/* Sensor */
- if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index1)) {
+ if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index)) {
if (is->config_index == 0)
__is_set_sensor(is, 0);
}
@@ -827,7 +825,7 @@
__is_set_drc_control(is, CONTROL_BYPASS_ENABLE);
drc->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_DRC_OTF_INPUT, p_index1)) {
+ if (!test_bit(PARAM_DRC_OTF_INPUT, p_index)) {
drc->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
drc->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
fimc_is_set_param_bit(is, PARAM_DRC_OTF_INPUT);
@@ -850,7 +848,7 @@
fimc_is_set_param_bit(is, PARAM_DRC_DMA_INPUT);
drc->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index1)) {
+ if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index)) {
drc->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
drc->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
fimc_is_set_param_bit(is, PARAM_DRC_OTF_OUTPUT);
@@ -865,7 +863,7 @@
fd->control.bypass = CONTROL_BYPASS_DISABLE;
fd->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
- if (!test_bit((PARAM_FD_OTF_INPUT - 32), p_index2)) {
+ if (!test_bit(PARAM_FD_OTF_INPUT, p_index)) {
fd->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
fd->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
fimc_is_set_param_bit(is, PARAM_FD_OTF_INPUT);
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
index d05eaa2..63c68ec 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
@@ -89,8 +89,8 @@
mcuctl_write(is->config_index, is, MCUCTL_REG_ISSR(2));
mcuctl_write(param_count, is, MCUCTL_REG_ISSR(3));
- mcuctl_write(config->p_region_index1, is, MCUCTL_REG_ISSR(4));
- mcuctl_write(config->p_region_index2, is, MCUCTL_REG_ISSR(5));
+ mcuctl_write(config->p_region_index[0], is, MCUCTL_REG_ISSR(4));
+ mcuctl_write(config->p_region_index[1], is, MCUCTL_REG_ISSR(5));
fimc_is_hw_set_intgr0_gd0(is);
return 0;
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 0741945..967f6a9 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -129,7 +129,7 @@
ATCLK_MCUISP_FREQUENCY);
}
-int fimc_is_enable_clocks(struct fimc_is *is)
+static int fimc_is_enable_clocks(struct fimc_is *is)
{
int i, ret;
@@ -149,7 +149,7 @@
return 0;
}
-void fimc_is_disable_clocks(struct fimc_is *is)
+static void fimc_is_disable_clocks(struct fimc_is *is)
{
int i;
@@ -527,8 +527,8 @@
break;
case HIC_SET_PARAMETER:
- is->config[is->config_index].p_region_index1 = 0;
- is->config[is->config_index].p_region_index2 = 0;
+ is->config[is->config_index].p_region_index[0] = 0;
+ is->config[is->config_index].p_region_index[1] = 0;
set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
pr_debug("HIC_SET_PARAMETER\n");
break;
@@ -587,8 +587,8 @@
switch (is->i2h_cmd.args[0]) {
case HIC_SET_PARAMETER:
- is->config[is->config_index].p_region_index1 = 0;
- is->config[is->config_index].p_region_index2 = 0;
+ is->config[is->config_index].p_region_index[0] = 0;
+ is->config[is->config_index].p_region_index[1] = 0;
set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
break;
}
diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
index d7db133..61bb012 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.h
+++ b/drivers/media/platform/exynos4-is/fimc-is.h
@@ -33,8 +33,8 @@
#define FIMC_IS_DRV_NAME "exynos4-fimc-is"
-#define FIMC_IS_FW_FILENAME "fimc_is_fw.bin"
-#define FIMC_IS_SETFILE_6A3 "setfile.bin"
+#define FIMC_IS_FW_FILENAME "exynos4_fimc_is_fw.bin"
+#define FIMC_IS_SETFILE_6A3 "exynos4_s5k6a3_setfile.bin"
#define FIMC_IS_FW_LOAD_TIMEOUT 1000 /* ms */
#define FIMC_IS_POWER_ON_TIMEOUT 1000 /* us */
@@ -225,8 +225,7 @@
struct drc_param drc;
struct fd_param fd;
- unsigned long p_region_index1;
- unsigned long p_region_index2;
+ unsigned long p_region_index[2];
};
/**
@@ -302,10 +301,7 @@
{
struct chain_config *cfg = &is->config[is->config_index];
- if (num >= 32)
- set_bit(num - 32, &cfg->p_region_index2);
- else
- set_bit(num, &cfg->p_region_index1);
+ set_bit(num, &cfg->p_region_index[0]);
}
static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd)
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 7ede30b..cf520a7 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -30,8 +30,8 @@
#include "fimc-is-regs.h"
#include "fimc-is.h"
-static int debug;
-module_param_named(debug_isp, debug, int, S_IRUGO | S_IWUSR);
+int fimc_isp_debug;
+module_param_named(debug_isp, fimc_isp_debug, int, S_IRUGO | S_IWUSR);
static const struct fimc_fmt fimc_isp_formats[FIMC_ISP_NUM_FORMATS] = {
{
@@ -128,57 +128,70 @@
struct v4l2_subdev_format *fmt)
{
struct fimc_isp *isp = v4l2_get_subdevdata(sd);
- struct fimc_is *is = fimc_isp_to_is(isp);
struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct v4l2_mbus_framefmt cur_fmt;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
- fmt->format = *mf;
+ *mf = *v4l2_subdev_get_try_format(fh, fmt->pad);
return 0;
}
mf->colorspace = V4L2_COLORSPACE_SRGB;
mutex_lock(&isp->subdev_lock);
- __is_get_frame_size(is, &cur_fmt);
if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
- /* full camera input frame size */
- mf->width = cur_fmt.width + FIMC_ISP_CAC_MARGIN_WIDTH;
- mf->height = cur_fmt.height + FIMC_ISP_CAC_MARGIN_HEIGHT;
- mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
+ /* ISP OTF input image format */
+ *mf = isp->sink_fmt;
} else {
- /* crop size */
- mf->width = cur_fmt.width;
- mf->height = cur_fmt.height;
- mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+ /* ISP OTF output image format */
+ *mf = isp->src_fmt;
+
+ if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
+ mf->colorspace = V4L2_COLORSPACE_JPEG;
+ mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+ }
}
mutex_unlock(&isp->subdev_lock);
- v4l2_dbg(1, debug, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n",
- __func__, fmt->pad, mf->code, mf->width, mf->height);
+ isp_dbg(1, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n", __func__,
+ fmt->pad, mf->code, mf->width, mf->height);
return 0;
}
static void __isp_subdev_try_format(struct fimc_isp *isp,
- struct v4l2_subdev_format *fmt)
+ struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_format *fmt)
{
struct v4l2_mbus_framefmt *mf = &fmt->format;
+ struct v4l2_mbus_framefmt *format;
+
+ mf->colorspace = V4L2_COLORSPACE_SRGB;
if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
FIMC_ISP_SINK_WIDTH_MAX, 0,
&mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
- isp->subdev_fmt = *mf;
+ mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
} else {
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+ format = v4l2_subdev_get_try_format(fh,
+ FIMC_ISP_SD_PAD_SINK);
+ else
+ format = &isp->sink_fmt;
+
/* Allow changing format only on sink pad */
- mf->width = isp->subdev_fmt.width - FIMC_ISP_CAC_MARGIN_WIDTH;
- mf->height = isp->subdev_fmt.height - FIMC_ISP_CAC_MARGIN_HEIGHT;
- mf->code = isp->subdev_fmt.code;
+ mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
+ mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;
+
+ if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
+ mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+ mf->colorspace = V4L2_COLORSPACE_JPEG;
+ } else {
+ mf->code = format->code;
+ }
}
}
@@ -191,27 +204,50 @@
struct v4l2_mbus_framefmt *mf = &fmt->format;
int ret = 0;
- v4l2_dbg(1, debug, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
+ isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
__func__, fmt->pad, mf->code, mf->width, mf->height);
- mf->colorspace = V4L2_COLORSPACE_SRGB;
-
mutex_lock(&isp->subdev_lock);
- __isp_subdev_try_format(isp, fmt);
+ __isp_subdev_try_format(isp, fh, fmt);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
mf = v4l2_subdev_get_try_format(fh, fmt->pad);
*mf = fmt->format;
- mutex_unlock(&isp->subdev_lock);
- return 0;
+
+ /* Propagate format to the source pads */
+ if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+ struct v4l2_subdev_format format = *fmt;
+ unsigned int pad;
+
+ for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
+ pad < FIMC_ISP_SD_PADS_NUM; pad++) {
+ format.pad = pad;
+ __isp_subdev_try_format(isp, fh, &format);
+ mf = v4l2_subdev_get_try_format(fh, pad);
+ *mf = format.format;
+ }
+ }
+ } else {
+ if (sd->entity.stream_count == 0) {
+ if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+ struct v4l2_subdev_format format = *fmt;
+
+ isp->sink_fmt = *mf;
+
+ format.pad = FIMC_ISP_SD_PAD_SRC_DMA;
+ __isp_subdev_try_format(isp, fh, &format);
+
+ isp->src_fmt = format.format;
+ __is_set_frame_size(is, &isp->src_fmt);
+ } else {
+ isp->src_fmt = *mf;
+ }
+ } else {
+ ret = -EBUSY;
+ }
}
- if (sd->entity.stream_count == 0)
- __is_set_frame_size(is, mf);
- else
- ret = -EBUSY;
mutex_unlock(&isp->subdev_lock);
-
return ret;
}
@@ -221,7 +257,7 @@
struct fimc_is *is = fimc_isp_to_is(isp);
int ret;
- v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on);
+ isp_dbg(1, sd, "%s: on: %d\n", __func__, on);
if (!test_bit(IS_ST_INIT_DONE, &is->state))
return -EBUSY;
@@ -235,8 +271,8 @@
return ret;
}
- v4l2_dbg(1, debug, sd, "changing mode to %d\n",
- is->config_index);
+ isp_dbg(1, sd, "changing mode to %d\n", is->config_index);
+
ret = fimc_is_itf_mode_change(is);
if (ret)
return -EINVAL;
@@ -317,8 +353,8 @@
clear_bit(IS_ST_PWR_ON, &is->state);
clear_bit(IS_ST_INIT_DONE, &is->state);
is->state = 0;
- is->config[is->config_index].p_region_index1 = 0;
- is->config[is->config_index].p_region_index2 = 0;
+ is->config[is->config_index].p_region_index[0] = 0;
+ is->config[is->config_index].p_region_index[1] = 0;
set_bit(IS_ST_IDLE, &is->state);
wmb();
}
@@ -609,6 +645,22 @@
.s_ctrl = fimc_is_s_ctrl,
};
+static void __isp_subdev_set_default_format(struct fimc_isp *isp)
+{
+ struct fimc_is *is = fimc_isp_to_is(isp);
+
+ isp->sink_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH +
+ FIMC_ISP_CAC_MARGIN_WIDTH;
+ isp->sink_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT +
+ FIMC_ISP_CAC_MARGIN_HEIGHT;
+ isp->sink_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10;
+
+ isp->src_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH;
+ isp->src_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT;
+ isp->src_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10;
+ __is_set_frame_size(is, &isp->src_fmt);
+}
+
int fimc_isp_subdev_create(struct fimc_isp *isp)
{
const struct v4l2_ctrl_ops *ops = &fimc_isp_ctrl_ops;
@@ -689,6 +741,8 @@
sd->entity.ops = &fimc_is_subdev_media_ops;
v4l2_set_subdevdata(sd, isp);
+ __isp_subdev_set_default_format(isp);
+
return 0;
}
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
index 800aba7..03bf95a 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.h
+++ b/drivers/media/platform/exynos4-is/fimc-isp.h
@@ -26,6 +26,11 @@
#include <media/v4l2-mediabus.h>
#include <media/s5p_fimc.h>
+extern int fimc_isp_debug;
+
+#define isp_dbg(level, dev, fmt, arg...) \
+ v4l2_dbg(level, fimc_isp_debug, dev, fmt, ## arg)
+
/* FIXME: revisit these constraints */
#define FIMC_ISP_SINK_WIDTH_MIN (16 + 8)
#define FIMC_ISP_SINK_HEIGHT_MIN (12 + 8)
@@ -118,7 +123,6 @@
unsigned int frame_count;
unsigned int reqbufs_count;
int streaming;
- unsigned long payload[FIMC_ISP_MAX_PLANES];
const struct fimc_fmt *format;
};
@@ -128,15 +132,9 @@
* @alloc_ctx: videobuf2 memory allocator context
* @subdev: ISP v4l2_subdev
* @subdev_pads: the ISP subdev media pads
- * @ctrl_handler: v4l2 controls handler
* @test_pattern: test pattern controls
- * @pipeline: video capture pipeline data structure
+ * @ctrls: v4l2 controls structure
* @video_lock: mutex serializing video device and the subdev operations
- * @fmt: pointer to color format description structure
- * @payload: image size in bytes (w x h x bpp)
- * @inp_frame: camera input frame structure
- * @out_frame: DMA output frame structure
- * @source_subdev_grp_id: group id of remote source subdev
* @cac_margin_x: horizontal CAC margin in pixels
* @cac_margin_y: vertical CAC margin in pixels
* @state: driver state flags
@@ -147,17 +145,14 @@
struct vb2_alloc_ctx *alloc_ctx;
struct v4l2_subdev subdev;
struct media_pad subdev_pads[FIMC_ISP_SD_PADS_NUM];
- struct v4l2_mbus_framefmt subdev_fmt;
+ struct v4l2_mbus_framefmt src_fmt;
+ struct v4l2_mbus_framefmt sink_fmt;
struct v4l2_ctrl *test_pattern;
struct fimc_isp_ctrls ctrls;
struct mutex video_lock;
struct mutex subdev_lock;
- struct fimc_isp_frame inp_frame;
- struct fimc_isp_frame out_frame;
- unsigned int source_subdev_grp_id;
-
unsigned int cac_margin_x;
unsigned int cac_margin_y;
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
index 8cc0d39..72a343e3b 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
@@ -2,15 +2,16 @@
* Register interface file for EXYNOS FIMC-LITE (camera interface) driver
*
* Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/io.h>
+#include <linux/bitops.h>
#include <linux/delay.h>
+#include <linux/io.h>
#include <media/s5p_fimc.h>
#include "fimc-lite-reg.h"
@@ -68,7 +69,8 @@
if (atomic_read(&dev->out_path) == FIMC_IO_DMA) {
intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
FLITE_REG_CIGCTRL_IRQ_LASTEN |
- FLITE_REG_CIGCTRL_IRQ_STARTEN;
+ FLITE_REG_CIGCTRL_IRQ_STARTEN |
+ FLITE_REG_CIGCTRL_IRQ_ENDEN;
} else {
/* An output to the FIMC-IS */
intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
@@ -137,7 +139,7 @@
}
if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
- v4l2_err(&dev->vfd,
+ v4l2_err(&dev->ve.vdev,
"Unsupported pixel code, falling back to %#08x\n",
src_pixfmt_map[i][0]);
}
@@ -215,6 +217,18 @@
flite_hw_set_camera_port(dev, si->mux_id);
}
+static void flite_hw_set_pack12(struct fimc_lite *dev, int on)
+{
+ u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
+
+ cfg &= ~FLITE_REG_CIODMAFMT_PACK12;
+
+ if (on)
+ cfg |= FLITE_REG_CIODMAFMT_PACK12;
+
+ writel(cfg, dev->regs + FLITE_REG_CIODMAFMT);
+}
+
static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
{
static const u32 pixcode[4][2] = {
@@ -250,6 +264,38 @@
writel(cfg, dev->regs + FLITE_REG_CIOOFF);
}
+void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf)
+{
+ unsigned int index;
+ u32 cfg;
+
+ if (dev->dd->max_dma_bufs == 1)
+ index = 0;
+ else
+ index = buf->index;
+
+ if (index == 0)
+ writel(buf->paddr, dev->regs + FLITE_REG_CIOSA);
+ else
+ writel(buf->paddr, dev->regs + FLITE_REG_CIOSAN(index - 1));
+
+ cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
+ cfg |= BIT(index);
+ writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
+}
+
+void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index)
+{
+ u32 cfg;
+
+ if (dev->dd->max_dma_bufs == 1)
+ index = 0;
+
+ cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
+ cfg &= ~BIT(index);
+ writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
+}
+
/* Enable/disable output DMA, set output pixel size and offsets (composition) */
void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
bool enable)
@@ -267,6 +313,7 @@
flite_hw_set_out_order(dev, f);
flite_hw_set_dma_window(dev, f);
+ flite_hw_set_pack12(dev, 0);
}
void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
index 3903839..10a7d7b 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
@@ -120,6 +120,9 @@
/* b0: 1 - camera B, 0 - camera A */
#define FLITE_REG_CIGENERAL_CAM_B (1 << 0)
+#define FLITE_REG_CIFCNTSEQ 0x100
+#define FLITE_REG_CIOSAN(x) (0x200 + (4 * (x)))
+
/* ----------------------------------------------------------------------------
* Function declarations
*/
@@ -142,9 +145,12 @@
void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
+void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf);
+void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index);
-static inline void flite_hw_set_output_addr(struct fimc_lite *dev, u32 paddr)
+static inline void flite_hw_set_dma_buf_mask(struct fimc_lite *dev, u32 mask)
{
- writel(paddr, dev->regs + FLITE_REG_CIOSA);
+ writel(mask, dev->regs + FLITE_REG_CIFCNTSEQ);
}
+
#endif /* FIMC_LITE_REG_H */
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 14bb7bc..08fbfed 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1,8 +1,8 @@
/*
* Samsung EXYNOS FIMC-LITE (camera host interface) driver
*
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -32,6 +32,7 @@
#include <media/videobuf2-dma-contig.h>
#include <media/s5p_fimc.h>
+#include "common.h"
#include "fimc-core.h"
#include "fimc-lite.h"
#include "fimc-lite-reg.h"
@@ -43,6 +44,7 @@
{
.name = "YUV 4:2:2 packed, YCbYCr",
.fourcc = V4L2_PIX_FMT_YUYV,
+ .colorspace = V4L2_COLORSPACE_JPEG,
.depth = { 16 },
.color = FIMC_FMT_YCBYCR422,
.memplanes = 1,
@@ -51,6 +53,7 @@
}, {
.name = "YUV 4:2:2 packed, CbYCrY",
.fourcc = V4L2_PIX_FMT_UYVY,
+ .colorspace = V4L2_COLORSPACE_JPEG,
.depth = { 16 },
.color = FIMC_FMT_CBYCRY422,
.memplanes = 1,
@@ -59,6 +62,7 @@
}, {
.name = "YUV 4:2:2 packed, CrYCbY",
.fourcc = V4L2_PIX_FMT_VYUY,
+ .colorspace = V4L2_COLORSPACE_JPEG,
.depth = { 16 },
.color = FIMC_FMT_CRYCBY422,
.memplanes = 1,
@@ -67,6 +71,7 @@
}, {
.name = "YUV 4:2:2 packed, YCrYCb",
.fourcc = V4L2_PIX_FMT_YVYU,
+ .colorspace = V4L2_COLORSPACE_JPEG,
.depth = { 16 },
.color = FIMC_FMT_YCRYCB422,
.memplanes = 1,
@@ -75,6 +80,7 @@
}, {
.name = "RAW8 (GRBG)",
.fourcc = V4L2_PIX_FMT_SGRBG8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = { 8 },
.color = FIMC_FMT_RAW8,
.memplanes = 1,
@@ -83,6 +89,7 @@
}, {
.name = "RAW10 (GRBG)",
.fourcc = V4L2_PIX_FMT_SGRBG10,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = { 10 },
.color = FIMC_FMT_RAW10,
.memplanes = 1,
@@ -91,6 +98,7 @@
}, {
.name = "RAW12 (GRBG)",
.fourcc = V4L2_PIX_FMT_SGRBG12,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = { 12 },
.color = FIMC_FMT_RAW12,
.memplanes = 1,
@@ -131,30 +139,6 @@
return def_fmt;
}
-/* Called with the media graph mutex held or @me stream_count > 0. */
-static struct v4l2_subdev *__find_remote_sensor(struct media_entity *me)
-{
- struct media_pad *pad = &me->pads[0];
- struct v4l2_subdev *sd;
-
- while (pad->flags & MEDIA_PAD_FL_SINK) {
- /* source pad */
- pad = media_entity_remote_source(pad);
- if (pad == NULL ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
- break;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
-
- if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
- sd->grp_id == GRP_ID_SENSOR)
- return sd;
- /* sink pad */
- pad = &sd->entity.pads[0];
- }
- return NULL;
-}
-
static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
{
struct fimc_source_info *si;
@@ -176,6 +160,7 @@
flite_hw_set_camera_bus(fimc, si);
flite_hw_set_source_format(fimc, &fimc->inp_frame);
flite_hw_set_window_offset(fimc, &fimc->inp_frame);
+ flite_hw_set_dma_buf_mask(fimc, 0);
flite_hw_set_output_dma(fimc, &fimc->out_frame, !isp_output);
flite_hw_set_interrupt_mask(fimc);
flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
@@ -233,7 +218,7 @@
if (!streaming)
return 0;
- return fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 0);
+ return fimc_pipeline_call(&fimc->ve, set_stream, 0);
}
static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
@@ -299,19 +284,23 @@
if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
test_bit(ST_FLITE_RUN, &fimc->state) &&
- !list_empty(&fimc->active_buf_q) &&
!list_empty(&fimc->pending_buf_q)) {
+ vbuf = fimc_lite_pending_queue_pop(fimc);
+ flite_hw_set_dma_buffer(fimc, vbuf);
+ fimc_lite_active_queue_add(fimc, vbuf);
+ }
+
+ if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMEND) &&
+ test_bit(ST_FLITE_RUN, &fimc->state) &&
+ !list_empty(&fimc->active_buf_q)) {
vbuf = fimc_lite_active_queue_pop(fimc);
ktime_get_ts(&ts);
tv = &vbuf->vb.v4l2_buf.timestamp;
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
+ flite_hw_mask_dma_buffer(fimc, vbuf->index);
vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
-
- vbuf = fimc_lite_pending_queue_pop(fimc);
- flite_hw_set_output_addr(fimc, vbuf->paddr);
- fimc_lite_active_queue_add(fimc, vbuf);
}
if (test_bit(ST_FLITE_CONFIG, &fimc->state))
@@ -330,10 +319,16 @@
static int start_streaming(struct vb2_queue *q, unsigned int count)
{
struct fimc_lite *fimc = q->drv_priv;
+ unsigned long flags;
int ret;
+ spin_lock_irqsave(&fimc->slock, flags);
+
+ fimc->buf_index = 0;
fimc->frame_count = 0;
+ spin_unlock_irqrestore(&fimc->slock, flags);
+
ret = fimc_lite_hw_init(fimc, false);
if (ret) {
fimc_lite_reinit(fimc, false);
@@ -347,8 +342,7 @@
flite_hw_capture_start(fimc);
if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
- fimc_pipeline_call(fimc, set_stream,
- &fimc->pipeline, 1);
+ fimc_pipeline_call(&fimc->ve, set_stream, 1);
}
if (debug > 0)
flite_hw_dump_regs(fimc, __func__);
@@ -415,7 +409,7 @@
unsigned long size = fimc->payload[i];
if (vb2_plane_size(vb, i) < size) {
- v4l2_err(&fimc->vfd,
+ v4l2_err(&fimc->ve.vdev,
"User buffer too small (%ld < %ld)\n",
vb2_plane_size(vb, i), size);
return -EINVAL;
@@ -436,10 +430,14 @@
spin_lock_irqsave(&fimc->slock, flags);
buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ buf->index = fimc->buf_index++;
+ if (fimc->buf_index >= fimc->reqbufs_count)
+ fimc->buf_index = 0;
+
if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
!test_bit(ST_FLITE_STREAM, &fimc->state) &&
list_empty(&fimc->active_buf_q)) {
- flite_hw_set_output_addr(fimc, buf->paddr);
+ flite_hw_set_dma_buffer(fimc, buf);
fimc_lite_active_queue_add(fimc, buf);
} else {
fimc_lite_pending_queue_add(fimc, buf);
@@ -452,8 +450,7 @@
spin_unlock_irqrestore(&fimc->slock, flags);
if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
- fimc_pipeline_call(fimc, set_stream,
- &fimc->pipeline, 1);
+ fimc_pipeline_call(&fimc->ve, set_stream, 1);
return;
}
spin_unlock_irqrestore(&fimc->slock, flags);
@@ -481,11 +478,9 @@
static int fimc_lite_open(struct file *file)
{
struct fimc_lite *fimc = video_drvdata(file);
- struct media_entity *me = &fimc->vfd.entity;
+ struct media_entity *me = &fimc->ve.vdev.entity;
int ret;
- mutex_lock(&me->parent->graph_mutex);
-
mutex_lock(&fimc->lock);
if (atomic_read(&fimc->out_path) != FIMC_IO_DMA) {
ret = -EBUSY;
@@ -505,11 +500,18 @@
atomic_read(&fimc->out_path) != FIMC_IO_DMA)
goto unlock;
- ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
- me, true);
+ mutex_lock(&me->parent->graph_mutex);
+
+ ret = fimc_pipeline_call(&fimc->ve, open, me, true);
+
+ /* Mark video pipeline ending at this video node as in use. */
+ if (ret == 0)
+ me->use_count++;
+
+ mutex_unlock(&me->parent->graph_mutex);
+
if (!ret) {
fimc_lite_clear_event_counters(fimc);
- fimc->ref_count++;
goto unlock;
}
@@ -519,26 +521,29 @@
clear_bit(ST_FLITE_IN_USE, &fimc->state);
unlock:
mutex_unlock(&fimc->lock);
- mutex_unlock(&me->parent->graph_mutex);
return ret;
}
static int fimc_lite_release(struct file *file)
{
struct fimc_lite *fimc = video_drvdata(file);
+ struct media_entity *entity = &fimc->ve.vdev.entity;
mutex_lock(&fimc->lock);
if (v4l2_fh_is_singular_file(file) &&
atomic_read(&fimc->out_path) == FIMC_IO_DMA) {
if (fimc->streaming) {
- media_entity_pipeline_stop(&fimc->vfd.entity);
+ media_entity_pipeline_stop(entity);
fimc->streaming = false;
}
- clear_bit(ST_FLITE_IN_USE, &fimc->state);
fimc_lite_stop_capture(fimc, false);
- fimc_pipeline_call(fimc, close, &fimc->pipeline);
- fimc->ref_count--;
+ fimc_pipeline_call(&fimc->ve, close);
+ clear_bit(ST_FLITE_IN_USE, &fimc->state);
+
+ mutex_lock(&entity->parent->graph_mutex);
+ entity->use_count--;
+ mutex_unlock(&entity->parent->graph_mutex);
}
vb2_fop_release(file);
@@ -562,37 +567,54 @@
* Format and crop negotiation helpers
*/
-static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
- u32 *width, u32 *height,
- u32 *code, u32 *fourcc, int pad)
+static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
+ struct v4l2_subdev_fh *fh,
+ struct v4l2_subdev_format *format)
{
struct flite_drvdata *dd = fimc->dd;
- const struct fimc_fmt *fmt;
- unsigned int flags = 0;
+ struct v4l2_mbus_framefmt *mf = &format->format;
+ const struct fimc_fmt *fmt = NULL;
- if (pad == FLITE_SD_PAD_SINK) {
- v4l_bound_align_image(width, 8, dd->max_width,
- ffs(dd->out_width_align) - 1,
- height, 0, dd->max_height, 0, 0);
+ if (format->pad == FLITE_SD_PAD_SINK) {
+ v4l_bound_align_image(&mf->width, 8, dd->max_width,
+ ffs(dd->out_width_align) - 1,
+ &mf->height, 0, dd->max_height, 0, 0);
+
+ fmt = fimc_lite_find_format(NULL, &mf->code, 0, 0);
+ if (WARN_ON(!fmt))
+ return NULL;
+
+ mf->colorspace = fmt->colorspace;
+ mf->code = fmt->mbus_code;
} else {
- v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
- ffs(dd->out_width_align) - 1,
- height, 0, fimc->inp_frame.rect.height,
- 0, 0);
- flags = fimc->inp_frame.fmt->flags;
+ struct flite_frame *sink = &fimc->inp_frame;
+ struct v4l2_mbus_framefmt *sink_fmt;
+ struct v4l2_rect *rect;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+ sink_fmt = v4l2_subdev_get_try_format(fh,
+ FLITE_SD_PAD_SINK);
+
+ mf->code = sink_fmt->code;
+ mf->colorspace = sink_fmt->colorspace;
+
+ rect = v4l2_subdev_get_try_crop(fh,
+ FLITE_SD_PAD_SINK);
+ } else {
+ mf->code = sink->fmt->mbus_code;
+ mf->colorspace = sink->fmt->colorspace;
+ rect = &sink->rect;
+ }
+
+ /* Allow changing format only on sink pad */
+ mf->width = rect->width;
+ mf->height = rect->height;
}
- fmt = fimc_lite_find_format(fourcc, code, flags, 0);
- if (WARN_ON(!fmt))
- return NULL;
+ mf->field = V4L2_FIELD_NONE;
- if (code)
- *code = fmt->mbus_code;
- if (fourcc)
- *fourcc = fmt->fourcc;
-
- v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
- code ? *code : 0, *width, *height);
+ v4l2_dbg(1, debug, &fimc->subdev, "code: %#x (%d), %dx%d\n",
+ mf->code, mf->colorspace, mf->width, mf->height);
return fmt;
}
@@ -637,13 +659,18 @@
/*
* Video node ioctl operations
*/
-static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
+static int fimc_lite_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
+ struct fimc_lite *fimc = video_drvdata(file);
+
strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
- cap->bus_info[0] = 0;
- cap->card[0] = 0;
- cap->capabilities = V4L2_CAP_STREAMING;
+ strlcpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card));
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+ dev_name(&fimc->pdev->dev));
+
+ cap->device_caps = V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -679,7 +706,7 @@
pixm->width = frame->f_width;
pixm->height = frame->f_height;
pixm->field = V4L2_FIELD_NONE;
- pixm->colorspace = V4L2_COLORSPACE_JPEG;
+ pixm->colorspace = fmt->colorspace;
return 0;
}
@@ -722,7 +749,7 @@
fmt->depth[0]) / 8;
pixm->num_planes = fmt->memplanes;
pixm->pixelformat = fmt->fourcc;
- pixm->colorspace = V4L2_COLORSPACE_JPEG;
+ pixm->colorspace = fmt->colorspace;
pixm->field = V4L2_FIELD_NONE;
return 0;
}
@@ -786,7 +813,7 @@
return -EPIPE;
}
/* Retrieve format at the source pad */
- pad = media_entity_remote_source(pad);
+ pad = media_entity_remote_pad(pad);
if (pad == NULL ||
media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
break;
@@ -810,14 +837,13 @@
enum v4l2_buf_type type)
{
struct fimc_lite *fimc = video_drvdata(file);
- struct media_entity *entity = &fimc->vfd.entity;
- struct fimc_pipeline *p = &fimc->pipeline;
+ struct media_entity *entity = &fimc->ve.vdev.entity;
int ret;
if (fimc_lite_active(fimc))
return -EBUSY;
- ret = media_entity_pipeline_start(entity, p->m_pipeline);
+ ret = media_entity_pipeline_start(entity, &fimc->ve.pipe->mp);
if (ret < 0)
return ret;
@@ -825,7 +851,7 @@
if (ret < 0)
goto err_p_stop;
- fimc->sensor = __find_remote_sensor(&fimc->subdev.entity);
+ fimc->sensor = fimc_find_remote_sensor(&fimc->subdev.entity);
ret = vb2_ioctl_streamon(file, priv, type);
if (!ret) {
@@ -848,7 +874,7 @@
if (ret < 0)
return ret;
- media_entity_pipeline_stop(&fimc->vfd.entity);
+ media_entity_pipeline_stop(&fimc->ve.vdev.entity);
fimc->streaming = false;
return 0;
}
@@ -938,7 +964,7 @@
}
static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
- .vidioc_querycap = fimc_vidioc_querycap_capture,
+ .vidioc_querycap = fimc_lite_querycap,
.vidioc_enum_fmt_vid_cap_mplane = fimc_lite_enum_fmt_mplane,
.vidioc_try_fmt_vid_cap_mplane = fimc_lite_try_fmt_mplane,
.vidioc_s_fmt_vid_cap_mplane = fimc_lite_s_fmt_mplane,
@@ -972,8 +998,6 @@
__func__, remote->entity->name, local->entity->name,
flags, fimc->source_subdev_grp_id);
- mutex_lock(&fimc->lock);
-
switch (local->index) {
case FLITE_SD_PAD_SINK:
if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
@@ -1015,7 +1039,6 @@
}
mb();
- mutex_unlock(&fimc->lock);
return ret;
}
@@ -1036,6 +1059,15 @@
return 0;
}
+static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt(
+ struct v4l2_subdev_fh *fh, unsigned int pad)
+{
+ if (pad != FLITE_SD_PAD_SINK)
+ pad = FLITE_SD_PAD_SOURCE_DMA;
+
+ return v4l2_subdev_get_try_format(fh, pad);
+}
+
static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh,
struct v4l2_subdev_format *fmt)
@@ -1045,13 +1077,13 @@
struct flite_frame *f = &fimc->inp_frame;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+ mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
fmt->format = *mf;
return 0;
}
- mf->colorspace = V4L2_COLORSPACE_JPEG;
mutex_lock(&fimc->lock);
+ mf->colorspace = f->fmt->colorspace;
mf->code = f->fmt->mbus_code;
if (fmt->pad == FLITE_SD_PAD_SINK) {
@@ -1080,7 +1112,6 @@
v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d\n",
fmt->pad, mf->code, mf->width, mf->height);
- mf->colorspace = V4L2_COLORSPACE_JPEG;
mutex_lock(&fimc->lock);
if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP &&
@@ -1091,12 +1122,20 @@
return -EBUSY;
}
- ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
- &mf->code, NULL, fmt->pad);
+ ffmt = fimc_lite_subdev_try_fmt(fimc, fh, fmt);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+ struct v4l2_mbus_framefmt *src_fmt;
+
+ mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
*mf = fmt->format;
+
+ if (fmt->pad == FLITE_SD_PAD_SINK) {
+ unsigned int pad = FLITE_SD_PAD_SOURCE_DMA;
+ src_fmt = __fimc_lite_subdev_get_try_fmt(fh, pad);
+ *src_fmt = *mf;
+ }
+
mutex_unlock(&fimc->lock);
return 0;
}
@@ -1114,11 +1153,6 @@
source->rect = sink->rect;
source->f_width = mf->width;
source->f_height = mf->height;
- } else {
- /* Allow changing format only on sink pad */
- mf->code = sink->fmt->mbus_code;
- mf->width = sink->rect.width;
- mf->height = sink->rect.height;
}
mutex_unlock(&fimc->lock);
@@ -1207,7 +1241,7 @@
* The pipeline links are protected through entity.stream_count
* so there is no need to take the media graph mutex here.
*/
- fimc->sensor = __find_remote_sensor(&sd->entity);
+ fimc->sensor = fimc_find_remote_sensor(&sd->entity);
if (atomic_read(&fimc->out_path) != FIMC_IO_ISP)
return -ENOIOCTLCMD;
@@ -1252,13 +1286,10 @@
{
struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
struct vb2_queue *q = &fimc->vb_queue;
- struct video_device *vfd = &fimc->vfd;
+ struct video_device *vfd = &fimc->ve.vdev;
int ret;
memset(vfd, 0, sizeof(*vfd));
-
- fimc->inp_frame.fmt = &fimc_lite_formats[0];
- fimc->out_frame.fmt = &fimc_lite_formats[0];
atomic_set(&fimc->out_path, FIMC_IO_DMA);
snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
@@ -1295,12 +1326,12 @@
return ret;
video_set_drvdata(vfd, fimc);
- fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
+ fimc->ve.pipe = v4l2_get_subdev_hostdata(sd);
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret < 0) {
media_entity_cleanup(&vfd->entity);
- fimc->pipeline_ops = NULL;
+ fimc->ve.pipe = NULL;
return ret;
}
@@ -1316,11 +1347,15 @@
if (fimc == NULL)
return;
- if (video_is_registered(&fimc->vfd)) {
- video_unregister_device(&fimc->vfd);
- media_entity_cleanup(&fimc->vfd.entity);
- fimc->pipeline_ops = NULL;
+ mutex_lock(&fimc->lock);
+
+ if (video_is_registered(&fimc->ve.vdev)) {
+ video_unregister_device(&fimc->ve.vdev);
+ media_entity_cleanup(&fimc->ve.vdev.entity);
+ fimc->ve.pipe = NULL;
}
+
+ mutex_unlock(&fimc->lock);
}
static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
@@ -1370,6 +1405,23 @@
.step = 1,
};
+static void fimc_lite_set_default_config(struct fimc_lite *fimc)
+{
+ struct flite_frame *sink = &fimc->inp_frame;
+ struct flite_frame *source = &fimc->out_frame;
+
+ sink->fmt = &fimc_lite_formats[0];
+ sink->f_width = FLITE_DEFAULT_WIDTH;
+ sink->f_height = FLITE_DEFAULT_HEIGHT;
+
+ sink->rect.width = FLITE_DEFAULT_WIDTH;
+ sink->rect.height = FLITE_DEFAULT_HEIGHT;
+ sink->rect.left = 0;
+ sink->rect.top = 0;
+
+ *source = *sink;
+}
+
static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
{
struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
@@ -1417,12 +1469,12 @@
static void fimc_lite_clk_put(struct fimc_lite *fimc)
{
- if (IS_ERR_OR_NULL(fimc->clock))
+ if (IS_ERR(fimc->clock))
return;
clk_unprepare(fimc->clock);
clk_put(fimc->clock);
- fimc->clock = NULL;
+ fimc->clock = ERR_PTR(-EINVAL);
}
static int fimc_lite_clk_get(struct fimc_lite *fimc)
@@ -1436,7 +1488,7 @@
ret = clk_prepare(fimc->clock);
if (ret < 0) {
clk_put(fimc->clock);
- fimc->clock = NULL;
+ fimc->clock = ERR_PTR(-EINVAL);
}
return ret;
}
@@ -1461,13 +1513,14 @@
if (of_id)
drv_data = (struct flite_drvdata *)of_id->data;
fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
- } else {
- drv_data = fimc_lite_get_drvdata(pdev);
- fimc->index = pdev->id;
}
- if (!drv_data || fimc->index < 0 || fimc->index >= FIMC_LITE_MAX_DEVS)
+ if (!drv_data || fimc->index >= drv_data->num_instances ||
+ fimc->index < 0) {
+ dev_err(dev, "Wrong %s node alias\n",
+ dev->of_node->full_name);
return -EINVAL;
+ }
fimc->dd = drv_data;
fimc->pdev = pdev;
@@ -1514,8 +1567,11 @@
ret = PTR_ERR(fimc->alloc_ctx);
goto err_pm;
}
+
pm_runtime_put(dev);
+ fimc_lite_set_default_config(fimc);
+
dev_dbg(dev, "FIMC-LITE.%d registered successfully\n",
fimc->index);
return 0;
@@ -1565,8 +1621,8 @@
return 0;
INIT_LIST_HEAD(&fimc->active_buf_q);
- fimc_pipeline_call(fimc, open, &fimc->pipeline,
- &fimc->vfd.entity, false);
+ fimc_pipeline_call(&fimc->ve, open,
+ &fimc->ve.vdev.entity, false);
fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP);
clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
@@ -1592,7 +1648,7 @@
if (ret < 0 || !fimc_lite_active(fimc))
return ret;
- return fimc_pipeline_call(fimc, close, &fimc->pipeline);
+ return fimc_pipeline_call(&fimc->ve, close);
}
#endif /* CONFIG_PM_SLEEP */
@@ -1624,22 +1680,30 @@
.out_width_align = 8,
.win_hor_offs_align = 2,
.out_hor_offs_align = 8,
+ .max_dma_bufs = 1,
+ .num_instances = 2,
};
-static struct platform_device_id fimc_lite_driver_ids[] = {
- {
- .name = "exynos-fimc-lite",
- .driver_data = (unsigned long)&fimc_lite_drvdata_exynos4,
- },
- { /* sentinel */ },
+/* EXYNOS5250 */
+static struct flite_drvdata fimc_lite_drvdata_exynos5 = {
+ .max_width = 8192,
+ .max_height = 8192,
+ .out_width_align = 8,
+ .win_hor_offs_align = 2,
+ .out_hor_offs_align = 8,
+ .max_dma_bufs = 32,
+ .num_instances = 3,
};
-MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
static const struct of_device_id flite_of_match[] = {
{
.compatible = "samsung,exynos4212-fimc-lite",
.data = &fimc_lite_drvdata_exynos4,
},
+ {
+ .compatible = "samsung,exynos5250-fimc-lite",
+ .data = &fimc_lite_drvdata_exynos5,
+ },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, flite_of_match);
@@ -1647,7 +1711,6 @@
static struct platform_driver fimc_lite_driver = {
.probe = fimc_lite_probe,
.remove = fimc_lite_remove,
- .id_table = fimc_lite_driver_ids,
.driver = {
.of_match_table = flite_of_match,
.name = FIMC_LITE_DRV_NAME,
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
index 47da5e0..7428b2d 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite.h
@@ -27,8 +27,10 @@
#define FIMC_LITE_DRV_NAME "exynos-fimc-lite"
#define FLITE_CLK_NAME "flite"
-#define FIMC_LITE_MAX_DEVS 2
+#define FIMC_LITE_MAX_DEVS 3
#define FLITE_REQ_BUFS_MIN 2
+#define FLITE_DEFAULT_WIDTH 640
+#define FLITE_DEFAULT_HEIGHT 480
/* Bit index definitions for struct fimc_lite::state */
enum {
@@ -48,17 +50,28 @@
#define FLITE_SD_PAD_SOURCE_ISP 2
#define FLITE_SD_PADS_NUM 3
+/**
+ * struct flite_drvdata - FIMC-LITE IP variant data structure
+ * @max_width: maximum camera interface input width in pixels
+ * @max_height: maximum camera interface input height in pixels
+ * @out_width_align: minimum output width alignment in pixels
+ * @win_hor_offs_align: minimum camera interface crop window horizontal
+ * offset alignment in pixels
+ * @out_hor_offs_align: minimum output DMA compose rectangle horizontal
+ * offset alignment in pixels
+ * @max_dma_bufs: number of output DMA buffer start address registers
+ * @num_instances: total number of FIMC-LITE IP instances available
+ */
struct flite_drvdata {
unsigned short max_width;
unsigned short max_height;
unsigned short out_width_align;
unsigned short win_hor_offs_align;
unsigned short out_hor_offs_align;
+ unsigned short max_dma_bufs;
+ unsigned short num_instances;
};
-#define fimc_lite_get_drvdata(_pdev) \
- ((struct flite_drvdata *) platform_get_device_id(_pdev)->driver_data)
-
struct fimc_lite_events {
unsigned int data_overflow;
};
@@ -83,20 +96,22 @@
* struct flite_buffer - video buffer structure
* @vb: vb2 buffer
* @list: list head for the buffers queue
- * @paddr: precalculated physical address
+ * @paddr: DMA buffer start address
+ * @index: DMA start address register's index
*/
struct flite_buffer {
struct vb2_buffer vb;
struct list_head list;
dma_addr_t paddr;
+ unsigned short index;
};
/**
* struct fimc_lite - fimc lite structure
* @pdev: pointer to FIMC-LITE platform device
* @dd: SoC specific driver data structure
+ * @ve: exynos video device entity structure
* @v4l2_dev: pointer to top the level v4l2_device
- * @vfd: video device node
* @fh: v4l2 file handle
* @alloc_ctx: videobuf2 memory allocator context
* @subdev: FIMC-LITE subdev
@@ -122,16 +137,16 @@
* @pending_buf_q: pending buffers queue head
* @active_buf_q: the queue head of buffers scheduled in hardware
* @vb_queue: vb2 buffers queue
+ * @buf_index: helps to keep track of the DMA start address register index
* @active_buf_count: number of video buffers scheduled in hardware
* @frame_count: the captured frames counter
* @reqbufs_count: the number of buffers requested with REQBUFS ioctl
- * @ref_count: driver's private reference counter
*/
struct fimc_lite {
struct platform_device *pdev;
struct flite_drvdata *dd;
+ struct exynos_video_entity ve;
struct v4l2_device *v4l2_dev;
- struct video_device vfd;
struct v4l2_fh fh;
struct vb2_alloc_ctx *alloc_ctx;
struct v4l2_subdev subdev;
@@ -141,8 +156,6 @@
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *test_pattern;
int index;
- struct fimc_pipeline pipeline;
- const struct fimc_pipeline_ops *pipeline_ops;
struct mutex lock;
spinlock_t slock;
@@ -161,9 +174,9 @@
struct list_head pending_buf_q;
struct list_head active_buf_q;
struct vb2_queue vb_queue;
+ unsigned short buf_index;
unsigned int frame_count;
unsigned int reqbufs_count;
- int ref_count;
struct fimc_lite_events events;
bool streaming;
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index bde1f47..8d33b68 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -27,6 +27,7 @@
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
+#include "common.h"
#include "fimc-core.h"
#include "fimc-reg.h"
#include "media-dev.h"
diff --git a/drivers/media/platform/exynos4-is/fimc-reg.c b/drivers/media/platform/exynos4-is/fimc-reg.c
index f079f36..1db8cb4 100644
--- a/drivers/media/platform/exynos4-is/fimc-reg.c
+++ b/drivers/media/platform/exynos4-is/fimc-reg.c
@@ -618,7 +618,7 @@
}
if (i == ARRAY_SIZE(pix_desc)) {
- v4l2_err(&vc->vfd,
+ v4l2_err(&vc->ve.vdev,
"Camera color format not supported: %d\n",
vc->ci_fmt.code);
return -EINVAL;
@@ -698,7 +698,7 @@
cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
break;
default:
- v4l2_err(&vid_cap->vfd,
+ v4l2_err(&vid_cap->ve.vdev,
"Not supported camera pixel format: %#x\n",
vid_cap->ci_fmt.code);
return -EINVAL;
@@ -721,7 +721,8 @@
WARN_ONCE(1, "ISP Writeback input is not supported\n");
break;
default:
- v4l2_err(&vid_cap->vfd, "Invalid FIMC bus type selected: %d\n",
+ v4l2_err(&vid_cap->ve.vdev,
+ "Invalid FIMC bus type selected: %d\n",
source->fimc_bus_type);
return -EINVAL;
}
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 15ef8f2..19f556c 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1,8 +1,8 @@
/*
* S5P/EXYNOS4 SoC series camera host interface media device driver
*
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
@@ -39,6 +39,26 @@
static int __fimc_md_set_camclk(struct fimc_md *fmd,
struct fimc_source_info *si,
bool on);
+
+/* Set up image sensor subdev -> FIMC capture node notifications. */
+static void __setup_sensor_notification(struct fimc_md *fmd,
+ struct v4l2_subdev *sensor,
+ struct v4l2_subdev *fimc_sd)
+{
+ struct fimc_source_info *src_inf;
+ struct fimc_sensor_info *md_si;
+ unsigned long flags;
+
+ src_inf = v4l2_get_subdev_hostdata(sensor);
+ if (!src_inf || WARN_ON(fmd == NULL))
+ return;
+
+ md_si = source_to_sensor_info(src_inf);
+ spin_lock_irqsave(&fmd->slock, flags);
+ md_si->host = v4l2_get_subdevdata(fimc_sd);
+ spin_unlock_irqrestore(&fmd->slock, flags);
+}
+
/**
* fimc_pipeline_prepare - update pipeline information with subdevice pointers
* @me: media entity terminating the pipeline
@@ -46,9 +66,11 @@
* Caller holds the graph mutex.
*/
static void fimc_pipeline_prepare(struct fimc_pipeline *p,
- struct media_entity *me)
+ struct media_entity *me)
{
+ struct fimc_md *fmd = entity_to_fimc_mdev(me);
struct v4l2_subdev *sd;
+ struct v4l2_subdev *sensor = NULL;
int i;
for (i = 0; i < IDX_MAX; i++)
@@ -62,7 +84,7 @@
struct media_pad *spad = &me->pads[i];
if (!(spad->flags & MEDIA_PAD_FL_SINK))
continue;
- pad = media_entity_remote_source(spad);
+ pad = media_entity_remote_pad(spad);
if (pad)
break;
}
@@ -73,8 +95,10 @@
sd = media_entity_to_v4l2_subdev(pad->entity);
switch (sd->grp_id) {
- case GRP_ID_FIMC_IS_SENSOR:
case GRP_ID_SENSOR:
+ sensor = sd;
+ /* fall through */
+ case GRP_ID_FIMC_IS_SENSOR:
p->subdevs[IDX_SENSOR] = sd;
break;
case GRP_ID_CSIS:
@@ -84,7 +108,7 @@
p->subdevs[IDX_FLITE] = sd;
break;
case GRP_ID_FIMC:
- /* No need to control FIMC subdev through subdev ops */
+ p->subdevs[IDX_FIMC] = sd;
break;
case GRP_ID_FIMC_IS:
p->subdevs[IDX_IS_ISP] = sd;
@@ -96,6 +120,9 @@
if (me->num_pads == 1)
break;
}
+
+ if (sensor && p->subdevs[IDX_FIMC])
+ __setup_sensor_notification(fmd, sensor, p->subdevs[IDX_FIMC]);
}
/**
@@ -168,10 +195,11 @@
*
* Called with the graph mutex held.
*/
-static int __fimc_pipeline_open(struct fimc_pipeline *p,
+static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
struct media_entity *me, bool prepare)
{
struct fimc_md *fmd = entity_to_fimc_mdev(me);
+ struct fimc_pipeline *p = to_fimc_pipeline(ep);
struct v4l2_subdev *sd;
int ret;
@@ -214,20 +242,21 @@
*
* Disable power of all subdevs and turn the external sensor clock off.
*/
-static int __fimc_pipeline_close(struct fimc_pipeline *p)
+static int __fimc_pipeline_close(struct exynos_media_pipeline *ep)
{
+ struct fimc_pipeline *p = to_fimc_pipeline(ep);
struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL;
struct fimc_md *fmd;
- int ret = 0;
+ int ret;
- if (WARN_ON(sd == NULL))
- return -EINVAL;
-
- if (p->subdevs[IDX_SENSOR]) {
- ret = fimc_pipeline_s_power(p, 0);
- fimc_md_set_camclk(sd, false);
+ if (sd == NULL) {
+ pr_warn("%s(): No sensor subdev\n", __func__);
+ return 0;
}
+ ret = fimc_pipeline_s_power(p, 0);
+ fimc_md_set_camclk(sd, false);
+
fmd = entity_to_fimc_mdev(&sd->entity);
/* Disable PXLASYNC clock if this pipeline includes FIMC-IS */
@@ -242,12 +271,13 @@
* @pipeline: video pipeline structure
* @on: passed as the s_stream() callback argument
*/
-static int __fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
+static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on)
{
static const u8 seq[2][IDX_MAX] = {
{ IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE },
{ IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP },
};
+ struct fimc_pipeline *p = to_fimc_pipeline(ep);
int i, ret = 0;
if (p->subdevs[IDX_SENSOR] == NULL)
@@ -271,12 +301,38 @@
}
/* Media pipeline operations for the FIMC/FIMC-LITE video device driver */
-static const struct fimc_pipeline_ops fimc_pipeline_ops = {
+static const struct exynos_media_pipeline_ops fimc_pipeline_ops = {
.open = __fimc_pipeline_open,
.close = __fimc_pipeline_close,
.set_stream = __fimc_pipeline_s_stream,
};
+static struct exynos_media_pipeline *fimc_md_pipeline_create(
+ struct fimc_md *fmd)
+{
+ struct fimc_pipeline *p;
+
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return NULL;
+
+ list_add_tail(&p->list, &fmd->pipelines);
+
+ p->ep.ops = &fimc_pipeline_ops;
+ return &p->ep;
+}
+
+static void fimc_md_pipelines_free(struct fimc_md *fmd)
+{
+ while (!list_empty(&fmd->pipelines)) {
+ struct fimc_pipeline *p;
+
+ p = list_entry(fmd->pipelines.next, typeof(*p), list);
+ list_del(&p->list);
+ kfree(p);
+ }
+}
+
/*
* Sensor subdevice helper functions
*/
@@ -592,6 +648,7 @@
struct fimc_lite *fimc_lite)
{
struct v4l2_subdev *sd;
+ struct exynos_media_pipeline *ep;
int ret;
if (WARN_ON(fimc_lite->index >= FIMC_LITE_MAX_DEVS ||
@@ -600,7 +657,12 @@
sd = &fimc_lite->subdev;
sd->grp_id = GRP_ID_FLITE;
- v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
+
+ ep = fimc_md_pipeline_create(fmd);
+ if (!ep)
+ return -ENOMEM;
+
+ v4l2_set_subdev_hostdata(sd, ep);
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
if (!ret)
@@ -614,6 +676,7 @@
static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc)
{
struct v4l2_subdev *sd;
+ struct exynos_media_pipeline *ep;
int ret;
if (WARN_ON(fimc->id >= FIMC_MAX_DEVS || fmd->fimc[fimc->id]))
@@ -621,7 +684,12 @@
sd = &fimc->vid_cap.subdev;
sd->grp_id = GRP_ID_FIMC;
- v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
+
+ ep = fimc_md_pipeline_create(fmd);
+ if (!ep)
+ return -ENOMEM;
+
+ v4l2_set_subdev_hostdata(sd, ep);
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
if (!ret) {
@@ -736,8 +804,6 @@
if (!strcmp(pdev->name, CSIS_DRIVER_NAME)) {
plat_entity = IDX_CSIS;
- } else if (!strcmp(pdev->name, FIMC_LITE_DRV_NAME)) {
- plat_entity = IDX_FLITE;
} else {
p = strstr(pdev->name, "fimc");
if (p && *(p + 4) == 0)
@@ -797,17 +863,19 @@
int i;
for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (fmd->fimc[i] == NULL)
+ struct fimc_dev *dev = fmd->fimc[i];
+ if (dev == NULL)
continue;
- v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
- fmd->fimc[i]->pipeline_ops = NULL;
+ v4l2_device_unregister_subdev(&dev->vid_cap.subdev);
+ dev->vid_cap.ve.pipe = NULL;
fmd->fimc[i] = NULL;
}
for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
- if (fmd->fimc_lite[i] == NULL)
+ struct fimc_lite *dev = fmd->fimc_lite[i];
+ if (dev == NULL)
continue;
- v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
- fmd->fimc_lite[i]->pipeline_ops = NULL;
+ v4l2_device_unregister_subdev(&dev->subdev);
+ dev->ve.pipe = NULL;
fmd->fimc_lite[i] = NULL;
}
for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
@@ -880,18 +948,6 @@
v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]\n",
source->name, flags ? '=' : '-', sink->name);
-
- if (flags == 0 || sensor == NULL)
- continue;
-
- if (!WARN_ON(si == NULL)) {
- unsigned long irq_flags;
- struct fimc_sensor_info *inf = source_to_sensor_info(si);
-
- spin_lock_irqsave(&fmd->slock, irq_flags);
- inf->host = fmd->fimc[i];
- spin_unlock_irqrestore(&fmd->slock, irq_flags);
- }
}
for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
@@ -929,7 +985,7 @@
continue;
source = &fimc->subdev.entity;
- sink = &fimc->vfd.entity;
+ sink = &fimc->ve.vdev.entity;
/* FIMC-LITE's subdev and video node */
ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
sink, 0, 0);
@@ -1066,7 +1122,7 @@
continue;
source = &fmd->fimc[i]->vid_cap.subdev.entity;
- sink = &fmd->fimc[i]->vid_cap.vfd.entity;
+ sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
sink, 0, flags);
@@ -1231,66 +1287,98 @@
return __fimc_md_set_camclk(fmd, si, on);
}
-static int fimc_md_link_notify(struct media_pad *source,
- struct media_pad *sink, u32 flags)
+static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
{
- struct fimc_lite *fimc_lite = NULL;
- struct fimc_dev *fimc = NULL;
- struct fimc_pipeline *pipeline;
- struct v4l2_subdev *sd;
- struct mutex *lock;
- int i, ret = 0;
- int ref_count;
+ struct exynos_video_entity *ve;
+ struct fimc_pipeline *p;
+ struct video_device *vdev;
+ int ret;
- if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+ vdev = media_entity_to_video_device(entity);
+ if (vdev->entity.use_count == 0)
return 0;
- sd = media_entity_to_v4l2_subdev(sink->entity);
-
- switch (sd->grp_id) {
- case GRP_ID_FLITE:
- fimc_lite = v4l2_get_subdevdata(sd);
- if (WARN_ON(fimc_lite == NULL))
- return 0;
- pipeline = &fimc_lite->pipeline;
- lock = &fimc_lite->lock;
- break;
- case GRP_ID_FIMC:
- fimc = v4l2_get_subdevdata(sd);
- if (WARN_ON(fimc == NULL))
- return 0;
- pipeline = &fimc->pipeline;
- lock = &fimc->lock;
- break;
- default:
+ ve = vdev_to_exynos_video_entity(vdev);
+ p = to_fimc_pipeline(ve->pipe);
+ /*
+ * Nothing to do if we are disabling the pipeline, some link
+ * has been disconnected and p->subdevs array is cleared now.
+ */
+ if (!enable && p->subdevs[IDX_SENSOR] == NULL)
return 0;
+
+ if (enable)
+ ret = __fimc_pipeline_open(ve->pipe, entity, true);
+ else
+ ret = __fimc_pipeline_close(ve->pipe);
+
+ if (ret == 0 && !enable)
+ memset(p->subdevs, 0, sizeof(p->subdevs));
+
+ return ret;
+}
+
+/* Locking: called with entity->parent->graph_mutex mutex held. */
+static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
+{
+ struct media_entity *entity_err = entity;
+ struct media_entity_graph graph;
+ int ret;
+
+ /*
+ * Walk current graph and call the pipeline open/close routine for each
+ * opened video node that belongs to the graph of entities connected
+ * through active links. This is needed as we cannot power on/off the
+ * subdevs in random order.
+ */
+ media_entity_graph_walk_start(&graph, entity);
+
+ while ((entity = media_entity_graph_walk_next(&graph))) {
+ if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+ continue;
+
+ ret = __fimc_md_modify_pipeline(entity, enable);
+
+ if (ret < 0)
+ goto err;
}
- mutex_lock(lock);
- ref_count = fimc ? fimc->vid_cap.refcnt : fimc_lite->ref_count;
+ return 0;
+ err:
+ media_entity_graph_walk_start(&graph, entity_err);
- if (!(flags & MEDIA_LNK_FL_ENABLED)) {
- if (ref_count > 0) {
- ret = __fimc_pipeline_close(pipeline);
- if (!ret && fimc)
- fimc_ctrls_delete(fimc->vid_cap.ctx);
- }
- for (i = 0; i < IDX_MAX; i++)
- pipeline->subdevs[i] = NULL;
- } else if (ref_count > 0) {
- /*
- * Link activation. Enable power of pipeline elements only if
- * the pipeline is already in use, i.e. its video node is open.
- * Recreate the controls destroyed during the link deactivation.
- */
- ret = __fimc_pipeline_open(pipeline,
- source->entity, true);
- if (!ret && fimc)
- ret = fimc_capture_ctrls_create(fimc);
+ while ((entity_err = media_entity_graph_walk_next(&graph))) {
+ if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE)
+ continue;
+
+ __fimc_md_modify_pipeline(entity_err, !enable);
+
+ if (entity_err == entity)
+ break;
}
- mutex_unlock(lock);
- return ret ? -EPIPE : ret;
+ return ret;
+}
+
+static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
+ unsigned int notification)
+{
+ struct media_entity *sink = link->sink->entity;
+ int ret = 0;
+
+ /* Before link disconnection */
+ if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
+ if (!(flags & MEDIA_LNK_FL_ENABLED))
+ ret = __fimc_md_modify_pipelines(sink, false);
+ else
+ ; /* TODO: Link state change validation */
+ /* After link activation */
+ } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+ (link->flags & MEDIA_LNK_FL_ENABLED)) {
+ ret = __fimc_md_modify_pipelines(sink, true);
+ }
+
+ return ret ? -EPIPE : 0;
}
static ssize_t fimc_md_sysfs_show(struct device *dev,
@@ -1370,6 +1458,7 @@
spin_lock_init(&fmd->slock);
fmd->pdev = pdev;
+ INIT_LIST_HEAD(&fmd->pipelines);
strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
sizeof(fmd->media_dev.model));
@@ -1457,6 +1546,7 @@
return 0;
device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
fimc_md_unregister_entities(fmd);
+ fimc_md_pipelines_free(fmd);
media_device_unregister(&fmd->media_dev);
fimc_md_put_clocks(fmd);
return 0;
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 44d86b6..62599fd 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -18,6 +18,7 @@
#include <media/media-entity.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
+#include <media/s5p_fimc.h>
#include "fimc-core.h"
#include "fimc-lite.h"
@@ -40,6 +41,29 @@
FIMC_MAX_WBCLKS
};
+enum fimc_subdev_index {
+ IDX_SENSOR,
+ IDX_CSIS,
+ IDX_FLITE,
+ IDX_IS_ISP,
+ IDX_FIMC,
+ IDX_MAX,
+};
+
+/*
+ * This structure represents a chain of media entities, including a data
+ * source entity (e.g. an image sensor subdevice), a data capture entity
+ * - a video capture device node and any remaining entities.
+ */
+struct fimc_pipeline {
+ struct exynos_media_pipeline ep;
+ struct list_head list;
+ struct media_entity *vdev_entity;
+ struct v4l2_subdev *subdevs[IDX_MAX];
+};
+
+#define to_fimc_pipeline(_ep) container_of(_ep, struct fimc_pipeline, ep)
+
struct fimc_csis_info {
struct v4l2_subdev *sd;
int id;
@@ -104,17 +128,11 @@
struct pinctrl_state *state_idle;
} pinctl;
bool user_subdev_api;
+
spinlock_t slock;
+ struct list_head pipelines;
};
-#define is_subdev_pad(pad) (pad == NULL || \
- media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV)
-
-#define me_subtype(me) \
- ((me->type) & (MEDIA_ENT_TYPE_MASK | MEDIA_ENT_SUBTYPE_MASK))
-
-#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)
-
static inline
struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
{
@@ -127,14 +145,14 @@
container_of(me->parent, struct fimc_md, media_dev);
}
-static inline void fimc_md_graph_lock(struct fimc_dev *fimc)
+static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
{
- mutex_lock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
+ mutex_lock(&ve->vdev.entity.parent->graph_mutex);
}
-static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
+static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
{
- mutex_unlock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
+ mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
}
int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
@@ -149,4 +167,16 @@
#define fimc_md_is_isp_available(node) (false)
#endif /* CONFIG_OF */
+static inline struct v4l2_subdev *__fimc_md_get_subdev(
+ struct exynos_media_pipeline *ep,
+ unsigned int index)
+{
+ struct fimc_pipeline *p = to_fimc_pipeline(ep);
+
+ if (!p || index >= IDX_MAX)
+ return NULL;
+ else
+ return p->subdevs[index];
+}
+
#endif
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 254d70f..0914230 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -1,8 +1,8 @@
/*
- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
+ * Samsung S5P/EXYNOS SoC series MIPI-CSI receiver driver
*
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -66,11 +66,12 @@
/* Interrupt mask */
#define S5PCSIS_INTMSK 0x10
-#define S5PCSIS_INTMSK_EN_ALL 0xf000103f
#define S5PCSIS_INTMSK_EVEN_BEFORE (1 << 31)
#define S5PCSIS_INTMSK_EVEN_AFTER (1 << 30)
#define S5PCSIS_INTMSK_ODD_BEFORE (1 << 29)
#define S5PCSIS_INTMSK_ODD_AFTER (1 << 28)
+#define S5PCSIS_INTMSK_FRAME_START (1 << 27)
+#define S5PCSIS_INTMSK_FRAME_END (1 << 26)
#define S5PCSIS_INTMSK_ERR_SOT_HS (1 << 12)
#define S5PCSIS_INTMSK_ERR_LOST_FS (1 << 5)
#define S5PCSIS_INTMSK_ERR_LOST_FE (1 << 4)
@@ -78,6 +79,8 @@
#define S5PCSIS_INTMSK_ERR_ECC (1 << 2)
#define S5PCSIS_INTMSK_ERR_CRC (1 << 1)
#define S5PCSIS_INTMSK_ERR_UNKNOWN (1 << 0)
+#define S5PCSIS_INTMSK_EXYNOS4_EN_ALL 0xf000103f
+#define S5PCSIS_INTMSK_EXYNOS5_EN_ALL 0xfc00103f
/* Interrupt source */
#define S5PCSIS_INTSRC 0x14
@@ -88,6 +91,8 @@
#define S5PCSIS_INTSRC_ODD_AFTER (1 << 28)
#define S5PCSIS_INTSRC_ODD (0x3 << 28)
#define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xff << 28)
+#define S5PCSIS_INTSRC_FRAME_START (1 << 27)
+#define S5PCSIS_INTSRC_FRAME_END (1 << 26)
#define S5PCSIS_INTSRC_ERR_SOT_HS (0xf << 12)
#define S5PCSIS_INTSRC_ERR_LOST_FS (1 << 5)
#define S5PCSIS_INTSRC_ERR_LOST_FE (1 << 4)
@@ -151,6 +156,9 @@
{ S5PCSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" },
{ S5PCSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" },
{ S5PCSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" },
+ /* Frame start/end */
+ { S5PCSIS_INTSRC_FRAME_START, "Frame Start" },
+ { S5PCSIS_INTSRC_FRAME_END, "Frame End" },
};
#define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
@@ -159,6 +167,11 @@
unsigned int len;
};
+struct csis_drvdata {
+ /* Mask of all used interrupts in S5PCSIS_INTMSK register */
+ u32 interrupt_mask;
+};
+
/**
* struct csis_state - the driver's internal state data structure
* @lock: mutex serializing the subdev and power management operations,
@@ -171,6 +184,7 @@
* @supplies: CSIS regulator supplies
* @clock: CSIS clocks
* @irq: requested s5p-mipi-csis irq number
+ * @interrupt_mask: interrupt mask of the all used interrupts
* @flags: the state variable for power and streaming control
* @clock_frequency: device bus clock frequency
* @hs_settle: HS-RX settle time
@@ -193,6 +207,7 @@
struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
struct clk *clock[NUM_CSIS_CLOCKS];
int irq;
+ u32 interrupt_mask;
u32 flags;
u32 clk_frequency;
@@ -274,9 +289,10 @@
static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
{
u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
-
- val = on ? val | S5PCSIS_INTMSK_EN_ALL :
- val & ~S5PCSIS_INTMSK_EN_ALL;
+ if (on)
+ val |= state->interrupt_mask;
+ else
+ val &= ~state->interrupt_mask;
s5pcsis_write(state, S5PCSIS_INTMSK, val);
}
@@ -771,8 +787,12 @@
#define s5pcsis_parse_dt(pdev, state) (-ENOSYS)
#endif
+static const struct of_device_id s5pcsis_of_match[];
+
static int s5pcsis_probe(struct platform_device *pdev)
{
+ const struct of_device_id *of_id;
+ const struct csis_drvdata *drv_data;
struct device *dev = &pdev->dev;
struct resource *mem_res;
struct csis_state *state;
@@ -787,10 +807,19 @@
spin_lock_init(&state->slock);
state->pdev = pdev;
- if (dev->of_node)
+ if (dev->of_node) {
+ of_id = of_match_node(s5pcsis_of_match, dev->of_node);
+ if (WARN_ON(of_id == NULL))
+ return -EINVAL;
+
+ drv_data = of_id->data;
+ state->interrupt_mask = drv_data->interrupt_mask;
+
ret = s5pcsis_parse_dt(pdev, state);
- else
+ } else {
ret = s5pcsis_get_platform_data(pdev, state);
+ }
+
if (ret < 0)
return ret;
@@ -994,9 +1023,25 @@
SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
};
+static const struct csis_drvdata exynos4_csis_drvdata = {
+ .interrupt_mask = S5PCSIS_INTMSK_EXYNOS4_EN_ALL,
+};
+
+static const struct csis_drvdata exynos5_csis_drvdata = {
+ .interrupt_mask = S5PCSIS_INTMSK_EXYNOS5_EN_ALL,
+};
+
static const struct of_device_id s5pcsis_of_match[] = {
- { .compatible = "samsung,s5pv210-csis" },
- { .compatible = "samsung,exynos4210-csis" },
+ {
+ .compatible = "samsung,s5pv210-csis",
+ .data = &exynos4_csis_drvdata,
+ }, {
+ .compatible = "samsung,exynos4210-csis",
+ .data = &exynos4_csis_drvdata,
+ }, {
+ .compatible = "samsung,exynos5250-csis",
+ .data = &exynos5_csis_drvdata,
+ },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, s5pcsis_of_match);
diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index 3a6a0dc..221ec42 100644
--- a/drivers/media/platform/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -1475,7 +1475,6 @@
.release = video_device_release,
.tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL,
- .current_norm = V4L2_STD_NTSC_M,
};
static int viu_of_probe(struct platform_device *op)
@@ -1546,6 +1545,7 @@
viu_dev->vidq.timeout.function = viu_vid_timeout;
viu_dev->vidq.timeout.data = (unsigned long)viu_dev;
init_timer(&viu_dev->vidq.timeout);
+ viu_dev->std = V4L2_STD_NTSC_M;
viu_dev->first = 1;
/* Allocate memory for video device */
diff --git a/drivers/media/platform/indycam.c b/drivers/media/platform/indycam.c
index 5482363..f1d192b 100644
--- a/drivers/media/platform/indycam.c
+++ b/drivers/media/platform/indycam.c
@@ -23,7 +23,6 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include "indycam.h"
@@ -283,20 +282,9 @@
/* I2C-interface */
-static int indycam_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct indycam *camera = to_indycam(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM,
- camera->version);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops indycam_core_ops = {
- .g_chip_ident = indycam_g_chip_ident,
.g_ctrl = indycam_g_ctrl,
.s_ctrl = indycam_s_ctrl,
};
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index 7585646..540516c 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -1033,6 +1033,7 @@
*vfd = deinterlace_videodev;
vfd->lock = &pcdev->dev_mutex;
+ vfd->v4l2_dev = &pcdev->v4l2_dev;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) {
diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
index d030f9b..1f079ff 100644
--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
@@ -27,7 +27,6 @@
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/delay.h>
@@ -469,7 +468,7 @@
goto out;
cam->pdev = pdev;
mcam = &cam->mcam;
- mcam->chip_id = V4L2_IDENT_CAFE;
+ mcam->chip_id = MCAM_CAFE;
spin_lock_init(&mcam->dev_lock);
init_waitqueue_head(&cam->smbus_wait);
mcam->plat_power_up = cafe_ctlr_power_up;
@@ -501,6 +500,7 @@
printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
goto out_disable;
}
+ mcam->regs_size = pci_resource_len(pdev, 0);
ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
if (ret)
goto out_iounmap;
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index 64ab91e..0821ed0 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -23,7 +23,6 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
#include <media/ov7670.h>
#include <media/videobuf2-vmalloc.h>
#include <media/videobuf2-dma-contig.h>
@@ -336,7 +335,7 @@
mcam_reg_clear_bit(cam, REG_CTRL1, C1_TWOBUFS);
} else
mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
- if (cam->chip_id == V4L2_IDENT_CAFE)
+ if (cam->chip_id == MCAM_CAFE)
mcam_reg_write(cam, REG_UBAR, 0); /* 32 bits only */
}
@@ -796,7 +795,6 @@
*/
static int mcam_cam_init(struct mcam_camera *cam)
{
- struct v4l2_dbg_chip_ident chip;
int ret;
mutex_lock(&cam->s_mutex);
@@ -804,24 +802,8 @@
cam_warn(cam, "Cam init with device in funky state %d",
cam->state);
ret = __mcam_cam_reset(cam);
- if (ret)
- goto out;
- chip.ident = V4L2_IDENT_NONE;
- chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
- chip.match.addr = cam->sensor_addr;
- ret = sensor_call(cam, core, g_chip_ident, &chip);
- if (ret)
- goto out;
- cam->sensor_type = chip.ident;
- if (cam->sensor_type != V4L2_IDENT_OV7670) {
- cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
- ret = -EINVAL;
- goto out;
- }
-/* Get/set parameters? */
- ret = 0;
+ /* Get/set parameters? */
cam->state = S_IDLE;
-out:
mcam_ctlr_power_down(cam);
mutex_unlock(&cam->s_mutex);
return ret;
@@ -1362,6 +1344,12 @@
return 0;
}
+static int mcam_vidioc_g_std(struct file *filp, void *priv, v4l2_std_id *a)
+{
+ *a = V4L2_STD_NTSC_M;
+ return 0;
+}
+
/*
* G/S_PARM. Most of this is done by the sensor, but we are
* the level which controls the number of read buffers.
@@ -1392,20 +1380,6 @@
return ret;
}
-static int mcam_vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct mcam_camera *cam = priv;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (v4l2_chip_match_host(&chip->match)) {
- chip->ident = cam->chip_id;
- return 0;
- }
- return sensor_call(cam, core, g_chip_ident, chip);
-}
-
static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
struct v4l2_frmsizeenum *sizes)
{
@@ -1436,12 +1410,11 @@
{
struct mcam_camera *cam = priv;
- if (v4l2_chip_match_host(®->match)) {
- reg->val = mcam_reg_read(cam, reg->reg);
- reg->size = 4;
- return 0;
- }
- return sensor_call(cam, core, g_register, reg);
+ if (reg->reg > cam->regs_size - 4)
+ return -EINVAL;
+ reg->val = mcam_reg_read(cam, reg->reg);
+ reg->size = 4;
+ return 0;
}
static int mcam_vidioc_s_register(struct file *file, void *priv,
@@ -1449,11 +1422,10 @@
{
struct mcam_camera *cam = priv;
- if (v4l2_chip_match_host(®->match)) {
- mcam_reg_write(cam, reg->reg, reg->val);
- return 0;
- }
- return sensor_call(cam, core, s_register, reg);
+ if (reg->reg > cam->regs_size - 4)
+ return -EINVAL;
+ mcam_reg_write(cam, reg->reg, reg->val);
+ return 0;
}
#endif
@@ -1467,6 +1439,7 @@
.vidioc_g_input = mcam_vidioc_g_input,
.vidioc_s_input = mcam_vidioc_s_input,
.vidioc_s_std = mcam_vidioc_s_std,
+ .vidioc_g_std = mcam_vidioc_g_std,
.vidioc_reqbufs = mcam_vidioc_reqbufs,
.vidioc_querybuf = mcam_vidioc_querybuf,
.vidioc_qbuf = mcam_vidioc_qbuf,
@@ -1477,7 +1450,6 @@
.vidioc_s_parm = mcam_vidioc_s_parm,
.vidioc_enum_framesizes = mcam_vidioc_enum_framesizes,
.vidioc_enum_frameintervals = mcam_vidioc_enum_frameintervals,
- .vidioc_g_chip_ident = mcam_vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = mcam_vidioc_g_register,
.vidioc_s_register = mcam_vidioc_s_register,
@@ -1593,7 +1565,6 @@
static struct video_device mcam_v4l_template = {
.name = "mcam",
.tvnorms = V4L2_STD_NTSC_M,
- .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */
.fops = &mcam_v4l_fops,
.ioctl_ops = &mcam_v4l_ioctl_ops,
@@ -1695,7 +1666,7 @@
if (buffer_mode >= 0)
cam->buffer_mode = buffer_mode;
if (cam->buffer_mode == B_DMA_sg &&
- cam->chip_id == V4L2_IDENT_CAFE) {
+ cam->chip_id == MCAM_CAFE) {
printk(KERN_ERR "marvell-cam: Cafe can't do S/G I/O, "
"attempting vmalloc mode instead\n");
cam->buffer_mode = B_vmalloc;
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h
index 01dec9e..520c8de 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.h
+++ b/drivers/media/platform/marvell-ccic/mcam-core.h
@@ -53,6 +53,11 @@
B_DMA_sg = 2
};
+enum mcam_chip_id {
+ MCAM_CAFE,
+ MCAM_ARMADA610,
+};
+
/*
* Is a given buffer mode supported by the current kernel configuration?
*/
@@ -96,9 +101,10 @@
*/
struct i2c_adapter *i2c_adapter;
unsigned char __iomem *regs;
+ unsigned regs_size; /* size in bytes of the register space */
spinlock_t dev_lock;
struct device *dev; /* For messages, dma alloc */
- unsigned int chip_id;
+ enum mcam_chip_id chip_id;
short int clock_speed; /* Sensor clock speed, default 30 */
short int use_smbus; /* SMBUS or straight I2c? */
enum mcam_buffer_mode buffer_mode;
@@ -152,7 +158,6 @@
void (*frame_complete)(struct mcam_camera *cam, int frame);
/* Current operating parameters */
- u32 sensor_type; /* Currently ov7670 only */
struct v4l2_pix_format pix_format;
enum v4l2_mbus_pixelcode mbus_code;
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index c4c17fe..a634888 100644
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -18,7 +18,6 @@
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/mmp-camera.h>
#include <linux/device.h>
#include <linux/platform_device.h>
@@ -185,7 +184,7 @@
mcam->plat_power_down = mmpcam_power_down;
mcam->dev = &pdev->dev;
mcam->use_smbus = 0;
- mcam->chip_id = V4L2_IDENT_ARMADA610;
+ mcam->chip_id = MCAM_ARMADA610;
mcam->buffer_mode = B_DMA_sg;
spin_lock_init(&mcam->dev_lock);
/*
@@ -203,6 +202,7 @@
ret = -ENODEV;
goto out_free;
}
+ mcam->regs_size = resource_size(res);
/*
* Power/clock memory is elsewhere; get it too. Perhaps this
* should really be managed outside of this driver?
diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c
index 4cc7f65d..6a17676 100644
--- a/drivers/media/platform/mem2mem_testdev.c
+++ b/drivers/media/platform/mem2mem_testdev.c
@@ -1051,6 +1051,7 @@
*vfd = m2mtest_videodev;
vfd->lock = &dev->dev_mutex;
+ vfd->v4l2_dev = &dev->v4l2_dev;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
if (ret) {
@@ -1061,7 +1062,7 @@
video_set_drvdata(vfd, dev);
snprintf(vfd->name, sizeof(vfd->name), "%s", m2mtest_videodev.name);
dev->vfd = vfd;
- v4l2_info(&dev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
+ v4l2_info(&dev->v4l2_dev,
"Device registered as /dev/video%d\n", vfd->num);
setup_timer(&dev->timer, device_isr, (long)dev);
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c
index f7440e5..c690435 100644
--- a/drivers/media/platform/mx2_emmaprp.c
+++ b/drivers/media/platform/mx2_emmaprp.c
@@ -937,6 +937,7 @@
*vfd = emmaprp_videodev;
vfd->lock = &pcdev->dev_mutex;
+ vfd->v4l2_dev = &pcdev->v4l2_dev;
video_set_drvdata(vfd, pcdev);
snprintf(vfd->name, sizeof(vfd->name), "%s", emmaprp_videodev.name);
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index d338b19..dfd0a21 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -335,8 +335,6 @@
ovl = ovid->overlays[0];
switch (pix->pixelformat) {
- case 0:
- break;
case V4L2_PIX_FMT_YUYV:
mode = OMAP_DSS_COLOR_YUV2;
break;
@@ -358,6 +356,7 @@
break;
default:
mode = -EINVAL;
+ break;
}
return mode;
}
diff --git a/drivers/media/platform/omap24xxcam.c b/drivers/media/platform/omap24xxcam.c
index debb44c..d2b440c 100644
--- a/drivers/media/platform/omap24xxcam.c
+++ b/drivers/media/platform/omap24xxcam.c
@@ -1656,7 +1656,7 @@
}
vfd->release = video_device_release;
- vfd->parent = cam->dev;
+ vfd->v4l2_dev = &cam->v4l2_dev;
strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
vfd->fops = &omap24xxcam_fops;
@@ -1752,6 +1752,11 @@
cam->dev = &pdev->dev;
+ if (v4l2_device_register(&pdev->dev, &cam->v4l2_dev)) {
+ dev_err(&pdev->dev, "v4l2_device_register failed\n");
+ goto err;
+ }
+
/*
* Impose a lower limit on the amount of memory allocated for
* capture. We require at least enough memory to double-buffer
@@ -1849,6 +1854,8 @@
cam->mmio_base_phys = 0;
}
+ v4l2_device_unregister(&cam->v4l2_dev);
+
kfree(cam);
return 0;
diff --git a/drivers/media/platform/omap24xxcam.h b/drivers/media/platform/omap24xxcam.h
index c439595..7f6f791 100644
--- a/drivers/media/platform/omap24xxcam.h
+++ b/drivers/media/platform/omap24xxcam.h
@@ -29,6 +29,7 @@
#include <media/videobuf-dma-sg.h>
#include <media/v4l2-int-device.h>
+#include <media/v4l2-device.h>
/*
*
@@ -462,6 +463,8 @@
*/
struct mutex mutex;
+ struct v4l2_device v4l2_dev;
+
/*** general driver state information ***/
atomic_t users;
/*
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 1d7dbd5..df3a0ec 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -792,9 +792,9 @@
/*
* isp_pipeline_link_notify - Link management notification callback
- * @source: Pad at the start of the link
- * @sink: Pad at the end of the link
+ * @link: The link
* @flags: New link flags that will be applied
+ * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*)
*
* React to link management on powered pipelines by updating the use count of
* all entities in the source and sink sides of the link. Entities are powered
@@ -804,29 +804,38 @@
* off is assumed to never fail. This function will not fail for disconnection
* events.
*/
-static int isp_pipeline_link_notify(struct media_pad *source,
- struct media_pad *sink, u32 flags)
+static int isp_pipeline_link_notify(struct media_link *link, u32 flags,
+ unsigned int notification)
{
- int source_use = isp_pipeline_pm_use_count(source->entity);
- int sink_use = isp_pipeline_pm_use_count(sink->entity);
+ struct media_entity *source = link->source->entity;
+ struct media_entity *sink = link->sink->entity;
+ int source_use = isp_pipeline_pm_use_count(source);
+ int sink_use = isp_pipeline_pm_use_count(sink);
int ret;
- if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+ if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+ !(link->flags & MEDIA_LNK_FL_ENABLED)) {
/* Powering off entities is assumed to never fail. */
- isp_pipeline_pm_power(source->entity, -sink_use);
- isp_pipeline_pm_power(sink->entity, -source_use);
+ isp_pipeline_pm_power(source, -sink_use);
+ isp_pipeline_pm_power(sink, -source_use);
return 0;
}
- ret = isp_pipeline_pm_power(source->entity, sink_use);
- if (ret < 0)
+ if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+ (flags & MEDIA_LNK_FL_ENABLED)) {
+
+ ret = isp_pipeline_pm_power(source, sink_use);
+ if (ret < 0)
+ return ret;
+
+ ret = isp_pipeline_pm_power(sink, source_use);
+ if (ret < 0)
+ isp_pipeline_pm_power(source, -sink_use);
+
return ret;
+ }
- ret = isp_pipeline_pm_power(sink->entity, source_use);
- if (ret < 0)
- isp_pipeline_pm_power(source->entity, -sink_use);
-
- return ret;
+ return 0;
}
/* -----------------------------------------------------------------------------
@@ -877,7 +886,7 @@
if (!(pad->flags & MEDIA_PAD_FL_SINK))
break;
- pad = media_entity_remote_source(pad);
+ pad = media_entity_remote_pad(pad);
if (pad == NULL ||
media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
break;
@@ -967,7 +976,7 @@
if (!(pad->flags & MEDIA_PAD_FL_SINK))
break;
- pad = media_entity_remote_source(pad);
+ pad = media_entity_remote_pad(pad);
if (pad == NULL ||
media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
break;
@@ -1083,7 +1092,7 @@
pipe = to_isp_pipeline(me);
if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
return 0;
- pad = media_entity_remote_source(&pipe->output->pad);
+ pad = media_entity_remote_pad(&pipe->output->pad);
return pad->entity == me;
}
@@ -2249,6 +2258,7 @@
ret = iommu_attach_device(isp->domain, &pdev->dev);
if (ret) {
dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret);
+ ret = -EPROBE_DEFER;
goto free_domain;
}
@@ -2287,12 +2297,11 @@
iommu_detach_device(isp->domain, &pdev->dev);
free_domain:
iommu_domain_free(isp->domain);
+ isp->domain = NULL;
error_isp:
isp_xclk_cleanup(isp);
omap3isp_put(isp);
error:
- platform_set_drvdata(pdev, NULL);
-
mutex_destroy(&isp->isp_mutex);
return ret;
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 60e60aa..907a205 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -1120,7 +1120,7 @@
u32 syn_mode;
u32 ccdc_pattern;
- pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
+ pad = media_entity_remote_pad(&ccdc->pads[CCDC_PAD_SINK]);
sensor = media_entity_to_v4l2_subdev(pad->entity);
if (ccdc->input == CCDC_INPUT_PARALLEL)
pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index c5d84c9..e716514 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -158,13 +158,17 @@
* @ccp2: pointer to ISP CCP2 device
* @enable: enable/disable flag
*/
-static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
+static int ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
{
struct isp_device *isp = to_isp_device(ccp2);
+ int ret;
int i;
- if (enable && ccp2->vdds_csib)
- regulator_enable(ccp2->vdds_csib);
+ if (enable && ccp2->vdds_csib) {
+ ret = regulator_enable(ccp2->vdds_csib);
+ if (ret < 0)
+ return ret;
+ }
/* Enable/Disable all the LCx channels */
for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
@@ -179,6 +183,8 @@
if (!enable && ccp2->vdds_csib)
regulator_disable(ccp2->vdds_csib);
+
+ return 0;
}
/*
@@ -360,7 +366,7 @@
ccp2_pwr_cfg(ccp2);
- pad = media_entity_remote_source(&ccp2->pads[CCP2_PAD_SINK]);
+ pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]);
sensor = media_entity_to_v4l2_subdev(pad->entity);
pdata = sensor->host_priv;
@@ -851,7 +857,12 @@
ccp2_print_status(ccp2);
/* Enable CSI1/CCP2 interface */
- ccp2_if_enable(ccp2, 1);
+ ret = ccp2_if_enable(ccp2, 1);
+ if (ret < 0) {
+ if (ccp2->phy)
+ omap3isp_csiphy_release(ccp2->phy);
+ return ret;
+ }
break;
case ISP_PIPELINE_STREAM_SINGLESHOT:
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 783f4b0..6db245d 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -573,7 +573,7 @@
if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
return -EBUSY;
- pad = media_entity_remote_source(&csi2->pads[CSI2_PAD_SINK]);
+ pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]);
sensor = media_entity_to_v4l2_subdev(pad->entity);
pdata = sensor->host_priv;
diff --git a/drivers/media/platform/omap3isp/ispqueue.h b/drivers/media/platform/omap3isp/ispqueue.h
index 908dfd7..3e048ad 100644
--- a/drivers/media/platform/omap3isp/ispqueue.h
+++ b/drivers/media/platform/omap3isp/ispqueue.h
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
+#include <linux/mm_types.h>
#include <linux/mutex.h>
#include <linux/videodev2.h>
#include <linux/wait.h>
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 8dac175..a908d00 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -219,7 +219,7 @@
{
struct media_pad *remote;
- remote = media_entity_remote_source(&video->pad);
+ remote = media_entity_remote_pad(&video->pad);
if (remote == NULL ||
media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
@@ -314,7 +314,7 @@
* entity can be found, and stop checking the pipeline if the
* source entity isn't a subdev.
*/
- pad = media_entity_remote_source(pad);
+ pad = media_entity_remote_pad(pad);
if (pad == NULL)
return -EPIPE;
@@ -901,7 +901,7 @@
continue;
/* ISP entities have always sink pad == 0. Find source. */
- source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+ source_pad = media_entity_remote_pad(&ents[i]->pads[0]);
if (source_pad == NULL)
continue;
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index 70438a0..40b298a 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -845,7 +845,7 @@
int ret;
/* Retrieve format at the sensor subdev source pad */
- pad = media_entity_remote_source(&camif->pads[0]);
+ pad = media_entity_remote_pad(&camif->pads[0]);
if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
return -EPIPE;
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index 0d0fab1..b385747 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -341,10 +341,11 @@
int i;
for (i = 0; i < CLK_MAX_NUM; i++) {
- if (IS_ERR_OR_NULL(camif->clock[i]))
+ if (IS_ERR(camif->clock[i]))
continue;
clk_unprepare(camif->clock[i]);
clk_put(camif->clock[i]);
+ camif->clock[i] = ERR_PTR(-EINVAL);
}
}
@@ -352,6 +353,9 @@
{
int ret, i;
+ for (i = 1; i < CLK_MAX_NUM; i++)
+ camif->clock[i] = ERR_PTR(-EINVAL);
+
for (i = 0; i < CLK_MAX_NUM; i++) {
camif->clock[i] = clk_get(camif->dev, camif_clocks[i]);
if (IS_ERR(camif->clock[i])) {
diff --git a/drivers/media/platform/s3c-camif/camif-regs.c b/drivers/media/platform/s3c-camif/camif-regs.c
index 1a3b4fc..a9e3b16 100644
--- a/drivers/media/platform/s3c-camif/camif-regs.c
+++ b/drivers/media/platform/s3c-camif/camif-regs.c
@@ -379,7 +379,7 @@
camif_write(camif, S3C_CAMIF_REG_CISCPREDST(vp->id, vp->offset), cfg);
}
-void camif_s3c244x_hw_set_scaler(struct camif_vp *vp)
+static void camif_s3c244x_hw_set_scaler(struct camif_vp *vp)
{
struct camif_dev *camif = vp->camif;
struct camif_scaler *scaler = &vp->scaler;
@@ -426,7 +426,7 @@
scaler->main_h_ratio, scaler->main_v_ratio);
}
-void camif_s3c64xx_hw_set_scaler(struct camif_vp *vp)
+static void camif_s3c64xx_hw_set_scaler(struct camif_vp *vp)
{
struct camif_dev *camif = vp->camif;
struct camif_scaler *scaler = &vp->scaler;
@@ -601,6 +601,6 @@
pr_info("--- %s ---\n", label);
for (i = 0; i < ARRAY_SIZE(registers); i++) {
u32 cfg = readl(camif->io_base + registers[i].offset);
- printk(KERN_INFO "%s:\t0x%08x\n", registers[i].name, cfg);
+ dev_info(camif->dev, "%s:\t0x%08x\n", registers[i].name, cfg);
}
}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index d12faa6..a130dcd 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1424,7 +1424,7 @@
if (pdev->dev.of_node) {
const struct of_device_id *match;
- match = of_match_node(of_match_ptr(exynos_mfc_match),
+ match = of_match_node(exynos_mfc_match,
pdev->dev.of_node);
if (match)
driver_data = (struct s5p_mfc_variant *)match->data;
diff --git a/drivers/media/platform/s5p-tv/hdmi_drv.c b/drivers/media/platform/s5p-tv/hdmi_drv.c
index 4e86626..1b34c36 100644
--- a/drivers/media/platform/s5p-tv/hdmi_drv.c
+++ b/drivers/media/platform/s5p-tv/hdmi_drv.c
@@ -576,16 +576,22 @@
return hdmi_streamoff(hdev);
}
-static void hdmi_resource_poweron(struct hdmi_resources *res)
+static int hdmi_resource_poweron(struct hdmi_resources *res)
{
+ int ret;
+
/* turn HDMI power on */
- regulator_bulk_enable(res->regul_count, res->regul_bulk);
+ ret = regulator_bulk_enable(res->regul_count, res->regul_bulk);
+ if (ret < 0)
+ return ret;
/* power-on hdmi physical interface */
clk_enable(res->hdmiphy);
/* use VPP as parent clock; HDMIPHY is not working yet */
clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
/* turn clocks on */
clk_enable(res->sclk_hdmi);
+
+ return 0;
}
static void hdmi_resource_poweroff(struct hdmi_resources *res)
@@ -728,11 +734,13 @@
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
- int ret = 0;
+ int ret;
dev_dbg(dev, "%s\n", __func__);
- hdmi_resource_poweron(&hdev->res);
+ ret = hdmi_resource_poweron(&hdev->res);
+ if (ret < 0)
+ return ret;
/* starting MHL */
ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
@@ -755,6 +763,15 @@
.runtime_resume = hdmi_runtime_resume,
};
+static void hdmi_resource_clear_clocks(struct hdmi_resources *res)
+{
+ res->hdmi = ERR_PTR(-EINVAL);
+ res->sclk_hdmi = ERR_PTR(-EINVAL);
+ res->sclk_pixel = ERR_PTR(-EINVAL);
+ res->sclk_hdmiphy = ERR_PTR(-EINVAL);
+ res->hdmiphy = ERR_PTR(-EINVAL);
+}
+
static void hdmi_resources_cleanup(struct hdmi_device *hdev)
{
struct hdmi_resources *res = &hdev->res;
@@ -765,17 +782,18 @@
regulator_bulk_free(res->regul_count, res->regul_bulk);
/* kfree is NULL-safe */
kfree(res->regul_bulk);
- if (!IS_ERR_OR_NULL(res->hdmiphy))
+ if (!IS_ERR(res->hdmiphy))
clk_put(res->hdmiphy);
- if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
+ if (!IS_ERR(res->sclk_hdmiphy))
clk_put(res->sclk_hdmiphy);
- if (!IS_ERR_OR_NULL(res->sclk_pixel))
+ if (!IS_ERR(res->sclk_pixel))
clk_put(res->sclk_pixel);
- if (!IS_ERR_OR_NULL(res->sclk_hdmi))
+ if (!IS_ERR(res->sclk_hdmi))
clk_put(res->sclk_hdmi);
- if (!IS_ERR_OR_NULL(res->hdmi))
+ if (!IS_ERR(res->hdmi))
clk_put(res->hdmi);
memset(res, 0, sizeof(*res));
+ hdmi_resource_clear_clocks(res);
}
static int hdmi_resources_init(struct hdmi_device *hdev)
@@ -793,8 +811,9 @@
dev_dbg(dev, "HDMI resource init\n");
memset(res, 0, sizeof(*res));
- /* get clocks, power */
+ hdmi_resource_clear_clocks(res);
+ /* get clocks, power */
res->hdmi = clk_get(dev, "hdmi");
if (IS_ERR(res->hdmi)) {
dev_err(dev, "failed to get clock 'hdmi'\n");
diff --git a/drivers/media/platform/s5p-tv/mixer_drv.c b/drivers/media/platform/s5p-tv/mixer_drv.c
index 5733033..51805a5 100644
--- a/drivers/media/platform/s5p-tv/mixer_drv.c
+++ b/drivers/media/platform/s5p-tv/mixer_drv.c
@@ -211,6 +211,15 @@
return ret;
}
+static void mxr_resource_clear_clocks(struct mxr_resources *res)
+{
+ res->mixer = ERR_PTR(-EINVAL);
+ res->vp = ERR_PTR(-EINVAL);
+ res->sclk_mixer = ERR_PTR(-EINVAL);
+ res->sclk_hdmi = ERR_PTR(-EINVAL);
+ res->sclk_dac = ERR_PTR(-EINVAL);
+}
+
static void mxr_release_plat_resources(struct mxr_device *mdev)
{
free_irq(mdev->res.irq, mdev);
@@ -222,15 +231,15 @@
{
struct mxr_resources *res = &mdev->res;
- if (!IS_ERR_OR_NULL(res->sclk_dac))
+ if (!IS_ERR(res->sclk_dac))
clk_put(res->sclk_dac);
- if (!IS_ERR_OR_NULL(res->sclk_hdmi))
+ if (!IS_ERR(res->sclk_hdmi))
clk_put(res->sclk_hdmi);
- if (!IS_ERR_OR_NULL(res->sclk_mixer))
+ if (!IS_ERR(res->sclk_mixer))
clk_put(res->sclk_mixer);
- if (!IS_ERR_OR_NULL(res->vp))
+ if (!IS_ERR(res->vp))
clk_put(res->vp);
- if (!IS_ERR_OR_NULL(res->mixer))
+ if (!IS_ERR(res->mixer))
clk_put(res->mixer);
}
@@ -239,6 +248,8 @@
struct mxr_resources *res = &mdev->res;
struct device *dev = mdev->dev;
+ mxr_resource_clear_clocks(res);
+
res->mixer = clk_get(dev, "mixer");
if (IS_ERR(res->mixer)) {
mxr_err(mdev, "failed to get clock 'mixer'\n");
@@ -299,6 +310,7 @@
mxr_release_clocks(mdev);
mxr_release_plat_resources(mdev);
memset(&mdev->res, 0, sizeof(mdev->res));
+ mxr_resource_clear_clocks(&mdev->res);
}
static void mxr_release_layers(struct mxr_device *mdev)
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
index ef0efdf..641b1f0 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -81,8 +81,9 @@
}
mdev->alloc_ctx = vb2_dma_contig_init_ctx(mdev->dev);
- if (IS_ERR_OR_NULL(mdev->alloc_ctx)) {
+ if (IS_ERR(mdev->alloc_ctx)) {
mxr_err(mdev, "could not acquire vb2 allocator\n");
+ ret = PTR_ERR(mdev->alloc_ctx);
goto fail_v4l2_dev;
}
diff --git a/drivers/media/platform/s5p-tv/sdo_drv.c b/drivers/media/platform/s5p-tv/sdo_drv.c
index ab6f9ef..0afa90f 100644
--- a/drivers/media/platform/s5p-tv/sdo_drv.c
+++ b/drivers/media/platform/s5p-tv/sdo_drv.c
@@ -262,11 +262,21 @@
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct sdo_device *sdev = sd_to_sdev(sd);
+ int ret;
dev_info(dev, "resume\n");
- clk_enable(sdev->sclk_dac);
- regulator_enable(sdev->vdac);
- regulator_enable(sdev->vdet);
+
+ ret = clk_enable(sdev->sclk_dac);
+ if (ret < 0)
+ return ret;
+
+ ret = regulator_enable(sdev->vdac);
+ if (ret < 0)
+ goto dac_clk_dis;
+
+ ret = regulator_enable(sdev->vdet);
+ if (ret < 0)
+ goto vdac_r_dis;
/* software reset */
sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_SW_RESET);
@@ -285,6 +295,12 @@
SDO_COMPENSATION_CVBS_COMP_OFF);
sdo_reg_debug(sdev);
return 0;
+
+vdac_r_dis:
+ regulator_disable(sdev->vdac);
+dac_clk_dis:
+ clk_disable(sdev->sclk_dac);
+ return ret;
}
static const struct dev_pm_ops sdo_pm_ops = {
diff --git a/drivers/media/platform/s5p-tv/sii9234_drv.c b/drivers/media/platform/s5p-tv/sii9234_drv.c
index 39b77d2..3dd762e 100644
--- a/drivers/media/platform/s5p-tv/sii9234_drv.c
+++ b/drivers/media/platform/s5p-tv/sii9234_drv.c
@@ -249,7 +249,9 @@
int ret;
dev_info(dev, "resume start\n");
- regulator_enable(ctx->power);
+ ret = regulator_enable(ctx->power);
+ if (ret < 0)
+ return ret;
ret = sii9234_reset(ctx);
if (ret)
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c
index 59a9dee..aa4cca3 100644
--- a/drivers/media/platform/sh_veu.c
+++ b/drivers/media/platform/sh_veu.c
@@ -359,10 +359,7 @@
veu->m2m_ctx = v4l2_m2m_ctx_init(veu->m2m_dev, veu,
sh_veu_queue_init);
- if (IS_ERR(veu->m2m_ctx))
- return PTR_ERR(veu->m2m_ctx);
-
- return 0;
+ return PTR_RET(veu->m2m_ctx);
}
static int sh_veu_querycap(struct file *file, void *priv,
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 7d02350..7a9c5e9 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -1248,32 +1248,6 @@
return res;
}
-static int sh_vou_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *id)
-{
- struct sh_vou_device *vou_dev = video_drvdata(file);
-
- return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_chip_ident, id);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int sh_vou_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct sh_vou_device *vou_dev = video_drvdata(file);
-
- return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_register, reg);
-}
-
-static int sh_vou_s_register(struct file *file, void *fh,
- const struct v4l2_dbg_register *reg)
-{
- struct sh_vou_device *vou_dev = video_drvdata(file);
-
- return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, s_register, reg);
-}
-#endif
-
/* sh_vou display ioctl operations */
static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
.vidioc_querycap = sh_vou_querycap,
@@ -1292,11 +1266,6 @@
.vidioc_cropcap = sh_vou_cropcap,
.vidioc_g_crop = sh_vou_g_crop,
.vidioc_s_crop = sh_vou_s_crop,
- .vidioc_g_chip_ident = sh_vou_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = sh_vou_g_register,
- .vidioc_s_register = sh_vou_s_register,
-#endif
};
static const struct v4l2_file_operations sh_vou_fops = {
@@ -1313,7 +1282,6 @@
.fops = &sh_vou_fops,
.ioctl_ops = &sh_vou_ioctl_ops,
.tvnorms = V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */
- .current_norm = V4L2_STD_NTSC_M,
.vfl_dir = VFL_DIR_TX,
};
@@ -1352,7 +1320,7 @@
pix = &vou_dev->pix;
/* Fill in defaults */
- vou_dev->std = sh_vou_video_template.current_norm;
+ vou_dev->std = V4L2_STD_NTSC_M;
rect->left = 0;
rect->top = 0;
rect->width = VOU_MAX_IMAGE_WIDTH;
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
index b139b52..626dccc 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -8,6 +8,9 @@
over a bus like PCI or USB. For example some i2c camera connected
directly to the data bus of an SoC.
+config SOC_CAMERA_SCALE_CROP
+ tristate
+
config SOC_CAMERA_PLATFORM
tristate "platform camera support"
depends on SOC_CAMERA
@@ -27,14 +30,10 @@
---help---
This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
-config MX3_VIDEO
- bool
-
config VIDEO_MX3
tristate "i.MX3x Camera Sensor Interface driver"
depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
select VIDEOBUF2_DMA_CONTIG
- select MX3_VIDEO
---help---
This is a v4l2 driver for the i.MX3x Camera Sensor Interface
@@ -55,6 +54,7 @@
tristate "SuperH Mobile CEU Interface driver"
depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
select VIDEOBUF2_DMA_CONTIG
+ select SOC_CAMERA_SCALE_CROP
---help---
This is a v4l2 driver for the SuperH Mobile CEU Interface
@@ -66,14 +66,10 @@
---help---
This is a v4l2 driver for the TI OMAP1 camera interface
-config VIDEO_MX2_HOSTSUPPORT
- bool
-
config VIDEO_MX2
tristate "i.MX27 Camera Sensor Interface driver"
depends on VIDEO_DEV && SOC_CAMERA && MACH_MX27
select VIDEOBUF2_DMA_CONTIG
- select VIDEO_MX2_HOSTSUPPORT
---help---
This is a v4l2 driver for the i.MX27 Camera Sensor Interface
diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
index 136b7f8..3918622 100644
--- a/drivers/media/platform/soc_camera/Makefile
+++ b/drivers/media/platform/soc_camera/Makefile
@@ -1,4 +1,8 @@
obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o
+obj-$(CONFIG_SOC_CAMERA_SCALE_CROP) += soc_scale_crop.o
+
+# a platform subdevice driver stub, allowing to support cameras by adding a
+# couple of callback functions to the board code
obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
# soc-camera host drivers have to be linked after camera drivers
@@ -10,5 +14,3 @@
obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
-
-ccflags-y += -I$(srctree)/drivers/media/i2c/soc_camera
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 1abbb36..1044856 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -102,7 +102,6 @@
struct list_head video_buffer_list;
struct frame_buffer *active;
- struct soc_camera_device *icd;
struct soc_camera_host soc_host;
};
@@ -367,7 +366,7 @@
/* Check if already in a frame */
if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
- dev_err(isi->icd->parent, "Already in frame handling.\n");
+ dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
return;
}
@@ -746,16 +745,26 @@
return formats;
}
-/* Called with .host_lock held */
static int isi_camera_add_device(struct soc_camera_device *icd)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
+ icd->devnum);
+
+ return 0;
+}
+
+static void isi_camera_remove_device(struct soc_camera_device *icd)
+{
+ dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
+ icd->devnum);
+}
+
+/* Called with .host_lock held */
+static int isi_camera_clock_start(struct soc_camera_host *ici)
+{
struct atmel_isi *isi = ici->priv;
int ret;
- if (isi->icd)
- return -EBUSY;
-
ret = clk_enable(isi->pclk);
if (ret)
return ret;
@@ -766,25 +775,16 @@
return ret;
}
- isi->icd = icd;
- dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
- icd->devnum);
return 0;
}
-/* Called with .host_lock held */
-static void isi_camera_remove_device(struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct atmel_isi *isi = ici->priv;
- BUG_ON(icd != isi->icd);
+/* Called with .host_lock held */
+static void isi_camera_clock_stop(struct soc_camera_host *ici)
+{
+ struct atmel_isi *isi = ici->priv;
clk_disable(isi->mck);
clk_disable(isi->pclk);
- isi->icd = NULL;
-
- dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
- icd->devnum);
}
static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
@@ -888,6 +888,8 @@
.owner = THIS_MODULE,
.add = isi_camera_add_device,
.remove = isi_camera_remove_device,
+ .clock_start = isi_camera_clock_start,
+ .clock_stop = isi_camera_clock_stop,
.set_fmt = isi_camera_set_fmt,
.try_fmt = isi_camera_try_fmt,
.get_formats = isi_camera_get_formats,
diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c
index a3fd8d6..fea3e61 100644
--- a/drivers/media/platform/soc_camera/mx1_camera.c
+++ b/drivers/media/platform/soc_camera/mx1_camera.c
@@ -104,7 +104,6 @@
*/
struct mx1_camera_dev {
struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
struct mx1_camera_pdata *pdata;
struct mx1_buffer *active;
struct resource *res;
@@ -220,7 +219,7 @@
static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
{
struct videobuf_buffer *vbuf = &pcdev->active->vb;
- struct device *dev = pcdev->icd->parent;
+ struct device *dev = pcdev->soc_host.icd->parent;
int ret;
if (unlikely(!pcdev->active)) {
@@ -331,7 +330,7 @@
static void mx1_camera_dma_irq(int channel, void *data)
{
struct mx1_camera_dev *pcdev = data;
- struct device *dev = pcdev->icd->parent;
+ struct device *dev = pcdev->soc_host.icd->parent;
struct mx1_buffer *buf;
struct videobuf_buffer *vb;
unsigned long flags;
@@ -389,7 +388,7 @@
*/
div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
- dev_dbg(pcdev->icd->parent,
+ dev_dbg(pcdev->soc_host.icd->parent,
"System clock %lukHz, target freq %dkHz, divisor %lu\n",
lcdclk / 1000, mclk / 1000, div);
@@ -400,7 +399,7 @@
{
unsigned int csicr1 = CSICR1_EN;
- dev_dbg(pcdev->icd->parent, "Activate device\n");
+ dev_dbg(pcdev->soc_host.v4l2_dev.dev, "Activate device\n");
clk_prepare_enable(pcdev->clk);
@@ -416,7 +415,7 @@
static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
{
- dev_dbg(pcdev->icd->parent, "Deactivate device\n");
+ dev_dbg(pcdev->soc_host.v4l2_dev.dev, "Deactivate device\n");
/* Disable all CSI interface */
__raw_writel(0x00, pcdev->base + CSICR1);
@@ -424,36 +423,38 @@
clk_disable_unprepare(pcdev->clk);
}
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on i.MX1/i.MXL camera sensor interface
- */
static int mx1_camera_add_device(struct soc_camera_device *icd)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
-
- if (pcdev->icd)
- return -EBUSY;
-
dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
icd->devnum);
- mx1_camera_activate(pcdev);
-
- pcdev->icd = icd;
-
return 0;
}
static void mx1_camera_remove_device(struct soc_camera_device *icd)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
+ icd->devnum);
+}
+
+/*
+ * The following two functions absolutely depend on the fact, that
+ * there can be only one camera on i.MX1/i.MXL camera sensor interface
+ */
+static int mx1_camera_clock_start(struct soc_camera_host *ici)
+{
+ struct mx1_camera_dev *pcdev = ici->priv;
+
+ mx1_camera_activate(pcdev);
+
+ return 0;
+}
+
+static void mx1_camera_clock_stop(struct soc_camera_host *ici)
+{
struct mx1_camera_dev *pcdev = ici->priv;
unsigned int csicr1;
- BUG_ON(icd != pcdev->icd);
-
/* disable interrupts */
csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
__raw_writel(csicr1, pcdev->base + CSICR1);
@@ -461,12 +462,7 @@
/* Stop DMA engine */
imx_dma_disable(pcdev->dma_chan);
- dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
- icd->devnum);
-
mx1_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
}
static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
@@ -679,6 +675,8 @@
.owner = THIS_MODULE,
.add = mx1_camera_add_device,
.remove = mx1_camera_remove_device,
+ .clock_start = mx1_camera_clock_start,
+ .clock_stop = mx1_camera_clock_stop,
.set_bus_param = mx1_camera_set_bus_param,
.set_fmt = mx1_camera_set_fmt,
.try_fmt = mx1_camera_try_fmt,
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 5bbeb43..45a0276 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -236,7 +236,6 @@
struct mx2_camera_dev {
struct device *dev;
struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
struct clk *clk_emma_ahb, *clk_emma_ipg;
struct clk *clk_csi_ahb, *clk_csi_per;
@@ -394,8 +393,8 @@
writel(phys, pcdev->base_emma +
PRP_DEST_Y_PTR - 0x14 * bufnum);
if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
- u32 imgsize = pcdev->icd->user_height *
- pcdev->icd->user_width;
+ u32 imgsize = pcdev->soc_host.icd->user_height *
+ pcdev->soc_host.icd->user_width;
writel(phys + imgsize, pcdev->base_emma +
PRP_DEST_CB_PTR - 0x14 * bufnum);
@@ -413,20 +412,30 @@
writel(0, pcdev->base_emma + PRP_CNTL);
}
+static int mx2_camera_add_device(struct soc_camera_device *icd)
+{
+ dev_info(icd->parent, "Camera driver attached to camera %d\n",
+ icd->devnum);
+
+ return 0;
+}
+
+static void mx2_camera_remove_device(struct soc_camera_device *icd)
+{
+ dev_info(icd->parent, "Camera driver detached from camera %d\n",
+ icd->devnum);
+}
+
/*
* The following two functions absolutely depend on the fact, that
* there can be only one camera on mx2 camera sensor interface
*/
-static int mx2_camera_add_device(struct soc_camera_device *icd)
+static int mx2_camera_clock_start(struct soc_camera_host *ici)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx2_camera_dev *pcdev = ici->priv;
int ret;
u32 csicr1;
- if (pcdev->icd)
- return -EBUSY;
-
ret = clk_prepare_enable(pcdev->clk_csi_ahb);
if (ret < 0)
return ret;
@@ -441,12 +450,8 @@
pcdev->csicr1 = csicr1;
writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
- pcdev->icd = icd;
pcdev->frame_count = 0;
- dev_info(icd->parent, "Camera driver attached to camera %d\n",
- icd->devnum);
-
return 0;
exit_csi_ahb:
@@ -455,19 +460,11 @@
return ret;
}
-static void mx2_camera_remove_device(struct soc_camera_device *icd)
+static void mx2_camera_clock_stop(struct soc_camera_host *ici)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx2_camera_dev *pcdev = ici->priv;
- BUG_ON(icd != pcdev->icd);
-
- dev_info(icd->parent, "Camera driver detached from camera %d\n",
- icd->devnum);
-
mx2_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
}
/*
@@ -1280,6 +1277,8 @@
.owner = THIS_MODULE,
.add = mx2_camera_add_device,
.remove = mx2_camera_remove_device,
+ .clock_start = mx2_camera_clock_start,
+ .clock_stop = mx2_camera_clock_stop,
.set_fmt = mx2_camera_set_fmt,
.set_crop = mx2_camera_set_crop,
.get_formats = mx2_camera_get_formats,
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index 5da3377..1047e3e 100644
--- a/drivers/media/platform/soc_camera/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -94,7 +94,6 @@
* Interface. If anyone ever builds hardware to enable more than one
* camera _simultaneously_, they will have to modify this driver too
*/
- struct soc_camera_device *icd;
struct clk *clk;
void __iomem *base;
@@ -461,8 +460,7 @@
}
/* First part of ipu_csi_init_interface() */
-static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
- struct soc_camera_device *icd)
+static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam)
{
u32 conf;
long rate;
@@ -506,51 +504,49 @@
clk_prepare_enable(mx3_cam->clk);
rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
- dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
+ dev_dbg(mx3_cam->soc_host.v4l2_dev.dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
if (rate)
clk_set_rate(mx3_cam->clk, rate);
}
-/* Called with .host_lock held */
static int mx3_camera_add_device(struct soc_camera_device *icd)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx3_camera_dev *mx3_cam = ici->priv;
-
- if (mx3_cam->icd)
- return -EBUSY;
-
- mx3_camera_activate(mx3_cam, icd);
-
- mx3_cam->buf_total = 0;
- mx3_cam->icd = icd;
-
dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
icd->devnum);
return 0;
}
-/* Called with .host_lock held */
static void mx3_camera_remove_device(struct soc_camera_device *icd)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
+ icd->devnum);
+}
+
+/* Called with .host_lock held */
+static int mx3_camera_clock_start(struct soc_camera_host *ici)
+{
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+
+ mx3_camera_activate(mx3_cam);
+
+ mx3_cam->buf_total = 0;
+
+ return 0;
+}
+
+/* Called with .host_lock held */
+static void mx3_camera_clock_stop(struct soc_camera_host *ici)
+{
struct mx3_camera_dev *mx3_cam = ici->priv;
struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
- BUG_ON(icd != mx3_cam->icd);
-
if (*ichan) {
dma_release_channel(&(*ichan)->dma_chan);
*ichan = NULL;
}
clk_disable_unprepare(mx3_cam->clk);
-
- mx3_cam->icd = NULL;
-
- dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
- icd->devnum);
}
static int test_platform_param(struct mx3_camera_dev *mx3_cam,
@@ -1133,6 +1129,8 @@
.owner = THIS_MODULE,
.add = mx3_camera_add_device,
.remove = mx3_camera_remove_device,
+ .clock_start = mx3_camera_clock_start,
+ .clock_stop = mx3_camera_clock_stop,
.set_crop = mx3_camera_set_crop,
.set_fmt = mx3_camera_set_fmt,
.try_fmt = mx3_camera_try_fmt,
diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c
index 9689a6e..6769193 100644
--- a/drivers/media/platform/soc_camera/omap1_camera.c
+++ b/drivers/media/platform/soc_camera/omap1_camera.c
@@ -150,7 +150,6 @@
struct omap1_cam_dev {
struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
struct clk *clk;
unsigned int irq;
@@ -564,7 +563,7 @@
{
struct omap1_cam_buf *buf = pcdev->active;
struct videobuf_buffer *vb;
- struct device *dev = pcdev->icd->parent;
+ struct device *dev = pcdev->soc_host.icd->parent;
if (WARN_ON(!buf)) {
suspend_capture(pcdev);
@@ -790,7 +789,7 @@
static irqreturn_t cam_isr(int irq, void *data)
{
struct omap1_cam_dev *pcdev = data;
- struct device *dev = pcdev->icd->parent;
+ struct device *dev = pcdev->soc_host.icd->parent;
struct omap1_cam_buf *buf = pcdev->active;
u32 it_status;
unsigned long flags;
@@ -894,19 +893,29 @@
CAM_WRITE(pcdev, GPIO, !reset);
}
+static int omap1_cam_add_device(struct soc_camera_device *icd)
+{
+ dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
+ icd->devnum);
+
+ return 0;
+}
+
+static void omap1_cam_remove_device(struct soc_camera_device *icd)
+{
+ dev_dbg(icd->parent,
+ "OMAP1 Camera driver detached from camera %d\n", icd->devnum);
+}
+
/*
* The following two functions absolutely depend on the fact, that
* there can be only one camera on OMAP1 camera sensor interface
*/
-static int omap1_cam_add_device(struct soc_camera_device *icd)
+static int omap1_cam_clock_start(struct soc_camera_host *ici)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct omap1_cam_dev *pcdev = ici->priv;
u32 ctrlclock;
- if (pcdev->icd)
- return -EBUSY;
-
clk_enable(pcdev->clk);
/* setup sensor clock */
@@ -941,21 +950,14 @@
sensor_reset(pcdev, false);
- pcdev->icd = icd;
-
- dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
- icd->devnum);
return 0;
}
-static void omap1_cam_remove_device(struct soc_camera_device *icd)
+static void omap1_cam_clock_stop(struct soc_camera_host *ici)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct omap1_cam_dev *pcdev = ici->priv;
u32 ctrlclock;
- BUG_ON(icd != pcdev->icd);
-
suspend_capture(pcdev);
disable_capture(pcdev);
@@ -973,11 +975,6 @@
CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~MCLK_EN);
clk_disable(pcdev->clk);
-
- pcdev->icd = NULL;
-
- dev_dbg(icd->parent,
- "OMAP1 Camera driver detached from camera %d\n", icd->devnum);
}
/* Duplicate standard formats based on host capability of byte swapping */
@@ -1535,6 +1532,8 @@
.owner = THIS_MODULE,
.add = omap1_cam_add_device,
.remove = omap1_cam_remove_device,
+ .clock_start = omap1_cam_clock_start,
+ .clock_stop = omap1_cam_clock_stop,
.get_formats = omap1_cam_get_formats,
.set_crop = omap1_cam_set_crop,
.set_fmt = omap1_cam_set_fmt,
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c
index d665242..d4df305 100644
--- a/drivers/media/platform/soc_camera/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
@@ -200,7 +200,6 @@
* interface. If anyone ever builds hardware to enable more than
* one camera, they will have to modify this driver too
*/
- struct soc_camera_device *icd;
struct clk *clk;
unsigned int irq;
@@ -956,39 +955,38 @@
return IRQ_HANDLED;
}
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on PXA quick capture interface
- * Called with .host_lock held
- */
static int pxa_camera_add_device(struct soc_camera_device *icd)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
-
- if (pcdev->icd)
- return -EBUSY;
-
- pxa_camera_activate(pcdev);
-
- pcdev->icd = icd;
-
dev_info(icd->parent, "PXA Camera driver attached to camera %d\n",
icd->devnum);
return 0;
}
-/* Called with .host_lock held */
static void pxa_camera_remove_device(struct soc_camera_device *icd)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct pxa_camera_dev *pcdev = ici->priv;
-
- BUG_ON(icd != pcdev->icd);
-
dev_info(icd->parent, "PXA Camera driver detached from camera %d\n",
icd->devnum);
+}
+
+/*
+ * The following two functions absolutely depend on the fact, that
+ * there can be only one camera on PXA quick capture interface
+ * Called with .host_lock held
+ */
+static int pxa_camera_clock_start(struct soc_camera_host *ici)
+{
+ struct pxa_camera_dev *pcdev = ici->priv;
+
+ pxa_camera_activate(pcdev);
+
+ return 0;
+}
+
+/* Called with .host_lock held */
+static void pxa_camera_clock_stop(struct soc_camera_host *ici)
+{
+ struct pxa_camera_dev *pcdev = ici->priv;
/* disable capture, disable interrupts */
__raw_writel(0x3ff, pcdev->base + CICR0);
@@ -999,8 +997,6 @@
DCSR(pcdev->dma_chans[2]) = 0;
pxa_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
}
static int test_platform_param(struct pxa_camera_dev *pcdev,
@@ -1596,8 +1592,8 @@
pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
- if (pcdev->icd) {
- struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
+ if (pcdev->soc_host.icd) {
+ struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
ret = v4l2_subdev_call(sd, core, s_power, 0);
if (ret == -ENOIOCTLCMD)
ret = 0;
@@ -1622,8 +1618,8 @@
__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3);
__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
- if (pcdev->icd) {
- struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
+ if (pcdev->soc_host.icd) {
+ struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
ret = v4l2_subdev_call(sd, core, s_power, 1);
if (ret == -ENOIOCTLCMD)
ret = 0;
@@ -1640,6 +1636,8 @@
.owner = THIS_MODULE,
.add = pxa_camera_add_device,
.remove = pxa_camera_remove_device,
+ .clock_start = pxa_camera_clock_start,
+ .clock_stop = pxa_camera_clock_stop,
.set_crop = pxa_camera_set_crop,
.get_formats = pxa_camera_get_formats,
.put_formats = pxa_camera_put_formats,
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 143d29fe..f2de006 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/moduleparam.h>
+#include <linux/of.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/device.h>
@@ -35,6 +36,7 @@
#include <linux/pm_runtime.h>
#include <linux/sched.h>
+#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
#include <media/soc_camera.h>
@@ -44,6 +46,8 @@
#include <media/v4l2-mediabus.h>
#include <media/soc_mediabus.h>
+#include "soc_scale_crop.h"
+
/* register offsets for sh7722 / sh7723 */
#define CAPSR 0x00 /* Capture start register */
@@ -95,7 +99,10 @@
struct sh_mobile_ceu_dev {
struct soc_camera_host ici;
- struct soc_camera_device *icd;
+ /* Asynchronous CSI2 linking */
+ struct v4l2_async_subdev *csi2_asd;
+ struct v4l2_subdev *csi2_sd;
+ /* Synchronous probing compatibility */
struct platform_device *csi2_pdev;
unsigned int irq;
@@ -119,6 +126,7 @@
enum v4l2_field field;
int sequence;
+ unsigned long flags;
unsigned int image_mode:1;
unsigned int is_16bit:1;
@@ -163,7 +171,6 @@
static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
{
int i, success = 0;
- struct soc_camera_device *icd = pcdev->icd;
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
@@ -185,9 +192,8 @@
udelay(1);
}
-
if (2 != success) {
- dev_warn(icd->pdev, "soft reset time out\n");
+ dev_warn(pcdev->ici.v4l2_dev.dev, "soft reset time out\n");
return -EIO;
}
@@ -277,7 +283,7 @@
*/
static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
{
- struct soc_camera_device *icd = pcdev->icd;
+ struct soc_camera_device *icd = pcdev->ici.icd;
dma_addr_t phys_addr_top, phys_addr_bottom;
unsigned long top1, top2;
unsigned long bottom1, bottom2;
@@ -534,72 +540,92 @@
{
struct v4l2_subdev *sd;
- if (!pcdev->csi2_pdev)
- return NULL;
+ if (pcdev->csi2_sd)
+ return pcdev->csi2_sd;
- v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
- if (&pcdev->csi2_pdev->dev == v4l2_get_subdevdata(sd))
- return sd;
+ if (pcdev->csi2_asd) {
+ char name[] = "sh-mobile-csi2";
+ v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
+ if (!strncmp(name, sd->name, sizeof(name) - 1)) {
+ pcdev->csi2_sd = sd;
+ return sd;
+ }
+ }
return NULL;
}
-/* Called with .host_lock held */
+static struct v4l2_subdev *csi2_subdev(struct sh_mobile_ceu_dev *pcdev,
+ struct soc_camera_device *icd)
+{
+ struct v4l2_subdev *sd = pcdev->csi2_sd;
+
+ return sd && sd->grp_id == soc_camera_grp_id(icd) ? sd : NULL;
+}
+
static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct v4l2_subdev *csi2_sd;
+ struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
int ret;
- if (pcdev->icd)
- return -EBUSY;
+ if (csi2_sd) {
+ csi2_sd->grp_id = soc_camera_grp_id(icd);
+ v4l2_set_subdev_hostdata(csi2_sd, icd);
+ }
+
+ ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
+ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+ return ret;
+
+ /*
+ * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
+ * has not found this soc-camera device among its clients
+ */
+ if (csi2_sd && ret == -ENODEV)
+ csi2_sd->grp_id = 0;
dev_info(icd->parent,
- "SuperH Mobile CEU driver attached to camera %d\n",
+ "SuperH Mobile CEU%s driver attached to camera %d\n",
+ csi2_sd && csi2_sd->grp_id ? "/CSI-2" : "", icd->devnum);
+
+ return 0;
+}
+
+static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
+
+ dev_info(icd->parent,
+ "SuperH Mobile CEU driver detached from camera %d\n",
icd->devnum);
+ v4l2_subdev_call(csi2_sd, core, s_power, 0);
+}
+
+/* Called with .host_lock held */
+static int sh_mobile_ceu_clock_start(struct soc_camera_host *ici)
+{
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ int ret;
+
pm_runtime_get_sync(ici->v4l2_dev.dev);
pcdev->buf_total = 0;
ret = sh_mobile_ceu_soft_reset(pcdev);
- csi2_sd = find_csi2(pcdev);
- if (csi2_sd) {
- csi2_sd->grp_id = soc_camera_grp_id(icd);
- v4l2_set_subdev_hostdata(csi2_sd, icd);
- }
-
- ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
- pm_runtime_put(ici->v4l2_dev.dev);
- return ret;
- }
-
- /*
- * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
- * has not found this soc-camera device among its clients
- */
- if (ret == -ENODEV && csi2_sd)
- csi2_sd->grp_id = 0;
- pcdev->icd = icd;
-
return 0;
}
/* Called with .host_lock held */
-static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
+static void sh_mobile_ceu_clock_stop(struct soc_camera_host *ici)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
- BUG_ON(icd != pcdev->icd);
-
- v4l2_subdev_call(csi2_sd, core, s_power, 0);
- if (csi2_sd)
- csi2_sd->grp_id = 0;
/* disable capture, disable interrupts */
ceu_write(pcdev, CEIER, 0);
sh_mobile_ceu_soft_reset(pcdev);
@@ -614,12 +640,6 @@
spin_unlock_irq(&pcdev->lock);
pm_runtime_put(ici->v4l2_dev.dev);
-
- dev_info(icd->parent,
- "SuperH Mobile CEU driver detached from camera %d\n",
- icd->devnum);
-
- pcdev->icd = NULL;
}
/*
@@ -705,7 +725,7 @@
}
/* CSI2 special configuration */
- if (pcdev->pdata->csi2) {
+ if (csi2_subdev(pcdev, icd)) {
in_width = ((in_width - 2) * 2);
left_offset *= 2;
}
@@ -762,13 +782,7 @@
static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
struct soc_camera_device *icd)
{
- if (pcdev->csi2_pdev) {
- struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
- if (csi2_sd && csi2_sd->grp_id == soc_camera_grp_id(icd))
- return csi2_sd;
- }
-
- return soc_camera_to_subdev(icd);
+ return csi2_subdev(pcdev, icd) ? : soc_camera_to_subdev(icd);
}
#define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \
@@ -809,7 +823,7 @@
/* Make choises, based on platform preferences */
if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
- if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
+ if (pcdev->flags & SH_CEU_FLAG_HSYNC_LOW)
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
else
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
@@ -817,7 +831,7 @@
if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
+ if (pcdev->flags & SH_CEU_FLAG_VSYNC_LOW)
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
else
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
@@ -872,11 +886,11 @@
value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
- if (pcdev->pdata->csi2) /* CSI2 mode */
+ if (csi2_subdev(pcdev, icd)) /* CSI2 mode */
value |= 3 << 12;
else if (pcdev->is_16bit)
value |= 1 << 12;
- else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT)
+ else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT)
value |= 2 << 12;
ceu_write(pcdev, CAMCR, value);
@@ -993,8 +1007,6 @@
fmt->packing == SOC_MBUS_PACKING_EXTEND16);
}
-static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
-
static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
{
return container_of(ctrl->handler, struct soc_camera_device,
@@ -1051,7 +1063,7 @@
return 0;
}
- if (!pcdev->pdata->csi2) {
+ if (!csi2_subdev(pcdev, icd)) {
/* Are there any restrictions in the CSI-2 case? */
ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
if (ret < 0)
@@ -1072,7 +1084,7 @@
/* FIXME: subwindow is lost between close / open */
/* Cache current client geometry */
- ret = client_g_rect(sd, &rect);
+ ret = soc_camera_client_g_rect(sd, &rect);
if (ret < 0)
return ret;
@@ -1182,334 +1194,8 @@
icd->host_priv = NULL;
}
-/* Check if any dimension of r1 is smaller than respective one of r2 */
-static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
-{
- return r1->width < r2->width || r1->height < r2->height;
-}
-
-/* Check if r1 fails to cover r2 */
-static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
-{
- return r1->left > r2->left || r1->top > r2->top ||
- r1->left + r1->width < r2->left + r2->width ||
- r1->top + r1->height < r2->top + r2->height;
-}
-
-static unsigned int scale_down(unsigned int size, unsigned int scale)
-{
- return (size * 4096 + scale / 2) / scale;
-}
-
-static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
-{
- return (input * 4096 + output / 2) / output;
-}
-
-/* Get and store current client crop */
-static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
-{
- struct v4l2_crop crop;
- struct v4l2_cropcap cap;
- int ret;
-
- crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- ret = v4l2_subdev_call(sd, video, g_crop, &crop);
- if (!ret) {
- *rect = crop.c;
- return ret;
- }
-
- /* Camera driver doesn't support .g_crop(), assume default rectangle */
- cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- ret = v4l2_subdev_call(sd, video, cropcap, &cap);
- if (!ret)
- *rect = cap.defrect;
-
- return ret;
-}
-
-/* Client crop has changed, update our sub-rectangle to remain within the area */
-static void update_subrect(struct sh_mobile_ceu_cam *cam)
-{
- struct v4l2_rect *rect = &cam->rect, *subrect = &cam->subrect;
-
- if (rect->width < subrect->width)
- subrect->width = rect->width;
-
- if (rect->height < subrect->height)
- subrect->height = rect->height;
-
- if (rect->left > subrect->left)
- subrect->left = rect->left;
- else if (rect->left + rect->width >
- subrect->left + subrect->width)
- subrect->left = rect->left + rect->width -
- subrect->width;
-
- if (rect->top > subrect->top)
- subrect->top = rect->top;
- else if (rect->top + rect->height >
- subrect->top + subrect->height)
- subrect->top = rect->top + rect->height -
- subrect->height;
-}
-
-/*
- * The common for both scaling and cropping iterative approach is:
- * 1. try if the client can produce exactly what requested by the user
- * 2. if (1) failed, try to double the client image until we get one big enough
- * 3. if (2) failed, try to request the maximum image
- */
-static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
- struct v4l2_crop *cam_crop)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
- struct device *dev = sd->v4l2_dev->dev;
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct v4l2_cropcap cap;
- int ret;
- unsigned int width, height;
-
- v4l2_subdev_call(sd, video, s_crop, crop);
- ret = client_g_rect(sd, cam_rect);
- if (ret < 0)
- return ret;
-
- /*
- * Now cam_crop contains the current camera input rectangle, and it must
- * be within camera cropcap bounds
- */
- if (!memcmp(rect, cam_rect, sizeof(*rect))) {
- /* Even if camera S_CROP failed, but camera rectangle matches */
- dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
- rect->width, rect->height, rect->left, rect->top);
- cam->rect = *cam_rect;
- return 0;
- }
-
- /* Try to fix cropping, that camera hasn't managed to set */
- dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
- cam_rect->width, cam_rect->height,
- cam_rect->left, cam_rect->top,
- rect->width, rect->height, rect->left, rect->top);
-
- /* We need sensor maximum rectangle */
- ret = v4l2_subdev_call(sd, video, cropcap, &cap);
- if (ret < 0)
- return ret;
-
- /* Put user requested rectangle within sensor bounds */
- soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
- cap.bounds.width);
- soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
- cap.bounds.height);
-
- /*
- * Popular special case - some cameras can only handle fixed sizes like
- * QVGA, VGA,... Take care to avoid infinite loop.
- */
- width = max(cam_rect->width, 2);
- height = max(cam_rect->height, 2);
-
- /*
- * Loop as long as sensor is not covering the requested rectangle and
- * is still within its bounds
- */
- while (!ret && (is_smaller(cam_rect, rect) ||
- is_inside(cam_rect, rect)) &&
- (cap.bounds.width > width || cap.bounds.height > height)) {
-
- width *= 2;
- height *= 2;
-
- cam_rect->width = width;
- cam_rect->height = height;
-
- /*
- * We do not know what capabilities the camera has to set up
- * left and top borders. We could try to be smarter in iterating
- * them, e.g., if camera current left is to the right of the
- * target left, set it to the middle point between the current
- * left and minimum left. But that would add too much
- * complexity: we would have to iterate each border separately.
- * Instead we just drop to the left and top bounds.
- */
- if (cam_rect->left > rect->left)
- cam_rect->left = cap.bounds.left;
-
- if (cam_rect->left + cam_rect->width < rect->left + rect->width)
- cam_rect->width = rect->left + rect->width -
- cam_rect->left;
-
- if (cam_rect->top > rect->top)
- cam_rect->top = cap.bounds.top;
-
- if (cam_rect->top + cam_rect->height < rect->top + rect->height)
- cam_rect->height = rect->top + rect->height -
- cam_rect->top;
-
- v4l2_subdev_call(sd, video, s_crop, cam_crop);
- ret = client_g_rect(sd, cam_rect);
- dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
- cam_rect->width, cam_rect->height,
- cam_rect->left, cam_rect->top);
- }
-
- /* S_CROP must not modify the rectangle */
- if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
- /*
- * The camera failed to configure a suitable cropping,
- * we cannot use the current rectangle, set to max
- */
- *cam_rect = cap.bounds;
- v4l2_subdev_call(sd, video, s_crop, cam_crop);
- ret = client_g_rect(sd, cam_rect);
- dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
- cam_rect->width, cam_rect->height,
- cam_rect->left, cam_rect->top);
- }
-
- if (!ret) {
- cam->rect = *cam_rect;
- update_subrect(cam);
- }
-
- return ret;
-}
-
-/* Iterative s_mbus_fmt, also updates cached client crop on success */
-static int client_s_fmt(struct soc_camera_device *icd,
- struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct sh_mobile_ceu_dev *pcdev = ici->priv;
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct device *dev = icd->parent;
- unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
- unsigned int max_width, max_height;
- struct v4l2_cropcap cap;
- bool ceu_1to1;
- int ret;
-
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
- soc_camera_grp_id(icd), video,
- s_mbus_fmt, mf);
- if (ret < 0)
- return ret;
-
- dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
-
- if (width == mf->width && height == mf->height) {
- /* Perfect! The client has done it all. */
- ceu_1to1 = true;
- goto update_cache;
- }
-
- ceu_1to1 = false;
- if (!ceu_can_scale)
- goto update_cache;
-
- cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- ret = v4l2_subdev_call(sd, video, cropcap, &cap);
- if (ret < 0)
- return ret;
-
- max_width = min(cap.bounds.width, pcdev->max_width);
- max_height = min(cap.bounds.height, pcdev->max_height);
-
- /* Camera set a format, but geometry is not precise, try to improve */
- tmp_w = mf->width;
- tmp_h = mf->height;
-
- /* width <= max_width && height <= max_height - guaranteed by try_fmt */
- while ((width > tmp_w || height > tmp_h) &&
- tmp_w < max_width && tmp_h < max_height) {
- tmp_w = min(2 * tmp_w, max_width);
- tmp_h = min(2 * tmp_h, max_height);
- mf->width = tmp_w;
- mf->height = tmp_h;
- ret = v4l2_device_call_until_err(sd->v4l2_dev,
- soc_camera_grp_id(icd), video,
- s_mbus_fmt, mf);
- dev_geo(dev, "Camera scaled to %ux%u\n",
- mf->width, mf->height);
- if (ret < 0) {
- /* This shouldn't happen */
- dev_err(dev, "Client failed to set format: %d\n", ret);
- return ret;
- }
- }
-
-update_cache:
- /* Update cache */
- ret = client_g_rect(sd, &cam->rect);
- if (ret < 0)
- return ret;
-
- if (ceu_1to1)
- cam->subrect = cam->rect;
- else
- update_subrect(cam);
-
- return 0;
-}
-
-/**
- * @width - on output: user width, mapped back to input
- * @height - on output: user height, mapped back to input
- * @mf - in- / output camera output window
- */
-static int client_scale(struct soc_camera_device *icd,
- struct v4l2_mbus_framefmt *mf,
- unsigned int *width, unsigned int *height,
- bool ceu_can_scale)
-{
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct device *dev = icd->parent;
- struct v4l2_mbus_framefmt mf_tmp = *mf;
- unsigned int scale_h, scale_v;
- int ret;
-
- /*
- * 5. Apply iterative camera S_FMT for camera user window (also updates
- * client crop cache and the imaginary sub-rectangle).
- */
- ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale);
- if (ret < 0)
- return ret;
-
- dev_geo(dev, "5: camera scaled to %ux%u\n",
- mf_tmp.width, mf_tmp.height);
-
- /* 6. Retrieve camera output window (g_fmt) */
-
- /* unneeded - it is already in "mf_tmp" */
-
- /* 7. Calculate new client scales. */
- scale_h = calc_generic_scale(cam->rect.width, mf_tmp.width);
- scale_v = calc_generic_scale(cam->rect.height, mf_tmp.height);
-
- mf->width = mf_tmp.width;
- mf->height = mf_tmp.height;
- mf->colorspace = mf_tmp.colorspace;
-
- /*
- * 8. Calculate new CEU crop - apply camera scales to previously
- * updated "effective" crop.
- */
- *width = scale_down(cam->subrect.width, scale_h);
- *height = scale_down(cam->subrect.height, scale_v);
-
- dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
-
- return 0;
-}
+#define scale_down(size, scale) soc_camera_shift_scale(size, 12, scale)
+#define calc_generic_scale(in, out) soc_camera_calc_scale(in, 12, out)
/*
* CEU can scale and crop, but we don't want to waste bandwidth and kill the
@@ -1547,7 +1233,8 @@
* 1. - 2. Apply iterative camera S_CROP for new input window, read back
* actual camera rectangle.
*/
- ret = client_s_crop(icd, &a_writable, &cam_crop);
+ ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
+ &cam->rect, &cam->subrect);
if (ret < 0)
return ret;
@@ -1666,55 +1353,6 @@
return 0;
}
-/*
- * Calculate real client output window by applying new scales to the current
- * client crop. New scales are calculated from the requested output format and
- * CEU crop, mapped backed onto the client input (subrect).
- */
-static void calculate_client_output(struct soc_camera_device *icd,
- const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
-{
- struct sh_mobile_ceu_cam *cam = icd->host_priv;
- struct device *dev = icd->parent;
- struct v4l2_rect *cam_subrect = &cam->subrect;
- unsigned int scale_v, scale_h;
-
- if (cam_subrect->width == cam->rect.width &&
- cam_subrect->height == cam->rect.height) {
- /* No sub-cropping */
- mf->width = pix->width;
- mf->height = pix->height;
- return;
- }
-
- /* 1.-2. Current camera scales and subwin - cached. */
-
- dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
- cam_subrect->width, cam_subrect->height,
- cam_subrect->left, cam_subrect->top);
-
- /*
- * 3. Calculate new combined scales from input sub-window to requested
- * user window.
- */
-
- /*
- * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
- * (128x96) or larger than VGA
- */
- scale_h = calc_generic_scale(cam_subrect->width, pix->width);
- scale_v = calc_generic_scale(cam_subrect->height, pix->height);
-
- dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
-
- /*
- * 4. Calculate desired client output window by applying combined scales
- * to client (real) input window.
- */
- mf->width = scale_down(cam->rect.width, scale_h);
- mf->height = scale_down(cam->rect.height, scale_v);
-}
-
/* Similar to set_crop multistage iterative algorithm */
static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
@@ -1727,8 +1365,8 @@
struct v4l2_mbus_framefmt mf;
__u32 pixfmt = pix->pixelformat;
const struct soc_camera_format_xlate *xlate;
- /* Keep Compiler Happy */
- unsigned int ceu_sub_width = 0, ceu_sub_height = 0;
+ unsigned int ceu_sub_width = pcdev->max_width,
+ ceu_sub_height = pcdev->max_height;
u16 scale_v, scale_h;
int ret;
bool image_mode;
@@ -1755,7 +1393,7 @@
}
/* 1.-4. Calculate desired client output geometry */
- calculate_client_output(icd, pix, &mf);
+ soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf, 12);
mf.field = pix->field;
mf.colorspace = pix->colorspace;
mf.code = xlate->code;
@@ -1777,8 +1415,9 @@
dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
/* 5. - 9. */
- ret = client_scale(icd, &mf, &ceu_sub_width, &ceu_sub_height,
- image_mode && V4L2_FIELD_NONE == field);
+ ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
+ &mf, &ceu_sub_width, &ceu_sub_height,
+ image_mode && V4L2_FIELD_NONE == field, 12);
dev_geo(dev, "5-9: client scale return %d\n", ret);
@@ -2036,6 +1675,8 @@
.owner = THIS_MODULE,
.add = sh_mobile_ceu_add_device,
.remove = sh_mobile_ceu_remove_device,
+ .clock_start = sh_mobile_ceu_clock_start,
+ .clock_stop = sh_mobile_ceu_clock_stop,
.get_formats = sh_mobile_ceu_get_formats,
.put_formats = sh_mobile_ceu_put_formats,
.get_crop = sh_mobile_ceu_get_crop,
@@ -2079,7 +1720,7 @@
struct resource *res;
void __iomem *base;
unsigned int irq;
- int err = 0;
+ int err, i;
struct bus_wait wait = {
.completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion),
.notifier.notifier_call = bus_notify,
@@ -2104,13 +1745,36 @@
init_completion(&pcdev->complete);
pcdev->pdata = pdev->dev.platform_data;
- if (!pcdev->pdata) {
+ if (!pcdev->pdata && !pdev->dev.of_node) {
dev_err(&pdev->dev, "CEU platform data not set.\n");
return -EINVAL;
}
- pcdev->max_width = pcdev->pdata->max_width ? : 2560;
- pcdev->max_height = pcdev->pdata->max_height ? : 1920;
+ /* TODO: implement per-device bus flags */
+ if (pcdev->pdata) {
+ pcdev->max_width = pcdev->pdata->max_width;
+ pcdev->max_height = pcdev->pdata->max_height;
+ pcdev->flags = pcdev->pdata->flags;
+ }
+
+ if (!pcdev->max_width) {
+ unsigned int v;
+ err = of_property_read_u32(pdev->dev.of_node, "renesas,max-width", &v);
+ if (!err)
+ pcdev->max_width = v;
+
+ if (!pcdev->max_width)
+ pcdev->max_width = 2560;
+ }
+ if (!pcdev->max_height) {
+ unsigned int v;
+ err = of_property_read_u32(pdev->dev.of_node, "renesas,max-height", &v);
+ if (!err)
+ pcdev->max_height = v;
+
+ if (!pcdev->max_height)
+ pcdev->max_height = 1920;
+ }
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
@@ -2160,31 +1824,60 @@
goto exit_free_clk;
}
- err = soc_camera_host_register(&pcdev->ici);
- if (err)
- goto exit_free_ctx;
+ if (pcdev->pdata && pcdev->pdata->asd_sizes) {
+ struct v4l2_async_subdev **asd;
+ char name[] = "sh-mobile-csi2";
+ int j;
- /* CSI2 interfacing */
- csi2 = pcdev->pdata->csi2;
+ /*
+ * CSI2 interfacing: several groups can use CSI2, pick up the
+ * first one
+ */
+ asd = pcdev->pdata->asd;
+ for (j = 0; pcdev->pdata->asd_sizes[j]; j++) {
+ for (i = 0; i < pcdev->pdata->asd_sizes[j]; i++, asd++) {
+ dev_dbg(&pdev->dev, "%s(): subdev #%d, type %u\n",
+ __func__, i, (*asd)->bus_type);
+ if ((*asd)->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
+ !strncmp(name, (*asd)->match.platform.name,
+ sizeof(name) - 1)) {
+ pcdev->csi2_asd = *asd;
+ break;
+ }
+ }
+ if (pcdev->csi2_asd)
+ break;
+ }
+
+ pcdev->ici.asd = pcdev->pdata->asd;
+ pcdev->ici.asd_sizes = pcdev->pdata->asd_sizes;
+ }
+
+ /* Legacy CSI2 interfacing */
+ csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL;
if (csi2) {
+ /*
+ * TODO: remove this once all users are converted to
+ * asynchronous CSI2 probing. If it has to be kept, csi2
+ * platform device resources have to be added, using
+ * platform_device_add_resources()
+ */
struct platform_device *csi2_pdev =
platform_device_alloc("sh-mobile-csi2", csi2->id);
struct sh_csi2_pdata *csi2_pdata = csi2->platform_data;
if (!csi2_pdev) {
err = -ENOMEM;
- goto exit_host_unregister;
+ goto exit_free_ctx;
}
pcdev->csi2_pdev = csi2_pdev;
- err = platform_device_add_data(csi2_pdev, csi2_pdata, sizeof(*csi2_pdata));
+ err = platform_device_add_data(csi2_pdev, csi2_pdata,
+ sizeof(*csi2_pdata));
if (err < 0)
goto exit_pdev_put;
- csi2_pdata = csi2_pdev->dev.platform_data;
- csi2_pdata->v4l2_dev = &pcdev->ici.v4l2_dev;
-
csi2_pdev->resource = csi2->resource;
csi2_pdev->num_resources = csi2->num_resources;
@@ -2226,17 +1919,38 @@
err = -ENODEV;
goto exit_pdev_unregister;
}
+
+ pcdev->csi2_sd = platform_get_drvdata(csi2_pdev);
+ }
+
+ err = soc_camera_host_register(&pcdev->ici);
+ if (err)
+ goto exit_csi2_unregister;
+
+ if (csi2) {
+ err = v4l2_device_register_subdev(&pcdev->ici.v4l2_dev,
+ pcdev->csi2_sd);
+ dev_dbg(&pdev->dev, "%s(): ret(register_subdev) = %d\n",
+ __func__, err);
+ if (err < 0)
+ goto exit_host_unregister;
+ /* v4l2_device_register_subdev() took a reference too */
+ module_put(pcdev->csi2_sd->owner);
}
return 0;
-exit_pdev_unregister:
- platform_device_del(pcdev->csi2_pdev);
-exit_pdev_put:
- pcdev->csi2_pdev->resource = NULL;
- platform_device_put(pcdev->csi2_pdev);
exit_host_unregister:
soc_camera_host_unregister(&pcdev->ici);
+exit_csi2_unregister:
+ if (csi2) {
+ module_put(pcdev->csi2_pdev->dev.driver->owner);
+exit_pdev_unregister:
+ platform_device_del(pcdev->csi2_pdev);
+exit_pdev_put:
+ pcdev->csi2_pdev->resource = NULL;
+ platform_device_put(pcdev->csi2_pdev);
+ }
exit_free_ctx:
vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
exit_free_clk:
@@ -2287,10 +2001,18 @@
.runtime_resume = sh_mobile_ceu_runtime_nop,
};
+static const struct of_device_id sh_mobile_ceu_of_match[] = {
+ { .compatible = "renesas,sh-mobile-ceu" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match);
+
static struct platform_driver sh_mobile_ceu_driver = {
.driver = {
.name = "sh_mobile_ceu",
+ .owner = THIS_MODULE,
.pm = &sh_mobile_ceu_dev_pm_ops,
+ .of_match_table = sh_mobile_ceu_of_match,
},
.probe = sh_mobile_ceu_probe,
.remove = sh_mobile_ceu_remove,
@@ -2314,5 +2036,5 @@
MODULE_DESCRIPTION("SuperH Mobile CEU driver");
MODULE_AUTHOR("Magnus Damm");
MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.6");
+MODULE_VERSION("0.1.0");
MODULE_ALIAS("platform:sh_mobile_ceu");
diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c
index 09cb4fc..05dd21a 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c
@@ -36,7 +36,6 @@
struct sh_csi2 {
struct v4l2_subdev subdev;
- struct list_head list;
unsigned int irq;
unsigned long mipi_flags;
void __iomem *base;
@@ -44,6 +43,8 @@
struct sh_csi2_client_config *client;
};
+static void sh_csi2_hwinit(struct sh_csi2 *priv);
+
static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
{
@@ -132,10 +133,58 @@
static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg)
{
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
+ struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
+
+ if (!priv->mipi_flags) {
+ struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
+ struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
+ struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
+ unsigned long common_flags, csi2_flags;
+ struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,};
+ int ret;
+
+ /* Check if we can support this camera */
+ csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
+ V4L2_MBUS_CSI2_1_LANE;
+
+ switch (pdata->type) {
+ case SH_CSI2C:
+ if (priv->client->lanes != 1)
+ csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
+ break;
+ case SH_CSI2I:
+ switch (priv->client->lanes) {
+ default:
+ csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
+ case 3:
+ csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
+ case 2:
+ csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
+ }
+ }
+
+ ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &client_cfg);
+ if (ret == -ENOIOCTLCMD)
+ common_flags = csi2_flags;
+ else if (!ret)
+ common_flags = soc_mbus_config_compatible(&client_cfg,
+ csi2_flags);
+ else
+ common_flags = 0;
+
+ if (!common_flags)
+ return -EINVAL;
+
+ /* All good: camera MIPI configuration supported */
+ priv->mipi_flags = common_flags;
+ }
+
+ if (cfg) {
+ cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
+ V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
+ cfg->type = V4L2_MBUS_PARALLEL;
+ }
return 0;
}
@@ -146,8 +195,17 @@
struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
- struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,
- .flags = priv->mipi_flags};
+ struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,};
+ int ret = sh_csi2_g_mbus_config(sd, NULL);
+
+ if (ret < 0)
+ return ret;
+
+ pm_runtime_get_sync(&priv->pdev->dev);
+
+ sh_csi2_hwinit(priv);
+
+ client_cfg.flags = priv->mipi_flags;
return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg);
}
@@ -202,19 +260,19 @@
static int sh_csi2_client_connect(struct sh_csi2 *priv)
{
- struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
- struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev);
- struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
struct device *dev = v4l2_get_subdevdata(&priv->subdev);
- struct v4l2_mbus_config cfg;
- unsigned long common_flags, csi2_flags;
- int i, ret;
+ struct sh_csi2_pdata *pdata = dev->platform_data;
+ struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev);
+ int i;
if (priv->client)
return -EBUSY;
for (i = 0; i < pdata->num_clients; i++)
- if (&pdata->clients[i].pdev->dev == icd->pdev)
+ if ((pdata->clients[i].pdev &&
+ &pdata->clients[i].pdev->dev == icd->pdev) ||
+ (icd->control &&
+ strcmp(pdata->clients[i].name, dev_name(icd->control))))
break;
dev_dbg(dev, "%s(%p): found #%d\n", __func__, dev, i);
@@ -222,46 +280,8 @@
if (i == pdata->num_clients)
return -ENODEV;
- /* Check if we can support this camera */
- csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_1_LANE;
-
- switch (pdata->type) {
- case SH_CSI2C:
- if (pdata->clients[i].lanes != 1)
- csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
- break;
- case SH_CSI2I:
- switch (pdata->clients[i].lanes) {
- default:
- csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
- case 3:
- csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
- case 2:
- csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
- }
- }
-
- cfg.type = V4L2_MBUS_CSI2;
- ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &cfg);
- if (ret == -ENOIOCTLCMD)
- common_flags = csi2_flags;
- else if (!ret)
- common_flags = soc_mbus_config_compatible(&cfg,
- csi2_flags);
- else
- common_flags = 0;
-
- if (!common_flags)
- return -EINVAL;
-
- /* All good: camera MIPI configuration supported */
- priv->mipi_flags = common_flags;
priv->client = pdata->clients + i;
- pm_runtime_get_sync(dev);
-
- sh_csi2_hwinit(priv);
-
return 0;
}
@@ -304,11 +324,18 @@
/* Platform data specify the PHY, lanes, ECC, CRC */
struct sh_csi2_pdata *pdata = pdev->dev.platform_data;
+ if (!pdata)
+ return -EINVAL;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
/* Interrupt unused so far */
irq = platform_get_irq(pdev, 0);
- if (!res || (int)irq <= 0 || !pdata) {
+ if (!res || (int)irq <= 0) {
dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n");
return -ENODEV;
}
@@ -319,10 +346,6 @@
return -EINVAL;
}
- priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
priv->irq = irq;
priv->base = devm_ioremap_resource(&pdev->dev, res);
@@ -330,37 +353,35 @@
return PTR_ERR(priv->base);
priv->pdev = pdev;
- platform_set_drvdata(pdev, priv);
+ priv->subdev.owner = THIS_MODULE;
+ priv->subdev.dev = &pdev->dev;
+ platform_set_drvdata(pdev, &priv->subdev);
v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops);
v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.mipi-csi",
- dev_name(pdata->v4l2_dev->dev));
- ret = v4l2_device_register_subdev(pdata->v4l2_dev, &priv->subdev);
- dev_dbg(&pdev->dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret);
+ dev_name(&pdev->dev));
+
+ ret = v4l2_async_register_subdev(&priv->subdev);
if (ret < 0)
- goto esdreg;
+ return ret;
pm_runtime_enable(&pdev->dev);
dev_dbg(&pdev->dev, "CSI2 probed.\n");
return 0;
-
-esdreg:
- platform_set_drvdata(pdev, NULL);
-
- return ret;
}
static int sh_csi2_remove(struct platform_device *pdev)
{
- struct sh_csi2 *priv = platform_get_drvdata(pdev);
+ struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+ struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev);
- v4l2_device_unregister_subdev(&priv->subdev);
+ v4l2_async_unregister_subdev(&priv->subdev);
+ v4l2_device_unregister_subdev(subdev);
pm_runtime_disable(&pdev->dev);
- platform_set_drvdata(pdev, NULL);
return 0;
}
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 3a4efbd..2dd0e52 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -21,21 +21,23 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/list.h>
-#include <linux/mutex.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
-#include <linux/pm_runtime.h>
#include <linux/vmalloc.h>
#include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-dev.h>
#include <media/videobuf-core.h>
#include <media/videobuf2-core.h>
-#include <media/soc_mediabus.h>
/* Default to VGA resolution */
#define DEFAULT_WIDTH 640
@@ -46,17 +48,39 @@
(icd)->vb_vidq.streaming : \
vb2_is_streaming(&(icd)->vb2_vidq))
+#define MAP_MAX_NUM 32
+static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
static LIST_HEAD(hosts);
static LIST_HEAD(devices);
-static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
+/*
+ * Protects lists and bitmaps of hosts and devices.
+ * Lock nesting: Ok to take ->host_lock under list_lock.
+ */
+static DEFINE_MUTEX(list_lock);
-int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+struct soc_camera_async_client {
+ struct v4l2_async_subdev *sensor;
+ struct v4l2_async_notifier notifier;
+ struct platform_device *pdev;
+ struct list_head list; /* needed for clean up */
+};
+
+static int soc_camera_video_start(struct soc_camera_device *icd);
+static int video_dev_create(struct soc_camera_device *icd);
+
+int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+ struct v4l2_clk *clk)
{
- int ret = regulator_bulk_enable(ssdd->num_regulators,
+ int ret = clk ? v4l2_clk_enable(clk) : 0;
+ if (ret < 0) {
+ dev_err(dev, "Cannot enable clock: %d\n", ret);
+ return ret;
+ }
+ ret = regulator_bulk_enable(ssdd->num_regulators,
ssdd->regulators);
if (ret < 0) {
dev_err(dev, "Cannot enable regulators\n");
- return ret;
+ goto eregenable;
}
if (ssdd->power) {
@@ -64,16 +88,25 @@
if (ret < 0) {
dev_err(dev,
"Platform failed to power-on the camera.\n");
- regulator_bulk_disable(ssdd->num_regulators,
- ssdd->regulators);
+ goto epwron;
}
}
+ return 0;
+
+epwron:
+ regulator_bulk_disable(ssdd->num_regulators,
+ ssdd->regulators);
+eregenable:
+ if (clk)
+ v4l2_clk_disable(clk);
+
return ret;
}
EXPORT_SYMBOL(soc_camera_power_on);
-int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+ struct v4l2_clk *clk)
{
int ret = 0;
int err;
@@ -94,10 +127,21 @@
ret = ret ? : err;
}
+ if (clk)
+ v4l2_clk_disable(clk);
+
return ret;
}
EXPORT_SYMBOL(soc_camera_power_off);
+int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+{
+
+ return devm_regulator_bulk_get(dev, ssdd->num_regulators,
+ ssdd->regulators);
+}
+EXPORT_SYMBOL(soc_camera_power_init);
+
static int __soc_camera_power_on(struct soc_camera_device *icd)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -235,7 +279,6 @@
/* default is camera */
inp->type = V4L2_INPUT_TYPE_CAMERA;
- inp->std = V4L2_STD_UNKNOWN;
strcpy(inp->name, "Camera");
return 0;
@@ -505,6 +548,58 @@
return ici->ops->set_bus_param(icd);
}
+static int soc_camera_add_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ int ret;
+
+ if (ici->icd)
+ return -EBUSY;
+
+ if (!icd->clk) {
+ mutex_lock(&ici->clk_lock);
+ ret = ici->ops->clock_start(ici);
+ mutex_unlock(&ici->clk_lock);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (ici->ops->add) {
+ ret = ici->ops->add(icd);
+ if (ret < 0)
+ goto eadd;
+ }
+
+ ici->icd = icd;
+
+ return 0;
+
+eadd:
+ if (!icd->clk) {
+ mutex_lock(&ici->clk_lock);
+ ici->ops->clock_stop(ici);
+ mutex_unlock(&ici->clk_lock);
+ }
+ return ret;
+}
+
+static void soc_camera_remove_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ if (WARN_ON(icd != ici->icd))
+ return;
+
+ if (ici->ops->remove)
+ ici->ops->remove(icd);
+ if (!icd->clk) {
+ mutex_lock(&ici->clk_lock);
+ ici->ops->clock_stop(ici);
+ mutex_unlock(&ici->clk_lock);
+ }
+ ici->icd = NULL;
+}
+
static int soc_camera_open(struct file *file)
{
struct video_device *vdev = video_devdata(file);
@@ -525,7 +620,7 @@
return -ENODEV;
}
- icd = dev_get_drvdata(vdev->parent);
+ icd = video_get_drvdata(vdev);
ici = to_soc_camera_host(icd->parent);
ret = try_module_get(ici->ops->owner) ? 0 : -ENODEV;
@@ -568,7 +663,7 @@
if (sdesc->subdev_desc.reset)
sdesc->subdev_desc.reset(icd->pdev);
- ret = ici->ops->add(icd);
+ ret = soc_camera_add_device(icd);
if (ret < 0) {
dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
goto eiciadd;
@@ -610,8 +705,8 @@
return 0;
/*
- * First four errors are entered with the .host_lock held
- * and use_count == 1
+ * All errors are entered with the .host_lock held, first four also
+ * with use_count == 1
*/
einitvb:
esfmt:
@@ -619,7 +714,7 @@
eresume:
__soc_camera_power_off(icd);
epower:
- ici->ops->remove(icd);
+ soc_camera_remove_device(icd);
eiciadd:
icd->use_count--;
mutex_unlock(&ici->host_lock);
@@ -645,7 +740,7 @@
vb2_queue_release(&icd->vb2_vidq);
__soc_camera_power_off(icd);
- ici->ops->remove(icd);
+ soc_camera_remove_device(icd);
}
if (icd->streamer == file)
@@ -1036,36 +1131,8 @@
return -ENOIOCTLCMD;
}
-static int soc_camera_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *id)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, core, g_chip_ident, id);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int soc_camera_g_register(struct file *file, void *fh,
- struct v4l2_dbg_register *reg)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, core, g_register, reg);
-}
-
-static int soc_camera_s_register(struct file *file, void *fh,
- const struct v4l2_dbg_register *reg)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- return v4l2_subdev_call(sd, core, s_register, reg);
-}
-#endif
-
-static int soc_camera_probe(struct soc_camera_device *icd);
+static int soc_camera_probe(struct soc_camera_host *ici,
+ struct soc_camera_device *icd);
/* So far this function cannot fail */
static void scan_add_host(struct soc_camera_host *ici)
@@ -1074,38 +1141,215 @@
mutex_lock(&list_lock);
- list_for_each_entry(icd, &devices, list) {
+ list_for_each_entry(icd, &devices, list)
if (icd->iface == ici->nr) {
+ struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
+ struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc;
+
+ /* The camera could have been already on, try to reset */
+ if (ssdd->reset)
+ ssdd->reset(icd->pdev);
+
icd->parent = ici->v4l2_dev.dev;
- soc_camera_probe(icd);
+
+ /* Ignore errors */
+ soc_camera_probe(ici, icd);
}
- }
mutex_unlock(&list_lock);
}
+/*
+ * It is invalid to call v4l2_clk_enable() after a successful probing
+ * asynchronously outside of V4L2 operations, i.e. with .host_lock not held.
+ */
+static int soc_camera_clk_enable(struct v4l2_clk *clk)
+{
+ struct soc_camera_device *icd = clk->priv;
+ struct soc_camera_host *ici;
+ int ret;
+
+ if (!icd || !icd->parent)
+ return -ENODEV;
+
+ ici = to_soc_camera_host(icd->parent);
+
+ if (!try_module_get(ici->ops->owner))
+ return -ENODEV;
+
+ /*
+ * If a different client is currently being probed, the host will tell
+ * you to go
+ */
+ mutex_lock(&ici->clk_lock);
+ ret = ici->ops->clock_start(ici);
+ mutex_unlock(&ici->clk_lock);
+ return ret;
+}
+
+static void soc_camera_clk_disable(struct v4l2_clk *clk)
+{
+ struct soc_camera_device *icd = clk->priv;
+ struct soc_camera_host *ici;
+
+ if (!icd || !icd->parent)
+ return;
+
+ ici = to_soc_camera_host(icd->parent);
+
+ mutex_lock(&ici->clk_lock);
+ ici->ops->clock_stop(ici);
+ mutex_unlock(&ici->clk_lock);
+
+ module_put(ici->ops->owner);
+}
+
+/*
+ * Eventually, it would be more logical to make the respective host the clock
+ * owner, but then we would have to copy this struct for each ici. Besides, it
+ * would introduce the circular dependency problem, unless we port all client
+ * drivers to release the clock, when not in use.
+ */
+static const struct v4l2_clk_ops soc_camera_clk_ops = {
+ .owner = THIS_MODULE,
+ .enable = soc_camera_clk_enable,
+ .disable = soc_camera_clk_disable,
+};
+
+static int soc_camera_dyn_pdev(struct soc_camera_desc *sdesc,
+ struct soc_camera_async_client *sasc)
+{
+ struct platform_device *pdev;
+ int ret, i;
+
+ mutex_lock(&list_lock);
+ i = find_first_zero_bit(device_map, MAP_MAX_NUM);
+ if (i < MAP_MAX_NUM)
+ set_bit(i, device_map);
+ mutex_unlock(&list_lock);
+ if (i >= MAP_MAX_NUM)
+ return -ENOMEM;
+
+ pdev = platform_device_alloc("soc-camera-pdrv", i);
+ if (!pdev)
+ return -ENOMEM;
+
+ ret = platform_device_add_data(pdev, sdesc, sizeof(*sdesc));
+ if (ret < 0) {
+ platform_device_put(pdev);
+ return ret;
+ }
+
+ sasc->pdev = pdev;
+
+ return 0;
+}
+
+static struct soc_camera_device *soc_camera_add_pdev(struct soc_camera_async_client *sasc)
+{
+ struct platform_device *pdev = sasc->pdev;
+ int ret;
+
+ ret = platform_device_add(pdev);
+ if (ret < 0 || !pdev->dev.driver)
+ return NULL;
+
+ return platform_get_drvdata(pdev);
+}
+
+/* Locking: called with .host_lock held */
+static int soc_camera_probe_finish(struct soc_camera_device *icd)
+{
+ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+ struct v4l2_mbus_framefmt mf;
+ int ret;
+
+ sd->grp_id = soc_camera_grp_id(icd);
+ v4l2_set_subdev_hostdata(sd, icd);
+
+ ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
+ if (ret < 0)
+ return ret;
+
+ ret = soc_camera_add_device(icd);
+ if (ret < 0) {
+ dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
+ return ret;
+ }
+
+ /* At this point client .probe() should have run already */
+ ret = soc_camera_init_user_formats(icd);
+ if (ret < 0)
+ goto eusrfmt;
+
+ icd->field = V4L2_FIELD_ANY;
+
+ ret = soc_camera_video_start(icd);
+ if (ret < 0)
+ goto evidstart;
+
+ /* Try to improve our guess of a reasonable window format */
+ if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
+ icd->user_width = mf.width;
+ icd->user_height = mf.height;
+ icd->colorspace = mf.colorspace;
+ icd->field = mf.field;
+ }
+ soc_camera_remove_device(icd);
+
+ return 0;
+
+evidstart:
+ soc_camera_free_user_formats(icd);
+eusrfmt:
+ soc_camera_remove_device(icd);
+
+ return ret;
+}
+
#ifdef CONFIG_I2C_BOARDINFO
-static int soc_camera_init_i2c(struct soc_camera_device *icd,
+static int soc_camera_i2c_init(struct soc_camera_device *icd,
struct soc_camera_desc *sdesc)
{
struct i2c_client *client;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ struct soc_camera_host *ici;
struct soc_camera_host_desc *shd = &sdesc->host_desc;
- struct i2c_adapter *adap = i2c_get_adapter(shd->i2c_adapter_id);
+ struct i2c_adapter *adap;
struct v4l2_subdev *subdev;
+ char clk_name[V4L2_SUBDEV_NAME_SIZE];
+ int ret;
+ /* First find out how we link the main client */
+ if (icd->sasc) {
+ /* Async non-OF probing handled by the subdevice list */
+ return -EPROBE_DEFER;
+ }
+
+ ici = to_soc_camera_host(icd->parent);
+ adap = i2c_get_adapter(shd->i2c_adapter_id);
if (!adap) {
dev_err(icd->pdev, "Cannot get I2C adapter #%d. No driver?\n",
shd->i2c_adapter_id);
- goto ei2cga;
+ return -ENODEV;
}
shd->board_info->platform_data = &sdesc->subdev_desc;
+ snprintf(clk_name, sizeof(clk_name), "%d-%04x",
+ shd->i2c_adapter_id, shd->board_info->addr);
+
+ icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd);
+ if (IS_ERR(icd->clk)) {
+ ret = PTR_ERR(icd->clk);
+ goto eclkreg;
+ }
+
subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
shd->board_info, NULL);
- if (!subdev)
+ if (!subdev) {
+ ret = -ENODEV;
goto ei2cnd;
+ }
client = v4l2_get_subdevdata(subdev);
@@ -1114,39 +1358,203 @@
return 0;
ei2cnd:
+ v4l2_clk_unregister(icd->clk);
+eclkreg:
+ icd->clk = NULL;
i2c_put_adapter(adap);
-ei2cga:
- return -ENODEV;
+ return ret;
}
-static void soc_camera_free_i2c(struct soc_camera_device *icd)
+static void soc_camera_i2c_free(struct soc_camera_device *icd)
{
struct i2c_client *client =
to_i2c_client(to_soc_camera_control(icd));
- struct i2c_adapter *adap = client->adapter;
+ struct i2c_adapter *adap;
icd->control = NULL;
+ if (icd->sasc)
+ return;
+
+ adap = client->adapter;
v4l2_device_unregister_subdev(i2c_get_clientdata(client));
i2c_unregister_device(client);
i2c_put_adapter(adap);
+ v4l2_clk_unregister(icd->clk);
+ icd->clk = NULL;
+}
+
+/*
+ * V4L2 asynchronous notifier callbacks. They are all called under a v4l2-async
+ * internal global mutex, therefore cannot race against other asynchronous
+ * events. Until notifier->complete() (soc_camera_async_complete()) is called,
+ * the video device node is not registered and no V4L fops can occur. Unloading
+ * of the host driver also calls a v4l2-async function, so also there we're
+ * protected.
+ */
+static int soc_camera_async_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct soc_camera_async_client *sasc = container_of(notifier,
+ struct soc_camera_async_client, notifier);
+ struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+ if (asd == sasc->sensor && !WARN_ON(icd->control)) {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ /*
+ * Only now we get subdevice-specific information like
+ * regulators, flags, callbacks, etc.
+ */
+ if (client) {
+ struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
+ struct soc_camera_subdev_desc *ssdd =
+ soc_camera_i2c_to_desc(client);
+ if (ssdd) {
+ memcpy(&sdesc->subdev_desc, ssdd,
+ sizeof(sdesc->subdev_desc));
+ if (ssdd->reset)
+ ssdd->reset(icd->pdev);
+ }
+
+ icd->control = &client->dev;
+ }
+ }
+
+ return 0;
+}
+
+static void soc_camera_async_unbind(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct soc_camera_async_client *sasc = container_of(notifier,
+ struct soc_camera_async_client, notifier);
+ struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+ if (icd->clk) {
+ v4l2_clk_unregister(icd->clk);
+ icd->clk = NULL;
+ }
+}
+
+static int soc_camera_async_complete(struct v4l2_async_notifier *notifier)
+{
+ struct soc_camera_async_client *sasc = container_of(notifier,
+ struct soc_camera_async_client, notifier);
+ struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+ if (to_soc_camera_control(icd)) {
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ int ret;
+
+ mutex_lock(&list_lock);
+ ret = soc_camera_probe(ici, icd);
+ mutex_unlock(&list_lock);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int scan_async_group(struct soc_camera_host *ici,
+ struct v4l2_async_subdev **asd, unsigned int size)
+{
+ struct soc_camera_async_subdev *sasd;
+ struct soc_camera_async_client *sasc;
+ struct soc_camera_device *icd;
+ struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,};
+ char clk_name[V4L2_SUBDEV_NAME_SIZE];
+ int ret, i;
+
+ /* First look for a sensor */
+ for (i = 0; i < size; i++) {
+ sasd = container_of(asd[i], struct soc_camera_async_subdev, asd);
+ if (sasd->role == SOCAM_SUBDEV_DATA_SOURCE)
+ break;
+ }
+
+ if (i == size || asd[i]->bus_type != V4L2_ASYNC_BUS_I2C) {
+ /* All useless */
+ dev_err(ici->v4l2_dev.dev, "No I2C data source found!\n");
+ return -ENODEV;
+ }
+
+ /* Or shall this be managed by the soc-camera device? */
+ sasc = devm_kzalloc(ici->v4l2_dev.dev, sizeof(*sasc), GFP_KERNEL);
+ if (!sasc)
+ return -ENOMEM;
+
+ /* HACK: just need a != NULL */
+ sdesc.host_desc.board_info = ERR_PTR(-ENODATA);
+
+ ret = soc_camera_dyn_pdev(&sdesc, sasc);
+ if (ret < 0)
+ return ret;
+
+ sasc->sensor = &sasd->asd;
+
+ icd = soc_camera_add_pdev(sasc);
+ if (!icd) {
+ platform_device_put(sasc->pdev);
+ return -ENOMEM;
+ }
+
+ sasc->notifier.subdev = asd;
+ sasc->notifier.num_subdevs = size;
+ sasc->notifier.bound = soc_camera_async_bound;
+ sasc->notifier.unbind = soc_camera_async_unbind;
+ sasc->notifier.complete = soc_camera_async_complete;
+
+ icd->sasc = sasc;
+ icd->parent = ici->v4l2_dev.dev;
+
+ snprintf(clk_name, sizeof(clk_name), "%d-%04x",
+ sasd->asd.match.i2c.adapter_id, sasd->asd.match.i2c.address);
+
+ icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd);
+ if (IS_ERR(icd->clk)) {
+ ret = PTR_ERR(icd->clk);
+ goto eclkreg;
+ }
+
+ ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier);
+ if (!ret)
+ return 0;
+
+ v4l2_clk_unregister(icd->clk);
+eclkreg:
+ icd->clk = NULL;
+ platform_device_unregister(sasc->pdev);
+ dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret);
+
+ return ret;
+}
+
+static void scan_async_host(struct soc_camera_host *ici)
+{
+ struct v4l2_async_subdev **asd;
+ int j;
+
+ for (j = 0, asd = ici->asd; ici->asd_sizes[j]; j++) {
+ scan_async_group(ici, asd, ici->asd_sizes[j]);
+ asd += ici->asd_sizes[j];
+ }
}
#else
-#define soc_camera_init_i2c(icd, sdesc) (-ENODEV)
-#define soc_camera_free_i2c(icd) do {} while (0)
+#define soc_camera_i2c_init(icd, sdesc) (-ENODEV)
+#define soc_camera_i2c_free(icd) do {} while (0)
+#define scan_async_host(ici) do {} while (0)
#endif
-static int soc_camera_video_start(struct soc_camera_device *icd);
-static int video_dev_create(struct soc_camera_device *icd);
/* Called during host-driver probe */
-static int soc_camera_probe(struct soc_camera_device *icd)
+static int soc_camera_probe(struct soc_camera_host *ici,
+ struct soc_camera_device *icd)
{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
struct soc_camera_host_desc *shd = &sdesc->host_desc;
- struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc;
struct device *control = NULL;
- struct v4l2_subdev *sd;
- struct v4l2_mbus_framefmt mf;
int ret;
dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
@@ -1162,30 +1570,32 @@
if (ret < 0)
return ret;
- /* The camera could have been already on, try to reset */
- if (ssdd->reset)
- ssdd->reset(icd->pdev);
-
- mutex_lock(&ici->host_lock);
- ret = ici->ops->add(icd);
- mutex_unlock(&ici->host_lock);
- if (ret < 0)
- goto eadd;
-
/* Must have icd->vdev before registering the device */
ret = video_dev_create(icd);
if (ret < 0)
goto evdc;
+ /*
+ * ..._video_start() will create a device node, video_register_device()
+ * itself is protected against concurrent open() calls, but we also have
+ * to protect our data also during client probing.
+ */
+
/* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
if (shd->board_info) {
- ret = soc_camera_init_i2c(icd, sdesc);
- if (ret < 0)
- goto eadddev;
+ ret = soc_camera_i2c_init(icd, sdesc);
+ if (ret < 0 && ret != -EPROBE_DEFER)
+ goto eadd;
} else if (!shd->add_device || !shd->del_device) {
ret = -EINVAL;
- goto eadddev;
+ goto eadd;
} else {
+ mutex_lock(&ici->clk_lock);
+ ret = ici->ops->clock_start(ici);
+ mutex_unlock(&ici->clk_lock);
+ if (ret < 0)
+ goto eadd;
+
if (shd->module_name)
ret = request_module(shd->module_name);
@@ -1206,81 +1616,49 @@
}
}
- sd = soc_camera_to_subdev(icd);
- sd->grp_id = soc_camera_grp_id(icd);
- v4l2_set_subdev_hostdata(sd, icd);
-
- ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
- if (ret < 0)
- goto ectrl;
-
- /* At this point client .probe() should have run already */
- ret = soc_camera_init_user_formats(icd);
- if (ret < 0)
- goto eiufmt;
-
- icd->field = V4L2_FIELD_ANY;
-
- /*
- * ..._video_start() will create a device node, video_register_device()
- * itself is protected against concurrent open() calls, but we also have
- * to protect our data.
- */
mutex_lock(&ici->host_lock);
-
- ret = soc_camera_video_start(icd);
- if (ret < 0)
- goto evidstart;
-
- /* Try to improve our guess of a reasonable window format */
- if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
- icd->user_width = mf.width;
- icd->user_height = mf.height;
- icd->colorspace = mf.colorspace;
- icd->field = mf.field;
- }
-
- ici->ops->remove(icd);
-
+ ret = soc_camera_probe_finish(icd);
mutex_unlock(&ici->host_lock);
+ if (ret < 0)
+ goto efinish;
return 0;
-evidstart:
- mutex_unlock(&ici->host_lock);
- soc_camera_free_user_formats(icd);
-eiufmt:
-ectrl:
+efinish:
if (shd->board_info) {
- soc_camera_free_i2c(icd);
+ soc_camera_i2c_free(icd);
} else {
shd->del_device(icd);
module_put(control->driver->owner);
- }
enodrv:
eadddev:
+ mutex_lock(&ici->clk_lock);
+ ici->ops->clock_stop(ici);
+ mutex_unlock(&ici->clk_lock);
+ }
+eadd:
video_device_release(icd->vdev);
icd->vdev = NULL;
+ if (icd->vdev) {
+ video_device_release(icd->vdev);
+ icd->vdev = NULL;
+ }
evdc:
- mutex_lock(&ici->host_lock);
- ici->ops->remove(icd);
- mutex_unlock(&ici->host_lock);
-eadd:
v4l2_ctrl_handler_free(&icd->ctrl_handler);
return ret;
}
/*
* This is called on device_unregister, which only means we have to disconnect
- * from the host, but not remove ourselves from the device list
+ * from the host, but not remove ourselves from the device list. With
+ * asynchronous client probing this can also be called without
+ * soc_camera_probe_finish() having run. Careful with clean up.
*/
static int soc_camera_remove(struct soc_camera_device *icd)
{
struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
struct video_device *vdev = icd->vdev;
- BUG_ON(!icd->parent);
-
v4l2_ctrl_handler_free(&icd->ctrl_handler);
if (vdev) {
video_unregister_device(vdev);
@@ -1288,15 +1666,27 @@
}
if (sdesc->host_desc.board_info) {
- soc_camera_free_i2c(icd);
+ soc_camera_i2c_free(icd);
} else {
- struct device_driver *drv = to_soc_camera_control(icd)->driver;
+ struct device *dev = to_soc_camera_control(icd);
+ struct device_driver *drv = dev ? dev->driver : NULL;
if (drv) {
sdesc->host_desc.del_device(icd);
module_put(drv->owner);
}
}
- soc_camera_free_user_formats(icd);
+
+ if (icd->num_user_formats)
+ soc_camera_free_user_formats(icd);
+
+ if (icd->clk) {
+ /* For the synchronous case */
+ v4l2_clk_unregister(icd->clk);
+ icd->clk = NULL;
+ }
+
+ if (icd->sasc)
+ platform_device_unregister(icd->sasc->pdev);
return 0;
}
@@ -1372,8 +1762,8 @@
((!ici->ops->init_videobuf ||
!ici->ops->reqbufs) &&
!ici->ops->init_videobuf2) ||
- !ici->ops->add ||
- !ici->ops->remove ||
+ !ici->ops->clock_start ||
+ !ici->ops->clock_stop ||
!ici->ops->poll ||
!ici->v4l2_dev.dev)
return -EINVAL;
@@ -1407,7 +1797,18 @@
mutex_unlock(&list_lock);
mutex_init(&ici->host_lock);
- scan_add_host(ici);
+ mutex_init(&ici->clk_lock);
+
+ if (ici->asd_sizes)
+ /*
+ * No OF, host with a list of subdevices. Don't try to mix
+ * modes by initialising some groups statically and some
+ * dynamically!
+ */
+ scan_async_host(ici);
+ else
+ /* Legacy: static platform devices from board data */
+ scan_add_host(ici);
return 0;
@@ -1420,13 +1821,30 @@
/* Unregister all clients! */
void soc_camera_host_unregister(struct soc_camera_host *ici)
{
- struct soc_camera_device *icd;
+ struct soc_camera_device *icd, *tmp;
+ struct soc_camera_async_client *sasc;
+ LIST_HEAD(notifiers);
+
+ mutex_lock(&list_lock);
+ list_del(&ici->list);
+ list_for_each_entry(icd, &devices, list)
+ if (icd->iface == ici->nr && icd->sasc) {
+ /* as long as we hold the device, sasc won't be freed */
+ get_device(icd->pdev);
+ list_add(&icd->sasc->list, ¬ifiers);
+ }
+ mutex_unlock(&list_lock);
+
+ list_for_each_entry(sasc, ¬ifiers, list) {
+ /* Must call unlocked to avoid AB-BA dead-lock */
+ v4l2_async_notifier_unregister(&sasc->notifier);
+ put_device(&sasc->pdev->dev);
+ }
mutex_lock(&list_lock);
- list_del(&ici->list);
- list_for_each_entry(icd, &devices, list)
- if (icd->iface == ici->nr && to_soc_camera_control(icd))
+ list_for_each_entry_safe(icd, tmp, &devices, list)
+ if (icd->iface == ici->nr)
soc_camera_remove(icd);
mutex_unlock(&list_lock);
@@ -1441,6 +1859,7 @@
struct soc_camera_device *ix;
int num = -1, i;
+ mutex_lock(&list_lock);
for (i = 0; i < 256 && num < 0; i++) {
num = i;
/* Check if this index is available on this interface */
@@ -1452,18 +1871,34 @@
}
}
- if (num < 0)
+ if (num < 0) {
/*
* ok, we have 256 cameras on this host...
* man, stay reasonable...
*/
+ mutex_unlock(&list_lock);
return -ENOMEM;
+ }
icd->devnum = num;
icd->use_count = 0;
icd->host_priv = NULL;
+ /*
+ * Dynamically allocated devices set the bit earlier, but it doesn't hurt setting
+ * it again
+ */
+ i = to_platform_device(icd->pdev)->id;
+ if (i < 0)
+ /* One static (legacy) soc-camera platform device */
+ i = 0;
+ if (i >= MAP_MAX_NUM) {
+ mutex_unlock(&list_lock);
+ return -EBUSY;
+ }
+ set_bit(i, device_map);
list_add_tail(&icd->list, &devices);
+ mutex_unlock(&list_lock);
return 0;
}
@@ -1495,11 +1930,6 @@
.vidioc_s_selection = soc_camera_s_selection,
.vidioc_g_parm = soc_camera_g_parm,
.vidioc_s_parm = soc_camera_s_parm,
- .vidioc_g_chip_ident = soc_camera_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = soc_camera_g_register,
- .vidioc_s_register = soc_camera_s_register,
-#endif
};
static int video_dev_create(struct soc_camera_device *icd)
@@ -1512,12 +1942,10 @@
strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
- vdev->parent = icd->pdev;
- vdev->current_norm = V4L2_STD_UNKNOWN;
+ vdev->v4l2_dev = &ici->v4l2_dev;
vdev->fops = &soc_camera_fops;
vdev->ioctl_ops = &soc_camera_ioctl_ops;
vdev->release = video_device_release;
- vdev->tvnorms = V4L2_STD_UNKNOWN;
vdev->ctrl_handler = &icd->ctrl_handler;
vdev->lock = &ici->host_lock;
@@ -1537,6 +1965,7 @@
if (!icd->parent)
return -ENODEV;
+ video_set_drvdata(icd->vdev, icd);
ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
if (ret < 0) {
dev_err(icd->pdev, "video_register_device failed: %d\n", ret);
@@ -1563,6 +1992,12 @@
if (!icd)
return -ENOMEM;
+ /*
+ * In the asynchronous case ssdd->num_regulators == 0 yet, so, the below
+ * regulator allocation is a dummy. They will be really requested later
+ * in soc_camera_async_bind(). Also note, that in that case regulators
+ * are attached to the I2C device and not to the camera platform device.
+ */
ret = devm_regulator_bulk_get(&pdev->dev, ssdd->num_regulators,
ssdd->regulators);
if (ret < 0)
@@ -1587,11 +2022,25 @@
static int soc_camera_pdrv_remove(struct platform_device *pdev)
{
struct soc_camera_device *icd = platform_get_drvdata(pdev);
+ int i;
if (!icd)
return -EINVAL;
- list_del(&icd->list);
+ i = pdev->id;
+ if (i < 0)
+ i = 0;
+
+ /*
+ * In synchronous mode with static platform devices this is called in a
+ * loop from drivers/base/dd.c::driver_detach(), no parallel execution,
+ * no need to lock. In asynchronous case the caller -
+ * soc_camera_host_unregister() - already holds the lock
+ */
+ if (test_bit(i, device_map)) {
+ clear_bit(i, device_map);
+ list_del(&icd->list);
+ }
return 0;
}
diff --git a/drivers/media/platform/soc_camera/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c
index 1b7a88c..ceaddfb 100644
--- a/drivers/media/platform/soc_camera/soc_camera_platform.c
+++ b/drivers/media/platform/soc_camera/soc_camera_platform.c
@@ -54,7 +54,7 @@
{
struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
- return soc_camera_set_power(p->icd->control, &p->icd->sdesc->subdev_desc, on);
+ return soc_camera_set_power(p->icd->control, &p->icd->sdesc->subdev_desc, NULL, on);
}
static struct v4l2_subdev_core_ops platform_subdev_core_ops = {
@@ -137,7 +137,6 @@
struct soc_camera_platform_priv *priv;
struct soc_camera_platform_info *p = pdev->dev.platform_data;
struct soc_camera_device *icd;
- int ret;
if (!p)
return -EINVAL;
@@ -165,15 +164,7 @@
v4l2_set_subdevdata(&priv->subdev, p);
strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
- ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
- if (ret)
- goto evdrs;
-
- return ret;
-
-evdrs:
- platform_set_drvdata(pdev, NULL);
- return ret;
+ return v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
}
static int soc_camera_platform_remove(struct platform_device *pdev)
@@ -183,7 +174,6 @@
p->icd->control = NULL;
v4l2_device_unregister_subdev(&priv->subdev);
- platform_set_drvdata(pdev, NULL);
return 0;
}
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
new file mode 100644
index 0000000..cbd3a34
--- /dev/null
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
@@ -0,0 +1,402 @@
+/*
+ * soc-camera generic scaling-cropping manipulation functions
+ *
+ * Copyright (C) 2013 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * 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.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include <media/soc_camera.h>
+#include <media/v4l2-common.h>
+
+#include "soc_scale_crop.h"
+
+#ifdef DEBUG_GEOMETRY
+#define dev_geo dev_info
+#else
+#define dev_geo dev_dbg
+#endif
+
+/* Check if any dimension of r1 is smaller than respective one of r2 */
+static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
+{
+ return r1->width < r2->width || r1->height < r2->height;
+}
+
+/* Check if r1 fails to cover r2 */
+static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
+{
+ return r1->left > r2->left || r1->top > r2->top ||
+ r1->left + r1->width < r2->left + r2->width ||
+ r1->top + r1->height < r2->top + r2->height;
+}
+
+/* Get and store current client crop */
+int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
+{
+ struct v4l2_crop crop;
+ struct v4l2_cropcap cap;
+ int ret;
+
+ crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = v4l2_subdev_call(sd, video, g_crop, &crop);
+ if (!ret) {
+ *rect = crop.c;
+ return ret;
+ }
+
+ /* Camera driver doesn't support .g_crop(), assume default rectangle */
+ cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+ if (!ret)
+ *rect = cap.defrect;
+
+ return ret;
+}
+EXPORT_SYMBOL(soc_camera_client_g_rect);
+
+/* Client crop has changed, update our sub-rectangle to remain within the area */
+static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect)
+{
+ if (rect->width < subrect->width)
+ subrect->width = rect->width;
+
+ if (rect->height < subrect->height)
+ subrect->height = rect->height;
+
+ if (rect->left > subrect->left)
+ subrect->left = rect->left;
+ else if (rect->left + rect->width >
+ subrect->left + subrect->width)
+ subrect->left = rect->left + rect->width -
+ subrect->width;
+
+ if (rect->top > subrect->top)
+ subrect->top = rect->top;
+ else if (rect->top + rect->height >
+ subrect->top + subrect->height)
+ subrect->top = rect->top + rect->height -
+ subrect->height;
+}
+
+/*
+ * The common for both scaling and cropping iterative approach is:
+ * 1. try if the client can produce exactly what requested by the user
+ * 2. if (1) failed, try to double the client image until we get one big enough
+ * 3. if (2) failed, try to request the maximum image
+ */
+int soc_camera_client_s_crop(struct v4l2_subdev *sd,
+ struct v4l2_crop *crop, struct v4l2_crop *cam_crop,
+ struct v4l2_rect *target_rect, struct v4l2_rect *subrect)
+{
+ struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
+ struct device *dev = sd->v4l2_dev->dev;
+ struct v4l2_cropcap cap;
+ int ret;
+ unsigned int width, height;
+
+ v4l2_subdev_call(sd, video, s_crop, crop);
+ ret = soc_camera_client_g_rect(sd, cam_rect);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Now cam_crop contains the current camera input rectangle, and it must
+ * be within camera cropcap bounds
+ */
+ if (!memcmp(rect, cam_rect, sizeof(*rect))) {
+ /* Even if camera S_CROP failed, but camera rectangle matches */
+ dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
+ rect->width, rect->height, rect->left, rect->top);
+ *target_rect = *cam_rect;
+ return 0;
+ }
+
+ /* Try to fix cropping, that camera hasn't managed to set */
+ dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
+ cam_rect->width, cam_rect->height,
+ cam_rect->left, cam_rect->top,
+ rect->width, rect->height, rect->left, rect->top);
+
+ /* We need sensor maximum rectangle */
+ ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+ if (ret < 0)
+ return ret;
+
+ /* Put user requested rectangle within sensor bounds */
+ soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
+ cap.bounds.width);
+ soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
+ cap.bounds.height);
+
+ /*
+ * Popular special case - some cameras can only handle fixed sizes like
+ * QVGA, VGA,... Take care to avoid infinite loop.
+ */
+ width = max(cam_rect->width, 2);
+ height = max(cam_rect->height, 2);
+
+ /*
+ * Loop as long as sensor is not covering the requested rectangle and
+ * is still within its bounds
+ */
+ while (!ret && (is_smaller(cam_rect, rect) ||
+ is_inside(cam_rect, rect)) &&
+ (cap.bounds.width > width || cap.bounds.height > height)) {
+
+ width *= 2;
+ height *= 2;
+
+ cam_rect->width = width;
+ cam_rect->height = height;
+
+ /*
+ * We do not know what capabilities the camera has to set up
+ * left and top borders. We could try to be smarter in iterating
+ * them, e.g., if camera current left is to the right of the
+ * target left, set it to the middle point between the current
+ * left and minimum left. But that would add too much
+ * complexity: we would have to iterate each border separately.
+ * Instead we just drop to the left and top bounds.
+ */
+ if (cam_rect->left > rect->left)
+ cam_rect->left = cap.bounds.left;
+
+ if (cam_rect->left + cam_rect->width < rect->left + rect->width)
+ cam_rect->width = rect->left + rect->width -
+ cam_rect->left;
+
+ if (cam_rect->top > rect->top)
+ cam_rect->top = cap.bounds.top;
+
+ if (cam_rect->top + cam_rect->height < rect->top + rect->height)
+ cam_rect->height = rect->top + rect->height -
+ cam_rect->top;
+
+ v4l2_subdev_call(sd, video, s_crop, cam_crop);
+ ret = soc_camera_client_g_rect(sd, cam_rect);
+ dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
+ cam_rect->width, cam_rect->height,
+ cam_rect->left, cam_rect->top);
+ }
+
+ /* S_CROP must not modify the rectangle */
+ if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
+ /*
+ * The camera failed to configure a suitable cropping,
+ * we cannot use the current rectangle, set to max
+ */
+ *cam_rect = cap.bounds;
+ v4l2_subdev_call(sd, video, s_crop, cam_crop);
+ ret = soc_camera_client_g_rect(sd, cam_rect);
+ dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
+ cam_rect->width, cam_rect->height,
+ cam_rect->left, cam_rect->top);
+ }
+
+ if (!ret) {
+ *target_rect = *cam_rect;
+ update_subrect(target_rect, subrect);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(soc_camera_client_s_crop);
+
+/* Iterative s_mbus_fmt, also updates cached client crop on success */
+static int client_s_fmt(struct soc_camera_device *icd,
+ struct v4l2_rect *rect, struct v4l2_rect *subrect,
+ unsigned int max_width, unsigned int max_height,
+ struct v4l2_mbus_framefmt *mf, bool host_can_scale)
+{
+ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+ struct device *dev = icd->parent;
+ unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
+ struct v4l2_cropcap cap;
+ bool host_1to1;
+ int ret;
+
+ ret = v4l2_device_call_until_err(sd->v4l2_dev,
+ soc_camera_grp_id(icd), video,
+ s_mbus_fmt, mf);
+ if (ret < 0)
+ return ret;
+
+ dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
+
+ if (width == mf->width && height == mf->height) {
+ /* Perfect! The client has done it all. */
+ host_1to1 = true;
+ goto update_cache;
+ }
+
+ host_1to1 = false;
+ if (!host_can_scale)
+ goto update_cache;
+
+ cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+ if (ret < 0)
+ return ret;
+
+ if (max_width > cap.bounds.width)
+ max_width = cap.bounds.width;
+ if (max_height > cap.bounds.height)
+ max_height = cap.bounds.height;
+
+ /* Camera set a format, but geometry is not precise, try to improve */
+ tmp_w = mf->width;
+ tmp_h = mf->height;
+
+ /* width <= max_width && height <= max_height - guaranteed by try_fmt */
+ while ((width > tmp_w || height > tmp_h) &&
+ tmp_w < max_width && tmp_h < max_height) {
+ tmp_w = min(2 * tmp_w, max_width);
+ tmp_h = min(2 * tmp_h, max_height);
+ mf->width = tmp_w;
+ mf->height = tmp_h;
+ ret = v4l2_device_call_until_err(sd->v4l2_dev,
+ soc_camera_grp_id(icd), video,
+ s_mbus_fmt, mf);
+ dev_geo(dev, "Camera scaled to %ux%u\n",
+ mf->width, mf->height);
+ if (ret < 0) {
+ /* This shouldn't happen */
+ dev_err(dev, "Client failed to set format: %d\n", ret);
+ return ret;
+ }
+ }
+
+update_cache:
+ /* Update cache */
+ ret = soc_camera_client_g_rect(sd, rect);
+ if (ret < 0)
+ return ret;
+
+ if (host_1to1)
+ *subrect = *rect;
+ else
+ update_subrect(rect, subrect);
+
+ return 0;
+}
+
+/**
+ * @icd - soc-camera device
+ * @rect - camera cropping window
+ * @subrect - part of rect, sent to the user
+ * @mf - in- / output camera output window
+ * @width - on input: max host input width
+ * on output: user width, mapped back to input
+ * @height - on input: max host input height
+ * on output: user height, mapped back to input
+ * @host_can_scale - host can scale this pixel format
+ * @shift - shift, used for scaling
+ */
+int soc_camera_client_scale(struct soc_camera_device *icd,
+ struct v4l2_rect *rect, struct v4l2_rect *subrect,
+ struct v4l2_mbus_framefmt *mf,
+ unsigned int *width, unsigned int *height,
+ bool host_can_scale, unsigned int shift)
+{
+ struct device *dev = icd->parent;
+ struct v4l2_mbus_framefmt mf_tmp = *mf;
+ unsigned int scale_h, scale_v;
+ int ret;
+
+ /*
+ * 5. Apply iterative camera S_FMT for camera user window (also updates
+ * client crop cache and the imaginary sub-rectangle).
+ */
+ ret = client_s_fmt(icd, rect, subrect, *width, *height,
+ &mf_tmp, host_can_scale);
+ if (ret < 0)
+ return ret;
+
+ dev_geo(dev, "5: camera scaled to %ux%u\n",
+ mf_tmp.width, mf_tmp.height);
+
+ /* 6. Retrieve camera output window (g_fmt) */
+
+ /* unneeded - it is already in "mf_tmp" */
+
+ /* 7. Calculate new client scales. */
+ scale_h = soc_camera_calc_scale(rect->width, shift, mf_tmp.width);
+ scale_v = soc_camera_calc_scale(rect->height, shift, mf_tmp.height);
+
+ mf->width = mf_tmp.width;
+ mf->height = mf_tmp.height;
+ mf->colorspace = mf_tmp.colorspace;
+
+ /*
+ * 8. Calculate new host crop - apply camera scales to previously
+ * updated "effective" crop.
+ */
+ *width = soc_camera_shift_scale(subrect->width, shift, scale_h);
+ *height = soc_camera_shift_scale(subrect->height, shift, scale_v);
+
+ dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
+
+ return 0;
+}
+EXPORT_SYMBOL(soc_camera_client_scale);
+
+/*
+ * Calculate real client output window by applying new scales to the current
+ * client crop. New scales are calculated from the requested output format and
+ * host crop, mapped backed onto the client input (subrect).
+ */
+void soc_camera_calc_client_output(struct soc_camera_device *icd,
+ struct v4l2_rect *rect, struct v4l2_rect *subrect,
+ const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf,
+ unsigned int shift)
+{
+ struct device *dev = icd->parent;
+ unsigned int scale_v, scale_h;
+
+ if (subrect->width == rect->width &&
+ subrect->height == rect->height) {
+ /* No sub-cropping */
+ mf->width = pix->width;
+ mf->height = pix->height;
+ return;
+ }
+
+ /* 1.-2. Current camera scales and subwin - cached. */
+
+ dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
+ subrect->width, subrect->height,
+ subrect->left, subrect->top);
+
+ /*
+ * 3. Calculate new combined scales from input sub-window to requested
+ * user window.
+ */
+
+ /*
+ * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
+ * (128x96) or larger than VGA. This and similar limitations have to be
+ * taken into account here.
+ */
+ scale_h = soc_camera_calc_scale(subrect->width, shift, pix->width);
+ scale_v = soc_camera_calc_scale(subrect->height, shift, pix->height);
+
+ dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
+
+ /*
+ * 4. Calculate desired client output window by applying combined scales
+ * to client (real) input window.
+ */
+ mf->width = soc_camera_shift_scale(rect->width, shift, scale_h);
+ mf->height = soc_camera_shift_scale(rect->height, shift, scale_v);
+}
+EXPORT_SYMBOL(soc_camera_calc_client_output);
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.h b/drivers/media/platform/soc_camera/soc_scale_crop.h
new file mode 100644
index 0000000..184a30d
--- /dev/null
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.h
@@ -0,0 +1,47 @@
+/*
+ * soc-camera generic scaling-cropping manipulation functions
+ *
+ * Copyright (C) 2013 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * 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.
+ */
+
+#ifndef SOC_SCALE_CROP_H
+#define SOC_SCALE_CROP_H
+
+#include <linux/kernel.h>
+
+struct soc_camera_device;
+
+struct v4l2_crop;
+struct v4l2_mbus_framefmt;
+struct v4l2_pix_format;
+struct v4l2_rect;
+struct v4l2_subdev;
+
+static inline unsigned int soc_camera_shift_scale(unsigned int size,
+ unsigned int shift, unsigned int scale)
+{
+ return DIV_ROUND_CLOSEST(size << shift, scale);
+}
+
+#define soc_camera_calc_scale(in, shift, out) soc_camera_shift_scale(in, shift, out)
+
+int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
+int soc_camera_client_s_crop(struct v4l2_subdev *sd,
+ struct v4l2_crop *crop, struct v4l2_crop *cam_crop,
+ struct v4l2_rect *target_rect, struct v4l2_rect *subrect);
+int soc_camera_client_scale(struct soc_camera_device *icd,
+ struct v4l2_rect *rect, struct v4l2_rect *subrect,
+ struct v4l2_mbus_framefmt *mf,
+ unsigned int *width, unsigned int *height,
+ bool host_can_scale, unsigned int shift);
+void soc_camera_calc_client_output(struct soc_camera_device *icd,
+ struct v4l2_rect *rect, struct v4l2_rect *subrect,
+ const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf,
+ unsigned int shift);
+
+#endif
diff --git a/drivers/media/platform/timblogiw.c b/drivers/media/platform/timblogiw.c
index a2f7bdd..b557caf 100644
--- a/drivers/media/platform/timblogiw.c
+++ b/drivers/media/platform/timblogiw.c
@@ -239,13 +239,12 @@
struct video_device *vdev = video_devdata(file);
dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
- memset(cap, 0, sizeof(*cap));
strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1);
strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1);
- strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info));
- cap->version = TIMBLOGIW_VERSION_CODE;
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", vdev->name);
+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
V4L2_CAP_READWRITE;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -834,11 +833,9 @@
goto err_request;
}
-
return 0;
err_request:
- platform_set_drvdata(pdev, NULL);
v4l2_device_unregister(&lw->v4l2_dev);
err_register:
kfree(lw);
@@ -858,8 +855,6 @@
kfree(lw);
- platform_set_drvdata(pdev, NULL);
-
return 0;
}
diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c
index a794cd6..b4f9d03 100644
--- a/drivers/media/platform/via-camera.c
+++ b/drivers/media/platform/via-camera.c
@@ -17,7 +17,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include <media/ov7670.h>
#include <media/videobuf-dma-sg.h>
@@ -805,20 +804,6 @@
* The long list of v4l2 ioctl ops
*/
-static int viacam_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *ident)
-{
- struct via_camera *cam = priv;
-
- ident->ident = V4L2_IDENT_NONE;
- ident->revision = 0;
- if (v4l2_chip_match_host(&ident->match)) {
- ident->ident = V4L2_IDENT_VIA_VX855;
- return 0;
- }
- return sensor_call(cam, core, g_chip_ident, ident);
-}
-
/*
* Only one input.
*/
@@ -852,6 +837,12 @@
return 0;
}
+static int viacam_g_std(struct file *filp, void *priv, v4l2_std_id *std)
+{
+ *std = V4L2_STD_NTSC_M;
+ return 0;
+}
+
/*
* Video format stuff. Here is our default format until
* user space messes with things.
@@ -1174,11 +1165,11 @@
static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
- .vidioc_g_chip_ident = viacam_g_chip_ident,
.vidioc_enum_input = viacam_enum_input,
.vidioc_g_input = viacam_g_input,
.vidioc_s_input = viacam_s_input,
.vidioc_s_std = viacam_s_std,
+ .vidioc_g_std = viacam_g_std,
.vidioc_enum_fmt_vid_cap = viacam_enum_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = viacam_try_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = viacam_g_fmt_vid_cap,
@@ -1266,7 +1257,6 @@
.name = "via-camera",
.minor = -1,
.tvnorms = V4L2_STD_NTSC_M,
- .current_norm = V4L2_STD_NTSC_M,
.fops = &viacam_fops,
.ioctl_ops = &viacam_ioctl_ops,
.release = video_device_release_empty, /* Check this */
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
index 4c9ae76..21db23b 100644
--- a/drivers/media/radio/radio-keene.c
+++ b/drivers/media/radio/radio-keene.c
@@ -93,7 +93,7 @@
/* If bit 4 is set, then tune to the frequency.
If bit 3 is set, then unmute; if bit 2 is set, then mute.
If bit 1 is set, then enter idle mode; if bit 0 is set,
- then enter transit mode.
+ then enter transmit mode.
*/
radio->buffer[5] = (radio->muted ? 4 : 8) | (play ? 1 : 2) |
(freq ? 0x10 : 0);
@@ -350,7 +350,6 @@
radio->pa = 118;
radio->tx = 0x32;
radio->stereo = true;
- radio->curfreq = 95.16 * FREQ_MUL;
if (hdl->error) {
retval = hdl->error;
@@ -383,6 +382,10 @@
video_set_drvdata(&radio->vdev, radio);
set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
+ /* at least 11ms is needed in order to settle hardware */
+ msleep(20);
+ keene_cmd_main(radio, 95.16 * FREQ_MUL, false);
+
retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
if (retval < 0) {
dev_err(&intf->dev, "could not register video device\n");
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index adfcc61..6f4318f 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -27,6 +27,8 @@
#include <linux/io.h> /* outb, outb_p */
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
#include "lm7000.h"
MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
@@ -44,10 +46,11 @@
struct fmi
{
struct v4l2_device v4l2_dev;
+ struct v4l2_ctrl_handler hdl;
struct video_device vdev;
int io;
bool mute;
- unsigned long curfreq; /* freq in kHz */
+ u32 curfreq; /* freq in kHz */
struct mutex lock;
};
@@ -55,8 +58,8 @@
static struct pnp_dev *dev;
bool pnp_attached;
-#define RSF16_MINFREQ (87 * 16000)
-#define RSF16_MAXFREQ (108 * 16000)
+#define RSF16_MINFREQ (87U * 16000)
+#define RSF16_MAXFREQ (108U * 16000)
#define FMI_BIT_TUN_CE (1 << 0)
#define FMI_BIT_TUN_CLK (1 << 1)
@@ -115,13 +118,22 @@
return (res & 2) ? 0 : 0xFFFF;
}
+static void fmi_set_freq(struct fmi *fmi)
+{
+ fmi->curfreq = clamp(fmi->curfreq, RSF16_MINFREQ, RSF16_MAXFREQ);
+ /* rounding in steps of 800 to match the freq
+ that will be used */
+ lm7000_set_freq((fmi->curfreq / 800) * 800, fmi, fmi_set_pins);
+}
+
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
strlcpy(v->card, "SF16-FMI/FMP/FMD radio", sizeof(v->card));
- strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
- v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ strlcpy(v->bus_info, "ISA:radio-sf16fmi", sizeof(v->bus_info));
+ v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -157,12 +169,10 @@
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
return -EINVAL;
- if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ)
- return -EINVAL;
- /* rounding in steps of 800 to match the freq
- that will be used */
- lm7000_set_freq((f->frequency / 800) * 800, fmi, fmi_set_pins);
+
+ fmi->curfreq = f->frequency;
+ fmi_set_freq(fmi);
+
return 0;
}
@@ -178,74 +188,31 @@
return 0;
}
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
+static int fmi_s_ctrl(struct v4l2_ctrl *ctrl)
{
- switch (qc->id) {
- case V4L2_CID_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
- }
- return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct fmi *fmi = video_drvdata(file);
+ struct fmi *fmi = container_of(ctrl->handler, struct fmi, hdl);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = fmi->mute;
- return 0;
- }
- return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct fmi *fmi = video_drvdata(file);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value)
+ if (ctrl->val)
fmi_mute(fmi);
else
fmi_unmute(fmi);
- fmi->mute = ctrl->value;
+ fmi->mute = ctrl->val;
return 0;
}
return -EINVAL;
}
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
- return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- a->index = 0;
- strlcpy(a->name, "Radio", sizeof(a->name));
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
- const struct v4l2_audio *a)
-{
- return a->index ? -EINVAL : 0;
-}
+static const struct v4l2_ctrl_ops fmi_ctrl_ops = {
+ .s_ctrl = fmi_s_ctrl,
+};
static const struct v4l2_file_operations fmi_fops = {
.owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = v4l2_fh_release,
+ .poll = v4l2_ctrl_poll,
.unlocked_ioctl = video_ioctl2,
};
@@ -253,15 +220,11 @@
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
/* ladis: this is my card. does any other types exist? */
@@ -311,6 +274,7 @@
{
struct fmi *fmi = &fmi_card;
struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
+ struct v4l2_ctrl_handler *hdl = &fmi->hdl;
int res, i;
int probe_ports[] = { 0, 0x284, 0x384 };
@@ -363,19 +327,35 @@
return res;
}
+ v4l2_ctrl_handler_init(hdl, 1);
+ v4l2_ctrl_new_std(hdl, &fmi_ctrl_ops,
+ V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+ v4l2_dev->ctrl_handler = hdl;
+ if (hdl->error) {
+ res = hdl->error;
+ v4l2_err(v4l2_dev, "Could not register controls\n");
+ v4l2_ctrl_handler_free(hdl);
+ v4l2_device_unregister(v4l2_dev);
+ return res;
+ }
+
strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
fmi->vdev.v4l2_dev = v4l2_dev;
fmi->vdev.fops = &fmi_fops;
fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
fmi->vdev.release = video_device_release_empty;
+ set_bit(V4L2_FL_USE_FH_PRIO, &fmi->vdev.flags);
video_set_drvdata(&fmi->vdev, fmi);
mutex_init(&fmi->lock);
- /* mute card - prevents noisy bootups */
- fmi_mute(fmi);
+ /* mute card and set default frequency */
+ fmi->mute = 1;
+ fmi->curfreq = RSF16_MINFREQ;
+ fmi_set_freq(fmi);
if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_ctrl_handler_free(hdl);
v4l2_device_unregister(v4l2_dev);
release_region(fmi->io, 2);
if (pnp_attached)
@@ -391,6 +371,7 @@
{
struct fmi *fmi = &fmi_card;
+ v4l2_ctrl_handler_free(&fmi->hdl);
video_unregister_device(&fmi->vdev);
v4l2_device_unregister(&fmi->v4l2_dev);
release_region(fmi->io, 2);
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index 9dc8baf..9c9084c 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -1018,16 +1018,6 @@
return retval;
}
-static int si476x_radio_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
- v4l2_chip_match_host(&chip->match))
- return 0;
- return -EINVAL;
-}
-
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int si476x_radio_g_register(struct file *file, void *fh,
struct v4l2_dbg_register *reg)
@@ -1203,7 +1193,6 @@
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = si476x_radio_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = si476x_radio_g_register,
.vidioc_s_register = si476x_radio_s_register,
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 38d563d..036e2f5 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -39,6 +39,9 @@
#include <linux/i2c.h> /* I2C */
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
#define DRIVER_VERSION "0.0.2"
@@ -57,8 +60,8 @@
/* Frequency limits in MHz -- these are European values. For Japanese
devices, that would be 76000 and 91000. */
-#define FREQ_MIN 87500
-#define FREQ_MAX 108000
+#define FREQ_MIN 87500U
+#define FREQ_MAX 108000U
#define FREQ_MUL 16
/* TEA5764 registers */
@@ -138,8 +141,10 @@
static int use_xtal = RADIO_TEA5764_XTAL;
struct tea5764_device {
+ struct v4l2_device v4l2_dev;
+ struct v4l2_ctrl_handler ctrl_handler;
struct i2c_client *i2c_client;
- struct video_device *videodev;
+ struct video_device vdev;
struct tea5764_regs regs;
struct mutex mutex;
};
@@ -187,18 +192,6 @@
return 0;
}
-/* V4L2 code related */
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
-
static void tea5764_power_up(struct tea5764_device *radio)
{
struct tea5764_regs *r = &radio->regs;
@@ -291,23 +284,19 @@
tea5764_i2c_write(radio);
}
-static int tea5764_is_muted(struct tea5764_device *radio)
-{
- return radio->regs.tnctrl & TEA5764_TNCTRL_MU;
-}
-
/* V4L2 vidioc */
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
struct tea5764_device *radio = video_drvdata(file);
- struct video_device *dev = radio->videodev;
+ struct video_device *dev = &radio->vdev;
strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
strlcpy(v->card, dev->name, sizeof(v->card));
snprintf(v->bus_info, sizeof(v->bus_info),
"I2C:%s", dev_name(&dev->dev));
- v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -320,8 +309,7 @@
if (v->index > 0)
return -EINVAL;
- memset(v, 0, sizeof(*v));
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
tea5764_i2c_read(radio);
v->rangelow = FREQ_MIN * FREQ_MUL;
@@ -354,19 +342,23 @@
const struct v4l2_frequency *f)
{
struct tea5764_device *radio = video_drvdata(file);
+ unsigned freq = f->frequency;
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
return -EINVAL;
- if (f->frequency == 0) {
+ if (freq == 0) {
/* We special case this as a power down control. */
tea5764_power_down(radio);
+ /* Yes, that's what is returned in this case. This
+ whole special case is non-compliant and should really
+ be replaced with something better, but changing this
+ might well break code that depends on this behavior.
+ So we keep it as-is. */
+ return -EINVAL;
}
- if (f->frequency < (FREQ_MIN * FREQ_MUL))
- return -EINVAL;
- if (f->frequency > (FREQ_MAX * FREQ_MUL))
- return -EINVAL;
+ clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
tea5764_power_up(radio);
- tea5764_tune(radio, (f->frequency * 125) / 2);
+ tea5764_tune(radio, (freq * 125) / 2);
return 0;
}
@@ -379,7 +371,6 @@
if (f->tuner != 0)
return -EINVAL;
tea5764_i2c_read(radio);
- memset(f, 0, sizeof(*f));
f->type = V4L2_TUNER_RADIO;
if (r->tnctrl & TEA5764_TNCTRL_PUPD0)
f->frequency = (tea5764_get_freq(radio) * 2) / 125;
@@ -389,83 +380,29 @@
return 0;
}
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
+static int tea5764_s_ctrl(struct v4l2_ctrl *ctrl)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct tea5764_device *radio = video_drvdata(file);
+ struct tea5764_device *radio =
+ container_of(ctrl->handler, struct tea5764_device, ctrl_handler);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- tea5764_i2c_read(radio);
- ctrl->value = tea5764_is_muted(radio) ? 1 : 0;
+ tea5764_mute(radio, ctrl->val);
return 0;
}
return -EINVAL;
}
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct tea5764_device *radio = video_drvdata(file);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- tea5764_mute(radio, ctrl->value);
- return 0;
- }
- return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
- const struct v4l2_audio *a)
-{
- if (a->index != 0)
- return -EINVAL;
-
- return 0;
-}
+static const struct v4l2_ctrl_ops tea5764_ctrl_ops = {
+ .s_ctrl = tea5764_s_ctrl,
+};
/* File system interface */
static const struct v4l2_file_operations tea5764_fops = {
.owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = v4l2_fh_release,
+ .poll = v4l2_ctrl_poll,
.unlocked_ioctl = video_ioctl2,
};
@@ -473,15 +410,11 @@
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
/* V4L2 interface */
@@ -489,7 +422,7 @@
.name = "TEA5764 FM-Radio",
.fops = &tea5764_fops,
.ioctl_ops = &tea5764_ioctl_ops,
- .release = video_device_release,
+ .release = video_device_release_empty,
};
/* I2C probe: check if the device exists and register with v4l if it is */
@@ -497,6 +430,8 @@
const struct i2c_device_id *id)
{
struct tea5764_device *radio;
+ struct v4l2_device *v4l2_dev;
+ struct v4l2_ctrl_handler *hdl;
struct tea5764_regs *r;
int ret;
@@ -505,31 +440,45 @@
if (!radio)
return -ENOMEM;
+ v4l2_dev = &radio->v4l2_dev;
+ ret = v4l2_device_register(&client->dev, v4l2_dev);
+ if (ret < 0) {
+ v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+ goto errfr;
+ }
+
+ hdl = &radio->ctrl_handler;
+ v4l2_ctrl_handler_init(hdl, 1);
+ v4l2_ctrl_new_std(hdl, &tea5764_ctrl_ops,
+ V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+ v4l2_dev->ctrl_handler = hdl;
+ if (hdl->error) {
+ ret = hdl->error;
+ v4l2_err(v4l2_dev, "Could not register controls\n");
+ goto errunreg;
+ }
+
mutex_init(&radio->mutex);
radio->i2c_client = client;
ret = tea5764_i2c_read(radio);
if (ret)
- goto errfr;
+ goto errunreg;
r = &radio->regs;
PDEBUG("chipid = %04X, manid = %04X", r->chipid, r->manid);
if (r->chipid != TEA5764_CHIPID ||
(r->manid & 0x0fff) != TEA5764_MANID) {
PWARN("This chip is not a TEA5764!");
ret = -EINVAL;
- goto errfr;
+ goto errunreg;
}
- radio->videodev = video_device_alloc();
- if (!(radio->videodev)) {
- ret = -ENOMEM;
- goto errfr;
- }
- memcpy(radio->videodev, &tea5764_radio_template,
- sizeof(tea5764_radio_template));
+ radio->vdev = tea5764_radio_template;
i2c_set_clientdata(client, radio);
- video_set_drvdata(radio->videodev, radio);
- radio->videodev->lock = &radio->mutex;
+ video_set_drvdata(&radio->vdev, radio);
+ radio->vdev.lock = &radio->mutex;
+ radio->vdev.v4l2_dev = v4l2_dev;
+ set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
/* initialize and power off the chip */
tea5764_i2c_read(radio);
@@ -537,16 +486,17 @@
tea5764_mute(radio, 1);
tea5764_power_down(radio);
- ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+ ret = video_register_device(&radio->vdev, VFL_TYPE_RADIO, radio_nr);
if (ret < 0) {
PWARN("Could not register video device!");
- goto errrel;
+ goto errunreg;
}
PINFO("registered.");
return 0;
-errrel:
- video_device_release(radio->videodev);
+errunreg:
+ v4l2_ctrl_handler_free(hdl);
+ v4l2_device_unregister(v4l2_dev);
errfr:
kfree(radio);
return ret;
@@ -559,7 +509,9 @@
PDEBUG("remove");
if (radio) {
tea5764_power_down(radio);
- video_unregister_device(radio->videodev);
+ video_unregister_device(&radio->vdev);
+ v4l2_ctrl_handler_free(&radio->ctrl_handler);
+ v4l2_device_unregister(&radio->v4l2_dev);
kfree(radio);
}
return 0;
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index bb7b143..0817964 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -19,6 +19,8 @@
#include <linux/io.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
@@ -44,7 +46,8 @@
strlcpy(v->driver, DRIVER_NAME, sizeof(v->driver));
strlcpy(v->card, "Timberdale Radio", sizeof(v->card));
snprintf(v->bus_info, sizeof(v->bus_info), "platform:"DRIVER_NAME);
- v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -62,34 +65,6 @@
return v4l2_subdev_call(tr->sd_tuner, tuner, s_tuner, v);
}
-static int timbradio_vidioc_g_input(struct file *filp, void *priv,
- unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int timbradio_vidioc_s_input(struct file *filp, void *priv,
- unsigned int i)
-{
- return i ? -EINVAL : 0;
-}
-
-static int timbradio_vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- a->index = 0;
- strlcpy(a->name, "Radio", sizeof(a->name));
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-static int timbradio_vidioc_s_audio(struct file *file, void *priv,
- const struct v4l2_audio *a)
-{
- return a->index ? -EINVAL : 0;
-}
-
static int timbradio_vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
@@ -104,44 +79,22 @@
return v4l2_subdev_call(tr->sd_tuner, tuner, g_frequency, f);
}
-static int timbradio_vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- struct timbradio *tr = video_drvdata(file);
- return v4l2_subdev_call(tr->sd_dsp, core, queryctrl, qc);
-}
-
-static int timbradio_vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct timbradio *tr = video_drvdata(file);
- return v4l2_subdev_call(tr->sd_dsp, core, g_ctrl, ctrl);
-}
-
-static int timbradio_vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct timbradio *tr = video_drvdata(file);
- return v4l2_subdev_call(tr->sd_dsp, core, s_ctrl, ctrl);
-}
-
static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
.vidioc_querycap = timbradio_vidioc_querycap,
.vidioc_g_tuner = timbradio_vidioc_g_tuner,
.vidioc_s_tuner = timbradio_vidioc_s_tuner,
.vidioc_g_frequency = timbradio_vidioc_g_frequency,
.vidioc_s_frequency = timbradio_vidioc_s_frequency,
- .vidioc_g_input = timbradio_vidioc_g_input,
- .vidioc_s_input = timbradio_vidioc_s_input,
- .vidioc_g_audio = timbradio_vidioc_g_audio,
- .vidioc_s_audio = timbradio_vidioc_s_audio,
- .vidioc_queryctrl = timbradio_vidioc_queryctrl,
- .vidioc_g_ctrl = timbradio_vidioc_g_ctrl,
- .vidioc_s_ctrl = timbradio_vidioc_s_ctrl
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
static const struct v4l2_file_operations timbradio_fops = {
.owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = v4l2_fh_release,
+ .poll = v4l2_ctrl_poll,
.unlocked_ioctl = video_ioctl2,
};
@@ -173,6 +126,7 @@
tr->video_dev.release = video_device_release_empty;
tr->video_dev.minor = -1;
tr->video_dev.lock = &tr->lock;
+ set_bit(V4L2_FL_USE_FH_PRIO, &tr->video_dev.flags);
strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
err = v4l2_device_register(NULL, &tr->v4l2_dev);
@@ -181,6 +135,15 @@
tr->video_dev.v4l2_dev = &tr->v4l2_dev;
+ tr->sd_tuner = v4l2_i2c_new_subdev_board(&tr->v4l2_dev,
+ i2c_get_adapter(pdata->i2c_adapter), pdata->tuner, NULL);
+ tr->sd_dsp = v4l2_i2c_new_subdev_board(&tr->v4l2_dev,
+ i2c_get_adapter(pdata->i2c_adapter), pdata->dsp, NULL);
+ if (tr->sd_tuner == NULL || tr->sd_dsp == NULL)
+ goto err_video_req;
+
+ tr->v4l2_dev.ctrl_handler = tr->sd_dsp->ctrl_handler;
+
err = video_register_device(&tr->video_dev, VFL_TYPE_RADIO, -1);
if (err) {
dev_err(&pdev->dev, "Error reg video\n");
@@ -193,7 +156,6 @@
return 0;
err_video_req:
- video_device_release_empty(&tr->video_dev);
v4l2_device_unregister(&tr->v4l2_dev);
err:
dev_err(&pdev->dev, "Failed to register: %d\n", err);
@@ -206,10 +168,7 @@
struct timbradio *tr = platform_get_drvdata(pdev);
video_unregister_device(&tr->video_dev);
- video_device_release_empty(&tr->video_dev);
-
v4l2_device_unregister(&tr->v4l2_dev);
-
return 0;
}
diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c
index 06c06cc..ec805b0 100644
--- a/drivers/media/radio/saa7706h.c
+++ b/drivers/media/radio/saa7706h.c
@@ -25,7 +25,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
#define DRIVER_NAME "saa7706h"
@@ -127,6 +127,7 @@
struct saa7706h_state {
struct v4l2_subdev sd;
+ struct v4l2_ctrl_handler hdl;
unsigned muted;
};
@@ -317,51 +318,32 @@
return err;
}
-static int saa7706h_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+static int saa7706h_s_ctrl(struct v4l2_ctrl *ctrl)
{
- switch (qc->id) {
- case V4L2_CID_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
- }
- return -EINVAL;
-}
-
-static int saa7706h_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct saa7706h_state *state = to_state(sd);
+ struct saa7706h_state *state =
+ container_of(ctrl->handler, struct saa7706h_state, hdl);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = state->muted;
- return 0;
+ if (ctrl->val)
+ return saa7706h_mute(&state->sd);
+ return saa7706h_unmute(&state->sd);
}
return -EINVAL;
}
-static int saa7706h_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value)
- return saa7706h_mute(sd);
- return saa7706h_unmute(sd);
- }
- return -EINVAL;
-}
-
-static int saa7706h_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7706H, 0);
-}
+static const struct v4l2_ctrl_ops saa7706h_ctrl_ops = {
+ .s_ctrl = saa7706h_s_ctrl,
+};
static const struct v4l2_subdev_core_ops saa7706h_core_ops = {
- .g_chip_ident = saa7706h_g_chip_ident,
- .queryctrl = saa7706h_queryctrl,
- .g_ctrl = saa7706h_g_ctrl,
- .s_ctrl = saa7706h_s_ctrl,
+ .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+ .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+ .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+ .g_ctrl = v4l2_subdev_g_ctrl,
+ .s_ctrl = v4l2_subdev_s_ctrl,
+ .queryctrl = v4l2_subdev_queryctrl,
+ .querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_ops saa7706h_ops = {
@@ -393,13 +375,20 @@
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &saa7706h_ops);
+ v4l2_ctrl_handler_init(&state->hdl, 4);
+ v4l2_ctrl_new_std(&state->hdl, &saa7706h_ctrl_ops,
+ V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+ sd->ctrl_handler = &state->hdl;
+ err = state->hdl.error;
+ if (err)
+ goto err;
+
/* check the rom versions */
err = saa7706h_get_reg16(sd, SAA7706H_DSP1_ROM_VER);
if (err < 0)
goto err;
if (err != SUPPORTED_DSP1_ROM_VER)
v4l2_warn(sd, "Unknown DSP1 ROM code version: 0x%x\n", err);
-
state->muted = 1;
/* startup in a muted state */
@@ -411,6 +400,7 @@
err:
v4l2_device_unregister_subdev(sd);
+ v4l2_ctrl_handler_free(&state->hdl);
kfree(to_state(sd));
printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", err);
@@ -421,9 +411,11 @@
static int saa7706h_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa7706h_state *state = to_state(sd);
saa7706h_mute(sd);
v4l2_device_unregister_subdev(sd);
+ v4l2_ctrl_handler_free(&state->hdl);
kfree(to_state(sd));
return 0;
}
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
index 82c6c94..06ac692 100644
--- a/drivers/media/radio/tef6862.c
+++ b/drivers/media/radio/tef6862.c
@@ -25,14 +25,13 @@
#include <linux/slab.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#define DRIVER_NAME "tef6862"
#define FREQ_MUL 16000
-#define TEF6862_LO_FREQ (875 * FREQ_MUL / 10)
-#define TEF6862_HI_FREQ (108 * FREQ_MUL)
+#define TEF6862_LO_FREQ (875U * FREQ_MUL / 10)
+#define TEF6862_HI_FREQ (108U * FREQ_MUL)
/* Write mode sub addresses */
#define WM_SUB_BANDWIDTH 0x0
@@ -105,6 +104,7 @@
{
struct tef6862_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
+ unsigned freq = f->frequency;
u16 pll;
u8 i2cmsg[3];
int err;
@@ -112,7 +112,8 @@
if (f->tuner != 0)
return -EINVAL;
- pll = 1964 + ((f->frequency - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
+ clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ);
+ pll = 1964 + ((freq - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM;
i2cmsg[1] = (pll >> 8) & 0xff;
i2cmsg[2] = pll & 0xff;
@@ -121,7 +122,7 @@
if (err != sizeof(i2cmsg))
return err < 0 ? err : -EIO;
- state->freq = f->frequency;
+ state->freq = freq;
return 0;
}
@@ -136,14 +137,6 @@
return 0;
}
-static int tef6862_g_chip_ident(struct v4l2_subdev *sd,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEF6862, 0);
-}
-
static const struct v4l2_subdev_tuner_ops tef6862_tuner_ops = {
.g_tuner = tef6862_g_tuner,
.s_tuner = tef6862_s_tuner,
@@ -151,12 +144,7 @@
.g_frequency = tef6862_g_frequency,
};
-static const struct v4l2_subdev_core_ops tef6862_core_ops = {
- .g_chip_ident = tef6862_g_chip_ident,
-};
-
static const struct v4l2_subdev_ops tef6862_ops = {
- .core = &tef6862_core_ops,
.tuner = &tef6862_tuner_ops,
};
diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h
index aac0f02..a587c9b 100644
--- a/drivers/media/radio/wl128x/fmdrv.h
+++ b/drivers/media/radio/wl128x/fmdrv.h
@@ -30,6 +30,7 @@
#include <linux/timer.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#define FM_DRV_VERSION "0.1.1"
@@ -202,6 +203,7 @@
/* FM driver operation structure */
struct fmdev {
struct video_device *radio_dev; /* V4L2 video device pointer */
+ struct v4l2_device v4l2_dev; /* V4L2 top level struct */
struct snd_card *card; /* Card which holds FM mixer controls */
u16 asci_id;
spinlock_t rds_buff_lock; /* To protect access to RDS buffer */
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
index a002234..253f307 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -715,7 +715,7 @@
struct fm_rdsdata_format rds_fmt;
struct fm_rds *rds = &fmdev->rx.rds;
unsigned long group_idx, flags;
- u8 *rds_data, meta_data, tmpbuf[3];
+ u8 *rds_data, meta_data, tmpbuf[FM_RDS_BLK_SIZE];
u8 type, blk_idx;
u16 cur_picode;
u32 rds_len;
@@ -1073,6 +1073,7 @@
u8 __user *buf, size_t count)
{
u32 block_count;
+ u8 tmpbuf[FM_RDS_BLK_SIZE];
unsigned long flags;
int ret;
@@ -1087,29 +1088,32 @@
}
/* Calculate block count from byte count */
- count /= 3;
+ count /= FM_RDS_BLK_SIZE;
block_count = 0;
ret = 0;
- spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
-
while (block_count < count) {
- if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx)
- break;
+ spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
- if (copy_to_user(buf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
- FM_RDS_BLK_SIZE))
+ if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) {
+ spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
break;
-
+ }
+ memcpy(tmpbuf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
+ FM_RDS_BLK_SIZE);
fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE;
if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size)
fmdev->rx.rds.rd_idx = 0;
+ spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
+
+ if (copy_to_user(buf, tmpbuf, FM_RDS_BLK_SIZE))
+ break;
+
block_count++;
buf += FM_RDS_BLK_SIZE;
ret += FM_RDS_BLK_SIZE;
}
- spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
return ret;
}
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
index 5dec323..b55012c 100644
--- a/drivers/media/radio/wl128x/fmdrv_v4l2.c
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -533,6 +533,11 @@
struct v4l2_ctrl *ctrl;
int ret;
+ strlcpy(fmdev->v4l2_dev.name, FM_DRV_NAME, sizeof(fmdev->v4l2_dev.name));
+ ret = v4l2_device_register(NULL, &fmdev->v4l2_dev);
+ if (ret < 0)
+ return ret;
+
/* Init mutex for core locking */
mutex_init(&fmdev->mutex);
@@ -549,6 +554,7 @@
video_set_drvdata(gradio_dev, fmdev);
gradio_dev->lock = &fmdev->mutex;
+ gradio_dev->v4l2_dev = &fmdev->v4l2_dev;
/* Register with V4L2 subsystem as RADIO device */
if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
@@ -611,5 +617,7 @@
/* Unregister RADIO device from V4L2 subsystem */
video_unregister_device(gradio_dev);
+ v4l2_device_unregister(&fmdev->v4l2_dev);
+
return fmdev;
}
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index 8b82ae9..07aacfa 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -178,7 +178,6 @@
return 0;
err_request_irq:
- platform_set_drvdata(pdev, NULL);
rc_unregister_device(rcdev);
rcdev = NULL;
err_register_rc_device:
@@ -196,7 +195,6 @@
struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
- platform_set_drvdata(pdev, NULL);
rc_unregister_device(gpio_dev->rcdev);
gpio_free(gpio_dev->gpio_nr);
kfree(gpio_dev);
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 5ab94ea..b1cde8c 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -20,6 +20,7 @@
rc-budget-ci-old.o \
rc-cinergy-1400.o \
rc-cinergy.o \
+ rc-delock-61959.o \
rc-dib0700-nec.o \
rc-dib0700-rc5.o \
rc-digitalnow-tinytwin.o \
diff --git a/drivers/media/rc/keymaps/rc-delock-61959.c b/drivers/media/rc/keymaps/rc-delock-61959.c
new file mode 100644
index 0000000..01bed86
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-delock-61959.c
@@ -0,0 +1,83 @@
+/* rc-delock-61959.c - Keytable for Delock
+ *
+ * Copyright (c) 2013 by Jakob Haufe <sur5r@sur5r.net>
+ *
+ * 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.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+ * Keytable for remote provided with Delock 61959
+ */
+static struct rc_map_table delock_61959[] = {
+ { 0x866b16, KEY_POWER2 }, /* Power */
+ { 0x866b0c, KEY_POWER }, /* Shut Down */
+
+ { 0x866b00, KEY_1},
+ { 0x866b01, KEY_2},
+ { 0x866b02, KEY_3},
+ { 0x866b03, KEY_4},
+ { 0x866b04, KEY_5},
+ { 0x866b05, KEY_6},
+ { 0x866b06, KEY_7},
+ { 0x866b07, KEY_8},
+ { 0x866b08, KEY_9},
+ { 0x866b14, KEY_0},
+
+ { 0x866b0a, KEY_ZOOM}, /* Full Screen */
+ { 0x866b10, KEY_CAMERA}, /* Photo */
+ { 0x866b0e, KEY_CHANNEL}, /* circular arrow / Recall */
+ { 0x866b13, KEY_ESC}, /* Back */
+
+ { 0x866b20, KEY_UP},
+ { 0x866b21, KEY_DOWN},
+ { 0x866b42, KEY_LEFT},
+ { 0x866b43, KEY_RIGHT},
+ { 0x866b0b, KEY_OK},
+
+ { 0x866b11, KEY_CHANNELUP},
+ { 0x866b1b, KEY_CHANNELDOWN},
+
+ { 0x866b12, KEY_VOLUMEUP},
+ { 0x866b48, KEY_VOLUMEDOWN},
+ { 0x866b44, KEY_MUTE},
+
+ { 0x866b1a, KEY_RECORD},
+ { 0x866b41, KEY_PLAY},
+ { 0x866b40, KEY_STOP},
+ { 0x866b19, KEY_PAUSE},
+ { 0x866b1c, KEY_FASTFORWARD}, /* >> / FWD */
+ { 0x866b1e, KEY_REWIND}, /* << / REW */
+
+};
+
+static struct rc_map_list delock_61959_map = {
+ .map = {
+ .scan = delock_61959,
+ .size = ARRAY_SIZE(delock_61959),
+ .rc_type = RC_TYPE_NEC,
+ .name = RC_MAP_DELOCK_61959,
+ }
+};
+
+static int __init init_rc_map_delock_61959(void)
+{
+ return rc_map_register(&delock_61959_map);
+}
+
+static void __exit exit_rc_map_delock_61959(void)
+{
+ rc_map_unregister(&delock_61959_map);
+}
+
+module_init(init_rc_map_delock_61959)
+module_exit(exit_rc_map_delock_61959)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jakob Haufe <sur5r@sur5r.net>");
+MODULE_DESCRIPTION("Delock 61959 remote keytable");
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index 4835021..1c23666 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -364,8 +364,8 @@
}
if (len <= 0)
return;
- if (len > NUM_REGS)
- len = NUM_REGS;
+ if (len > NUM_REGS - r)
+ len = NUM_REGS - r;
tuner_dbg("%s: prev reg=%02x len=%d: %*ph\n",
__func__, r + REG_SHADOW_START, len, len, val);
@@ -1857,9 +1857,9 @@
int reg18, reg19, reg1f;
if (priv->cfg->xtal > 24000000)
- ring_ref = priv->cfg->xtal / 2;
+ ring_ref = priv->cfg->xtal / 2000;
else
- ring_ref = priv->cfg->xtal;
+ ring_ref = priv->cfg->xtal / 1000;
n_ring = 15;
for (n = 0; n < 16; n++) {
@@ -2256,7 +2256,6 @@
mutex_unlock(&r820t_list_mutex);
- kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
@@ -2311,8 +2310,6 @@
break;
}
- memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops, sizeof(r820t_tuner_ops));
-
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -2327,15 +2324,14 @@
tuner_info("Rafael Micro r820t successfully identified\n");
- fe->tuner_priv = priv;
- memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
- sizeof(struct dvb_tuner_ops));
-
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
mutex_unlock(&r820t_list_mutex);
+ memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
return fe;
err:
if (fe->ops.i2c_gate_ctrl)
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
index 0a7d520..cfe8056 100644
--- a/drivers/media/usb/Kconfig
+++ b/drivers/media/usb/Kconfig
@@ -1,6 +1,7 @@
+if USB && MEDIA_SUPPORT
+
menuconfig MEDIA_USB_SUPPORT
bool "Media USB Adapters"
- depends on USB && MEDIA_SUPPORT
help
Enable media drivers for USB bus.
If you have such devices, say Y.
@@ -17,6 +18,7 @@
source "drivers/media/usb/stkwebcam/Kconfig"
source "drivers/media/usb/s2255/Kconfig"
source "drivers/media/usb/sn9c102/Kconfig"
+source "drivers/media/usb/usbtv/Kconfig"
endif
if MEDIA_ANALOG_TV_SUPPORT
@@ -52,3 +54,4 @@
endif
endif #MEDIA_USB_SUPPORT
+endif #USB
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
index 7f51d7e..0935f47 100644
--- a/drivers/media/usb/Makefile
+++ b/drivers/media/usb/Makefile
@@ -20,3 +20,4 @@
obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
obj-$(CONFIG_VIDEO_TM6000) += tm6000/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
+obj-$(CONFIG_VIDEO_USBTV) += usbtv/
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 75ac994..f615454 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -36,7 +36,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
#include <media/tuner.h>
#include "au0828.h"
#include "au0828-reg.h"
@@ -1638,26 +1637,6 @@
return 0;
}
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
-
- if (v4l2_chip_match_host(&chip->match)) {
- chip->ident = V4L2_IDENT_AU0828;
- return 0;
- }
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
- if (chip->ident == V4L2_IDENT_NONE)
- return -EINVAL;
-
- return 0;
-}
-
static int vidioc_cropcap(struct file *file, void *priv,
struct v4l2_cropcap *cc)
{
@@ -1779,16 +1758,8 @@
struct au0828_fh *fh = priv;
struct au0828_dev *dev = fh->dev;
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
- return 0;
- default:
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
- }
-
reg->val = au0828_read(dev, reg->reg);
+ reg->size = 1;
return 0;
}
@@ -1798,14 +1769,6 @@
struct au0828_fh *fh = priv;
struct au0828_dev *dev = fh->dev;
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
- return 0;
- default:
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
- }
return au0828_writereg(dev, reg->reg, reg->val);
}
#endif
@@ -1943,7 +1906,6 @@
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
#endif
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
.vidioc_log_status = vidioc_log_status,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index f548db8..2f63029 100644
--- a/drivers/media/usb/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -1840,7 +1840,6 @@
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_log_status = vidioc_log_status,
- .vidioc_g_chip_ident = cx231xx_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = cx231xx_g_register,
.vidioc_s_register = cx231xx_s_register,
diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c
index 235ba65..89de00b 100644
--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
@@ -35,7 +35,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
#include "cx231xx.h"
#include "cx231xx-dif.h"
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 13249e5..27948e1 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -29,7 +29,6 @@
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
#include <media/cx25840.h>
#include "dvb-usb-ids.h"
diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c
index 1340ff2..c027942 100644
--- a/drivers/media/usb/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c
@@ -32,7 +32,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
#include <media/msp3400.h>
#include <media/tuner.h>
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index cd22147..9906261 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -36,7 +36,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
#include <media/msp3400.h>
#include <media/tuner.h>
@@ -1228,179 +1227,93 @@
return rc;
}
-int cx231xx_g_chip_ident(struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+int cx231xx_g_chip_info(struct file *file, void *fh,
+ struct v4l2_dbg_chip_info *chip)
{
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(&chip->match))
- chip->ident = V4L2_IDENT_CX23100;
+ switch (chip->match.addr) {
+ case 0: /* Cx231xx - internal registers */
+ return 0;
+ case 1: /* AFE - read byte */
+ strlcpy(chip->name, "AFE (byte)", sizeof(chip->name));
+ return 0;
+ case 2: /* Video Block - read byte */
+ strlcpy(chip->name, "Video (byte)", sizeof(chip->name));
+ return 0;
+ case 3: /* I2S block - read byte */
+ strlcpy(chip->name, "I2S (byte)", sizeof(chip->name));
+ return 0;
+ case 4: /* AFE - read dword */
+ strlcpy(chip->name, "AFE (dword)", sizeof(chip->name));
+ return 0;
+ case 5: /* Video Block - read dword */
+ strlcpy(chip->name, "Video (dword)", sizeof(chip->name));
+ return 0;
+ case 6: /* I2S Block - read dword */
+ strlcpy(chip->name, "I2S (dword)", sizeof(chip->name));
return 0;
}
return -EINVAL;
}
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-
-/*
- -R, --list-registers=type=<host/i2cdrv/i2caddr>,
- chip=<chip>[,min=<addr>,max=<addr>]
- dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER]
- -r, --set-register=type=<host/i2cdrv/i2caddr>,
- chip=<chip>,reg=<addr>,val=<val>
- set the register [VIDIOC_DBG_S_REGISTER]
-
- if type == host, then <chip> is the hosts chip ID (default 0)
- if type == i2cdrv (default), then <chip> is the I2C driver name or ID
- if type == i2caddr, then <chip> is the 7-bit I2C address
-*/
-
int cx231xx_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg)
{
struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev;
- int ret = 0;
+ int ret;
u8 value[4] = { 0, 0, 0, 0 };
u32 data = 0;
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- switch (reg->match.addr) {
- case 0: /* Cx231xx - internal registers */
- ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
- (u16)reg->reg, value, 4);
- reg->val = value[0] | value[1] << 8 |
- value[2] << 16 | value[3] << 24;
- break;
- case 1: /* AFE - read byte */
- ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2, &data, 1);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 14: /* AFE - read dword */
- ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2, &data, 4);
- reg->val = le32_to_cpu(data);
- break;
- case 2: /* Video Block - read byte */
- ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2, &data, 1);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 24: /* Video Block - read dword */
- ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2, &data, 4);
- reg->val = le32_to_cpu(data);
- break;
- case 3: /* I2S block - read byte */
- ret = cx231xx_read_i2c_data(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- &data, 1);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 34: /* I2S Block - read dword */
- ret =
- cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1, &data, 4);
- reg->val = le32_to_cpu(data);
- break;
- }
- return ret < 0 ? ret : 0;
-
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- call_all(dev, core, g_register, reg);
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:/*for register debug*/
- switch (reg->match.addr) {
- case 0: /* Cx231xx - internal registers */
- ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
- (u16)reg->reg, value, 4);
- reg->val = value[0] | value[1] << 8 |
- value[2] << 16 | value[3] << 24;
-
- break;
- case 0x600:/* AFE - read byte */
- ret = cx231xx_read_i2c_master(dev, AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2,
- &data, 1 , 0);
- reg->val = le32_to_cpu(data & 0xff);
- break;
-
- case 0x880:/* Video Block - read byte */
- if (reg->reg < 0x0b) {
- ret = cx231xx_read_i2c_master(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- &data, 1 , 0);
- reg->val = le32_to_cpu(data & 0xff);
- } else {
- ret = cx231xx_read_i2c_master(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- &data, 4 , 0);
- reg->val = le32_to_cpu(data);
- }
- break;
- case 0x980:
- ret = cx231xx_read_i2c_master(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- &data, 1 , 0);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 0x400:
- ret =
- cx231xx_read_i2c_master(dev, 0x40,
- (u16)reg->reg, 1,
- &data, 1 , 0);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 0xc01:
- ret =
- cx231xx_read_i2c_master(dev, 0xc0,
- (u16)reg->reg, 2,
- &data, 38, 1);
- reg->val = le32_to_cpu(data);
- break;
- case 0x022:
- ret =
- cx231xx_read_i2c_master(dev, 0x02,
- (u16)reg->reg, 1,
- &data, 1, 2);
- reg->val = le32_to_cpu(data & 0xff);
- break;
- case 0x322:
- ret = cx231xx_read_i2c_master(dev,
- 0x32,
- (u16)reg->reg, 1,
- &data, 4 , 2);
- reg->val = le32_to_cpu(data);
- break;
- case 0x342:
- ret = cx231xx_read_i2c_master(dev,
- 0x34,
- (u16)reg->reg, 1,
- &data, 4 , 2);
- reg->val = le32_to_cpu(data);
- break;
-
- default:
- cx231xx_info("no match device address!!\n");
- break;
- }
- return ret < 0 ? ret : 0;
- /*return -EINVAL;*/
+ switch (reg->match.addr) {
+ case 0: /* Cx231xx - internal registers */
+ ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
+ (u16)reg->reg, value, 4);
+ reg->val = value[0] | value[1] << 8 |
+ value[2] << 16 | value[3] << 24;
+ reg->size = 4;
+ break;
+ case 1: /* AFE - read byte */
+ ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+ (u16)reg->reg, 2, &data, 1);
+ reg->val = data;
+ reg->size = 1;
+ break;
+ case 2: /* Video Block - read byte */
+ ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ (u16)reg->reg, 2, &data, 1);
+ reg->val = data;
+ reg->size = 1;
+ break;
+ case 3: /* I2S block - read byte */
+ ret = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ (u16)reg->reg, 1, &data, 1);
+ reg->val = data;
+ reg->size = 1;
+ break;
+ case 4: /* AFE - read dword */
+ ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+ (u16)reg->reg, 2, &data, 4);
+ reg->val = data;
+ reg->size = 4;
+ break;
+ case 5: /* Video Block - read dword */
+ ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ (u16)reg->reg, 2, &data, 4);
+ reg->val = data;
+ reg->size = 4;
+ break;
+ case 6: /* I2S Block - read dword */
+ ret = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ (u16)reg->reg, 1, &data, 4);
+ reg->val = data;
+ reg->size = 4;
+ break;
default:
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
+ return -EINVAL;
}
-
- call_all(dev, core, g_register, reg);
-
- return ret;
+ return ret < 0 ? ret : 0;
}
int cx231xx_s_register(struct file *file, void *priv,
@@ -1408,165 +1321,46 @@
{
struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev;
- int ret = 0;
- __le64 buf;
- u32 value;
+ int ret;
u8 data[4] = { 0, 0, 0, 0 };
- buf = cpu_to_le64(reg->val);
-
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- {
- value = (u32) buf & 0xffffffff;
-
- switch (reg->match.addr) {
- case 0: /* cx231xx internal registers */
- data[0] = (u8) value;
- data[1] = (u8) (value >> 8);
- data[2] = (u8) (value >> 16);
- data[3] = (u8) (value >> 24);
- ret = cx231xx_write_ctrl_reg(dev,
- VRT_SET_REGISTER,
- (u16)reg->reg, data,
- 4);
- break;
- case 1: /* AFE - read byte */
- ret = cx231xx_write_i2c_data(dev,
- AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2,
- value, 1);
- break;
- case 14: /* AFE - read dword */
- ret = cx231xx_write_i2c_data(dev,
- AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2,
- value, 4);
- break;
- case 2: /* Video Block - read byte */
- ret =
- cx231xx_write_i2c_data(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- value, 1);
- break;
- case 24: /* Video Block - read dword */
- ret =
- cx231xx_write_i2c_data(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- value, 4);
- break;
- case 3: /* I2S block - read byte */
- ret =
- cx231xx_write_i2c_data(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- value, 1);
- break;
- case 34: /* I2S block - read dword */
- ret =
- cx231xx_write_i2c_data(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- value, 4);
- break;
- }
- }
- return ret < 0 ? ret : 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- {
- value = (u32) buf & 0xffffffff;
-
- switch (reg->match.addr) {
- case 0:/*cx231xx internal registers*/
- data[0] = (u8) value;
- data[1] = (u8) (value >> 8);
- data[2] = (u8) (value >> 16);
- data[3] = (u8) (value >> 24);
- ret = cx231xx_write_ctrl_reg(dev,
- VRT_SET_REGISTER,
- (u16)reg->reg, data,
- 4);
- break;
- case 0x600:/* AFE - read byte */
- ret = cx231xx_write_i2c_master(dev,
- AFE_DEVICE_ADDRESS,
- (u16)reg->reg, 2,
- value, 1 , 0);
- break;
-
- case 0x880:/* Video Block - read byte */
- if (reg->reg < 0x0b)
- cx231xx_write_i2c_master(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- value, 1, 0);
- else
- cx231xx_write_i2c_master(dev,
- VID_BLK_I2C_ADDRESS,
- (u16)reg->reg, 2,
- value, 4, 0);
- break;
- case 0x980:
- ret =
- cx231xx_write_i2c_master(dev,
- I2S_BLK_DEVICE_ADDRESS,
- (u16)reg->reg, 1,
- value, 1, 0);
- break;
- case 0x400:
- ret =
- cx231xx_write_i2c_master(dev,
- 0x40,
- (u16)reg->reg, 1,
- value, 1, 0);
- break;
- case 0xc01:
- ret =
- cx231xx_write_i2c_master(dev,
- 0xc0,
- (u16)reg->reg, 1,
- value, 1, 1);
- break;
-
- case 0x022:
- ret =
- cx231xx_write_i2c_master(dev,
- 0x02,
- (u16)reg->reg, 1,
- value, 1, 2);
- break;
- case 0x322:
- ret =
- cx231xx_write_i2c_master(dev,
- 0x32,
- (u16)reg->reg, 1,
- value, 4, 2);
- break;
-
- case 0x342:
- ret =
- cx231xx_write_i2c_master(dev,
- 0x34,
- (u16)reg->reg, 1,
- value, 4, 2);
- break;
- default:
- cx231xx_info("no match device address, "
- "the value is %x\n", reg->match.addr);
- break;
-
- }
-
- }
- default:
+ switch (reg->match.addr) {
+ case 0: /* cx231xx internal registers */
+ data[0] = (u8) reg->val;
+ data[1] = (u8) (reg->val >> 8);
+ data[2] = (u8) (reg->val >> 16);
+ data[3] = (u8) (reg->val >> 24);
+ ret = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+ (u16)reg->reg, data, 4);
break;
+ case 1: /* AFE - write byte */
+ ret = cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
+ (u16)reg->reg, 2, reg->val, 1);
+ break;
+ case 2: /* Video Block - write byte */
+ ret = cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ (u16)reg->reg, 2, reg->val, 1);
+ break;
+ case 3: /* I2S block - write byte */
+ ret = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ (u16)reg->reg, 1, reg->val, 1);
+ break;
+ case 4: /* AFE - write dword */
+ ret = cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
+ (u16)reg->reg, 2, reg->val, 4);
+ break;
+ case 5: /* Video Block - write dword */
+ ret = cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+ (u16)reg->reg, 2, reg->val, 4);
+ break;
+ case 6: /* I2S block - write dword */
+ ret = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+ (u16)reg->reg, 1, reg->val, 4);
+ break;
+ default:
+ return -EINVAL;
}
-
- call_all(dev, core, s_register, reg);
-
- return ret;
+ return ret < 0 ? ret : 0;
}
#endif
@@ -2208,8 +2002,8 @@
.vidioc_s_tuner = cx231xx_s_tuner,
.vidioc_g_frequency = cx231xx_g_frequency,
.vidioc_s_frequency = cx231xx_s_frequency,
- .vidioc_g_chip_ident = cx231xx_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_chip_info = cx231xx_g_chip_info,
.vidioc_g_register = cx231xx_g_register,
.vidioc_s_register = cx231xx_s_register,
#endif
@@ -2240,8 +2034,8 @@
.vidioc_s_tuner = radio_s_tuner,
.vidioc_g_frequency = cx231xx_g_frequency,
.vidioc_s_frequency = cx231xx_s_frequency,
- .vidioc_g_chip_ident = cx231xx_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_chip_info = cx231xx_g_chip_info,
.vidioc_g_register = cx231xx_g_register,
.vidioc_s_register = cx231xx_s_register,
#endif
diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h
index 5ad9fd6..e812119 100644
--- a/drivers/media/usb/cx231xx/cx231xx.h
+++ b/drivers/media/usb/cx231xx/cx231xx.h
@@ -945,7 +945,7 @@
struct v4l2_input *i);
int cx231xx_g_input(struct file *file, void *priv, unsigned int *i);
int cx231xx_s_input(struct file *file, void *priv, unsigned int i);
-int cx231xx_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip);
+int cx231xx_g_chip_info(struct file *file, void *fh, struct v4l2_dbg_chip_info *chip);
int cx231xx_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg);
int cx231xx_s_register(struct file *file, void *priv,
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index b638fc1..1ea17dc 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -55,7 +55,7 @@
if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n",
- __func__, req->wlen, req->rlen);
+ KBUILD_MODNAME, req->wlen, req->rlen);
ret = -EINVAL;
goto exit;
}
@@ -91,9 +91,10 @@
checksum = af9035_checksum(state->buf, rlen - 2);
tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1];
if (tmp_checksum != checksum) {
- dev_err(&d->udev->dev, "%s: command=%02x checksum mismatch " \
- "(%04x != %04x)\n", KBUILD_MODNAME, req->cmd,
- tmp_checksum, checksum);
+ dev_err(&d->udev->dev,
+ "%s: command=%02x checksum mismatch (%04x != %04x)\n",
+ KBUILD_MODNAME, req->cmd, tmp_checksum,
+ checksum);
ret = -EIO;
goto exit;
}
@@ -268,11 +269,29 @@
memcpy(&buf[5], msg[0].buf, msg[0].len);
ret = af9035_ctrl_msg(d, &req);
}
+ } else if (num == 1 && (msg[0].flags & I2C_M_RD)) {
+ if (msg[0].len > 40) {
+ /* TODO: correct limits > 40 */
+ ret = -EOPNOTSUPP;
+ } else {
+ /* I2C */
+ u8 buf[5];
+ struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
+ buf, msg[0].len, msg[0].buf };
+ req.mbox |= ((msg[0].addr & 0x80) >> 3);
+ buf[0] = msg[0].len;
+ buf[1] = msg[0].addr << 1;
+ buf[2] = 0x00; /* reg addr len */
+ buf[3] = 0x00; /* reg addr MSB */
+ buf[4] = 0x00; /* reg addr LSB */
+ ret = af9035_ctrl_msg(d, &req);
+ }
} else {
/*
- * We support only two kind of I2C transactions:
- * 1) 1 x read + 1 x write
+ * We support only three kind of I2C transactions:
+ * 1) 1 x read + 1 x write (repeated start)
* 2) 1 x write
+ * 3) 1 x read
*/
ret = -EOPNOTSUPP;
}
@@ -317,8 +336,8 @@
dev_info(&d->udev->dev,
"%s: prechip_version=%02x chip_version=%02x chip_type=%04x\n",
- __func__, state->prechip_version, state->chip_version,
- state->chip_type);
+ KBUILD_MODNAME, state->prechip_version,
+ state->chip_version, state->chip_type);
if (state->chip_type == 0x9135) {
if (state->chip_version == 0x02)
@@ -382,9 +401,10 @@
hdr_checksum = fw->data[fw->size - i + 5] << 8;
hdr_checksum |= fw->data[fw->size - i + 6] << 0;
- dev_dbg(&d->udev->dev, "%s: core=%d addr=%04x data_len=%d " \
- "checksum=%04x\n", __func__, hdr_core, hdr_addr,
- hdr_data_len, hdr_checksum);
+ dev_dbg(&d->udev->dev,
+ "%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
+ __func__, hdr_core, hdr_addr, hdr_data_len,
+ hdr_checksum);
if (((hdr_core != 1) && (hdr_core != 2)) ||
(hdr_data_len > i)) {
@@ -489,7 +509,7 @@
u8 rbuf[4];
u8 tmp;
struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
- struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
+ struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf };
dev_dbg(&d->udev->dev, "%s:\n", __func__);
/*
@@ -498,11 +518,11 @@
* which is done by master demod.
* Master feeds also clock and controls power via GPIO.
*/
- ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_DUAL_MODE, &tmp);
+ ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
if (ret < 0)
goto err;
- if (tmp) {
+ if (tmp == 1 || tmp == 3) {
/* configure gpioh1, reset & power slave demod */
ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01);
if (ret < 0)
@@ -620,13 +640,15 @@
}
/* check if there is dual tuners */
- ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_DUAL_MODE, &tmp);
+ ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
if (ret < 0)
goto err;
- state->dual_mode = tmp;
- dev_dbg(&d->udev->dev, "%s: dual mode=%d\n", __func__,
- state->dual_mode);
+ if (tmp == 1 || tmp == 3)
+ state->dual_mode = true;
+
+ dev_dbg(&d->udev->dev, "%s: ts mode=%d dual mode=%d\n", __func__,
+ tmp, state->dual_mode);
if (state->dual_mode) {
/* read 2nd demodulator I2C address */
@@ -1200,9 +1222,9 @@
{ 0x80f9a4, 0x00, 0x01 },
};
- dev_dbg(&d->udev->dev, "%s: USB speed=%d frame_size=%04x " \
- "packet_size=%02x\n", __func__,
- d->udev->speed, frame_size, packet_size);
+ dev_dbg(&d->udev->dev,
+ "%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
+ __func__, d->udev->speed, frame_size, packet_size);
/* init endpoints */
for (i = 0; i < ARRAY_SIZE(tab); i++) {
@@ -1477,7 +1499,7 @@
&af9035_props, "AVerMedia Twinstar (A825)", NULL) },
{ DVB_USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100MINI_PLUS,
&af9035_props, "Asus U3100Mini Plus", NULL) },
- { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
+ { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
&af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) },
/* IT9135 devices */
#if 0
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
index b5827ca..a1c68d8 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.h
+++ b/drivers/media/usb/dvb-usb-v2/af9035.h
@@ -100,8 +100,13 @@
* eeprom is memory mapped as read only. Writing that memory mapped address
* will not corrupt eeprom.
*
- * eeprom has value 0x00 single mode and 0x03 for dual mode as far as I have
- * seen to this day.
+ * TS mode:
+ * 0 TS
+ * 1 DCA + PIP
+ * 3 PIP
+ * n DCA
+ *
+ * Values 0 and 3 are seen to this day. 0 for single TS and 3 for dual TS.
*/
#define EEPROM_BASE_AF9035 0x42fd
@@ -109,7 +114,7 @@
#define EEPROM_SHIFT 0x10
#define EEPROM_IR_MODE 0x10
-#define EEPROM_DUAL_MODE 0x29
+#define EEPROM_TS_MODE 0x29
#define EEPROM_2ND_DEMOD_ADDR 0x2a
#define EEPROM_IR_TYPE 0x2c
#define EEPROM_1_IF_L 0x30
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
index 658c6d4..399916b 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -140,7 +140,7 @@
int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
int (*query) (struct dvb_usb_device *d);
unsigned int interval;
- const enum rc_driver_type driver_type;
+ enum rc_driver_type driver_type;
bool bulk_mode;
};
diff --git a/drivers/media/usb/dvb-usb-v2/it913x.c b/drivers/media/usb/dvb-usb-v2/it913x.c
index e48cdeb..1cb6899 100644
--- a/drivers/media/usb/dvb-usb-v2/it913x.c
+++ b/drivers/media/usb/dvb-usb-v2/it913x.c
@@ -45,7 +45,7 @@
static int dvb_usb_it913x_firmware;
module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
-MODULE_PARM_DESC(firmware, "set firmware 0=auto"\
+MODULE_PARM_DESC(firmware, "set firmware 0=auto "\
"1=IT9137 2=IT9135 V1 3=IT9135 V2");
#define FW_IT9137 "dvb-usb-it9137-01.fw"
#define FW_IT9135_V1 "dvb-usb-it9135-01.fw"
@@ -796,6 +796,9 @@
{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
&it913x_properties, "Avermedia A835B(4835)",
RC_MAP_IT913X_V2) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2,
+ &it913x_properties, "Digital Dual TV Receiver CTVDIGDUAL_V2",
+ RC_MAP_IT913X_V1) },
{} /* Terminating entry */
};
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
index ef4c65f..879c529 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
@@ -31,8 +31,6 @@
if (mxl111sf_tuner_debug) \
mxl_printk(KERN_DEBUG, fmt, ##arg)
-#define err pr_err
-
/* ------------------------------------------------------------------------ */
struct mxl111sf_tuner_state {
@@ -113,7 +111,7 @@
filt_bw = 63;
break;
default:
- err("%s: invalid bandwidth setting!", __func__);
+ pr_err("%s: invalid bandwidth setting!", __func__);
return NULL;
}
@@ -304,12 +302,12 @@
bw = 8;
break;
default:
- err("%s: bandwidth not set!", __func__);
+ pr_err("%s: bandwidth not set!", __func__);
return -EINVAL;
}
break;
default:
- err("%s: modulation type not supported!", __func__);
+ pr_err("%s: modulation type not supported!", __func__);
return -EINVAL;
}
ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
index efdcb15..e97964e 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -52,12 +52,6 @@
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-#define deb_info pr_debug
-#define deb_reg pr_debug
-#define deb_adv pr_debug
-#define err pr_err
-#define info pr_info
-
int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
{
@@ -65,7 +59,7 @@
int ret;
u8 sndbuf[1+wlen];
- deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
+ pr_debug("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
memset(sndbuf, 0, 1+wlen);
@@ -98,12 +92,12 @@
if (buf[0] == addr)
*data = buf[1];
else {
- err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
+ pr_err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
addr, buf[0], buf[1]);
ret = -EINVAL;
}
- deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
+ pr_debug("R: (0x%02x, 0x%02x)\n", addr, *data);
fail:
return ret;
}
@@ -113,11 +107,11 @@
u8 buf[] = { addr, data };
int ret;
- deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
+ pr_debug("W: (0x%02x, 0x%02x)\n", addr, data);
ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
if (mxl_fail(ret))
- err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
+ pr_err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
return ret;
}
@@ -134,7 +128,7 @@
#if 1
/* dont know why this usually errors out on the first try */
if (mxl_fail(ret))
- err("error writing addr: 0x%02x, mask: 0x%02x, "
+ pr_err("error writing addr: 0x%02x, mask: 0x%02x, "
"data: 0x%02x, retrying...", addr, mask, data);
ret = mxl111sf_read_reg(state, addr, &val);
@@ -167,7 +161,7 @@
ctrl_reg_info[i].mask,
ctrl_reg_info[i].data);
if (mxl_fail(ret)) {
- err("failed on reg #%d (0x%02x)", i,
+ pr_err("failed on reg #%d (0x%02x)", i,
ctrl_reg_info[i].addr);
break;
}
@@ -225,7 +219,7 @@
mxl_rev = "UNKNOWN REVISION";
break;
}
- info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
+ pr_info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
fail:
return ret;
}
@@ -239,7 +233,7 @@
" on first probe attempt"); \
___ret = mxl1x1sf_get_chip_info(state); \
if (mxl_fail(___ret)) \
- err("failed to get chip info during probe"); \
+ pr_err("failed to get chip info during probe"); \
else \
mxl_debug("probe needed a retry " \
"in order to succeed."); \
@@ -270,14 +264,14 @@
goto fail;
}
- deb_info("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
mutex_lock(&state->fe_lock);
state->alt_mode = adap_state->alt_mode;
if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
+ pr_err("set interface failed");
err = mxl1x1sf_soft_reset(state);
mxl_fail(err);
@@ -326,7 +320,7 @@
goto fail;
}
- deb_info("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
@@ -344,7 +338,7 @@
struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
int ret = 0;
- deb_info("%s(%d)\n", __func__, onoff);
+ pr_debug("%s(%d)\n", __func__, onoff);
if (onoff) {
ret = mxl111sf_enable_usb_output(state);
@@ -368,7 +362,7 @@
struct mxl111sf_state *state = fe_to_priv(fe);
int ret = 0;
- deb_info("%s(%d)\n", __func__, onoff);
+ pr_debug("%s(%d)\n", __func__, onoff);
if (onoff) {
ret = mxl111sf_enable_usb_output(state);
@@ -394,7 +388,7 @@
struct mxl111sf_state *state = fe_to_priv(fe);
int ret = 0;
- deb_info("%s(%d)\n", __func__, onoff);
+ pr_debug("%s(%d)\n", __func__, onoff);
if (onoff) {
ret = mxl111sf_enable_usb_output(state);
@@ -424,7 +418,7 @@
struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
int ret;
- deb_adv("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
/* save a pointer to the dvb_usb_device in device state */
state->d = d;
@@ -432,7 +426,7 @@
state->alt_mode = adap_state->alt_mode;
if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
+ pr_err("set interface failed");
state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
adap_state->gpio_mode = state->gpio_mode;
@@ -495,7 +489,7 @@
struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
int ret;
- deb_adv("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
/* save a pointer to the dvb_usb_device in device state */
state->d = d;
@@ -503,7 +497,7 @@
state->alt_mode = adap_state->alt_mode;
if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
+ pr_err("set interface failed");
state->gpio_mode = MXL111SF_GPIO_MOD_MH;
adap_state->gpio_mode = state->gpio_mode;
@@ -580,7 +574,7 @@
struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
int ret;
- deb_adv("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
/* save a pointer to the dvb_usb_device in device state */
state->d = d;
@@ -588,7 +582,7 @@
state->alt_mode = adap_state->alt_mode;
if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
+ pr_err("set interface failed");
state->gpio_mode = MXL111SF_GPIO_MOD_MH;
adap_state->gpio_mode = state->gpio_mode;
@@ -667,7 +661,7 @@
struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
int ret;
- deb_adv("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
/* save a pointer to the dvb_usb_device in device state */
state->d = d;
@@ -675,7 +669,7 @@
state->alt_mode = adap_state->alt_mode;
if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
+ pr_err("set interface failed");
state->gpio_mode = MXL111SF_GPIO_MOD_MH;
adap_state->gpio_mode = state->gpio_mode;
@@ -742,7 +736,7 @@
struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
int ret;
- deb_adv("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
/* save a pointer to the dvb_usb_device in device state */
state->d = d;
@@ -750,7 +744,7 @@
state->alt_mode = adap_state->alt_mode;
if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
- err("set interface failed");
+ pr_err("set interface failed");
state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
adap_state->gpio_mode = state->gpio_mode;
@@ -802,7 +796,7 @@
}
#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
- err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
+ pr_err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
__func__, __LINE__, \
(ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
pwr0, pwr1, pwr2, pwr3)
@@ -868,7 +862,7 @@
struct mxl111sf_state *state = adap_to_priv(adap);
int i;
- deb_adv("%s()\n", __func__);
+ pr_debug("%s()\n", __func__);
for (i = 0; i < state->num_frontends; i++) {
if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
@@ -902,7 +896,7 @@
ret = get_chip_info(state);
if (mxl_fail(ret))
- err("failed to get chip info during probe");
+ pr_err("failed to get chip info during probe");
mutex_init(&state->fe_lock);
@@ -950,7 +944,7 @@
static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
{
int ret;
- deb_info("%s\n", __func__);
+ pr_debug("%s\n", __func__);
ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
if (ret < 0)
@@ -970,7 +964,7 @@
static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
{
int ret;
- deb_info("%s\n", __func__);
+ pr_debug("%s\n", __func__);
ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
if (ret < 0)
@@ -990,7 +984,7 @@
static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
{
int ret;
- deb_info("%s\n", __func__);
+ pr_debug("%s\n", __func__);
ret = mxl111sf_attach_demod(adap, 0);
if (ret < 0)
@@ -1006,7 +1000,7 @@
static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
{
- deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
+ pr_debug("%s: endpoint=%d size=8192\n", __func__, endpoint);
stream->type = USB_BULK;
stream->count = 5;
stream->endpoint = endpoint;
@@ -1016,7 +1010,7 @@
static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
u8 endpoint, int framesperurb, int framesize)
{
- deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
+ pr_debug("%s: endpoint=%d size=%d\n", __func__, endpoint,
framesperurb * framesize);
stream->type = USB_ISOC;
stream->count = 5;
@@ -1035,7 +1029,7 @@
static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
u8 *ts_type, struct usb_data_stream_properties *stream)
{
- deb_info("%s: fe=%d\n", __func__, fe->id);
+ pr_debug("%s: fe=%d\n", __func__, fe->id);
*ts_type = DVB_USB_FE_TS_TYPE_188;
if (dvb_usb_mxl111sf_isoc)
@@ -1076,7 +1070,7 @@
static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
u8 *ts_type, struct usb_data_stream_properties *stream)
{
- deb_info("%s: fe=%d\n", __func__, fe->id);
+ pr_debug("%s: fe=%d\n", __func__, fe->id);
*ts_type = DVB_USB_FE_TS_TYPE_188;
if (dvb_usb_mxl111sf_isoc)
@@ -1117,7 +1111,7 @@
static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
u8 *ts_type, struct usb_data_stream_properties *stream)
{
- deb_info("%s: fe=%d\n", __func__, fe->id);
+ pr_debug("%s: fe=%d\n", __func__, fe->id);
*ts_type = DVB_USB_FE_TS_TYPE_RAW;
if (dvb_usb_mxl111sf_isoc)
@@ -1158,7 +1152,7 @@
static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
u8 *ts_type, struct usb_data_stream_properties *stream)
{
- deb_info("%s: fe=%d\n", __func__, fe->id);
+ pr_debug("%s: fe=%d\n", __func__, fe->id);
if (fe->id == 0) {
*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1184,7 +1178,7 @@
static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
{
- deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+ pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
if (fe->id == 0)
return mxl111sf_ep6_streaming_ctrl(fe, onoff);
@@ -1228,7 +1222,7 @@
static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
u8 *ts_type, struct usb_data_stream_properties *stream)
{
- deb_info("%s: fe=%d\n", __func__, fe->id);
+ pr_debug("%s: fe=%d\n", __func__, fe->id);
if (fe->id == 0) {
*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1260,7 +1254,7 @@
static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
{
- deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+ pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
if (fe->id == 0)
return mxl111sf_ep6_streaming_ctrl(fe, onoff);
@@ -1306,7 +1300,7 @@
static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
u8 *ts_type, struct usb_data_stream_properties *stream)
{
- deb_info("%s: fe=%d\n", __func__, fe->id);
+ pr_debug("%s: fe=%d\n", __func__, fe->id);
if (fe->id == 0) {
*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1332,7 +1326,7 @@
static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
{
- deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+ pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
if (fe->id == 0)
return mxl111sf_ep4_streaming_ctrl(fe, onoff);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 2cc8ec7..c0cd084 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1041,67 +1041,34 @@
static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
{
int ret;
- u8 val;
dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
if (onoff) {
- /* set output values */
- ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
+ /* GPIO3=1, GPIO4=0 */
+ ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x08, 0x18);
if (ret)
goto err;
- val |= 0x08;
- val &= 0xef;
-
- ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
+ /* suspend? */
+ ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL1, 0x00, 0x10);
if (ret)
goto err;
- /* demod_ctl_1 */
- ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
+ /* enable PLL */
+ ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x80, 0x80);
if (ret)
goto err;
- val &= 0xef;
-
- ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
- if (ret)
- goto err;
-
- /* demod control */
- /* PLL enable */
- ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
- if (ret)
- goto err;
-
- /* bit 7 to 1 */
- val |= 0x80;
-
- ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
- if (ret)
- goto err;
-
- ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
- if (ret)
- goto err;
-
- val |= 0x20;
-
- ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+ /* disable reset */
+ ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x20, 0x20);
if (ret)
goto err;
mdelay(5);
- /*enable ADC_Q and ADC_I */
- ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
- if (ret)
- goto err;
-
- val |= 0x48;
-
- ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+ /* enable ADC */
+ ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x48, 0x48);
if (ret)
goto err;
@@ -1114,36 +1081,18 @@
if (ret)
goto err;
} else {
- /* demod_ctl_1 */
- ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
+ /* GPIO4=1 */
+ ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x10, 0x10);
if (ret)
goto err;
- val |= 0x0c;
-
- ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
+ /* disable ADC */
+ ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x48);
if (ret)
goto err;
- /* set output values */
- ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
- if (ret)
- goto err;
-
- val |= 0x10;
-
- ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
- if (ret)
- goto err;
-
- /* demod control */
- ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
- if (ret)
- goto err;
-
- val &= 0x37;
-
- ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+ /* disable PLL */
+ ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x80);
if (ret)
goto err;
@@ -1242,42 +1191,47 @@
return 0;
}
-#else
- #define rtl2831u_get_rc_config NULL
-#endif
-#if IS_ENABLED(CONFIG_RC_CORE)
static int rtl2832u_rc_query(struct dvb_usb_device *d)
{
- int ret, i;
+ int ret, i, len;
struct rtl28xxu_priv *priv = d->priv;
+ struct ir_raw_event ev;
u8 buf[128];
- int len;
- struct rtl28xxu_reg_val rc_nec_tab[] = {
- { IR_RX_CTRL, 0x20 },
- { IR_RX_BUF_CTRL, 0x80 },
- { IR_RX_IF, 0xff },
- { IR_RX_IE, 0xff },
- { IR_MAX_DURATION0, 0xd0 },
- { IR_MAX_DURATION1, 0x07 },
- { IR_IDLE_LEN0, 0xc0 },
- { IR_IDLE_LEN1, 0x00 },
- { IR_GLITCH_LEN, 0x03 },
- { IR_RX_CLK, 0x09 },
- { IR_RX_CFG, 0x1c },
- { IR_MAX_H_TOL_LEN, 0x1e },
- { IR_MAX_L_TOL_LEN, 0x1e },
- { IR_RX_CTRL, 0x80 },
+ static const struct rtl28xxu_reg_val_mask refresh_tab[] = {
+ {IR_RX_IF, 0x03, 0xff},
+ {IR_RX_BUF_CTRL, 0x80, 0xff},
+ {IR_RX_CTRL, 0x80, 0xff},
};
/* init remote controller */
if (!priv->rc_active) {
- for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
- ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
- rc_nec_tab[i].val);
+ static const struct rtl28xxu_reg_val_mask init_tab[] = {
+ {SYS_DEMOD_CTL1, 0x00, 0x04},
+ {SYS_DEMOD_CTL1, 0x00, 0x08},
+ {USB_CTRL, 0x20, 0x20},
+ {SYS_GPIO_DIR, 0x00, 0x08},
+ {SYS_GPIO_OUT_EN, 0x08, 0x08},
+ {SYS_GPIO_OUT_VAL, 0x08, 0x08},
+ {IR_MAX_DURATION0, 0xd0, 0xff},
+ {IR_MAX_DURATION1, 0x07, 0xff},
+ {IR_IDLE_LEN0, 0xc0, 0xff},
+ {IR_IDLE_LEN1, 0x00, 0xff},
+ {IR_GLITCH_LEN, 0x03, 0xff},
+ {IR_RX_CLK, 0x09, 0xff},
+ {IR_RX_CFG, 0x1c, 0xff},
+ {IR_MAX_H_TOL_LEN, 0x1e, 0xff},
+ {IR_MAX_L_TOL_LEN, 0x1e, 0xff},
+ {IR_RX_CTRL, 0x80, 0xff},
+ };
+
+ for (i = 0; i < ARRAY_SIZE(init_tab); i++) {
+ ret = rtl28xx_wr_reg_mask(d, init_tab[i].reg,
+ init_tab[i].val, init_tab[i].mask);
if (ret)
goto err;
}
+
priv->rc_active = true;
}
@@ -1293,14 +1247,32 @@
goto err;
len = buf[0];
+
+ /* read raw code from hw */
ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
+ if (ret)
+ goto err;
- /* TODO: pass raw IR to Kernel IR decoder */
+ /* let hw receive new code */
+ for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) {
+ ret = rtl28xx_wr_reg_mask(d, refresh_tab[i].reg,
+ refresh_tab[i].val, refresh_tab[i].mask);
+ if (ret)
+ goto err;
+ }
- ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03);
- ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
- ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80);
+ /* pass data to Kernel IR decoder */
+ init_ir_raw_event(&ev);
+ for (i = 0; i < len; i++) {
+ ev.pulse = buf[i] >> 7;
+ ev.duration = 50800 * (buf[i] & 0x7f);
+ ir_raw_event_store_with_filter(d->rc_dev, &ev);
+ }
+
+ /* 'flush' ir_raw_event_store_with_filter() */
+ ir_raw_event_set_idle(d->rc_dev, true);
+ ir_raw_event_handle(d->rc_dev);
exit:
return ret;
err:
@@ -1311,15 +1283,19 @@
static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
struct dvb_usb_rc *rc)
{
- rc->map_name = RC_MAP_EMPTY;
- rc->allowed_protos = RC_BIT_NEC;
+ /* load empty to enable rc */
+ if (!rc->map_name)
+ rc->map_name = RC_MAP_EMPTY;
+ rc->allowed_protos = RC_BIT_ALL;
+ rc->driver_type = RC_DRIVER_IR_RAW;
rc->query = rtl2832u_rc_query;
rc->interval = 400;
return 0;
}
#else
- #define rtl2832u_get_rc_config NULL
+#define rtl2831u_get_rc_config NULL
+#define rtl2832u_get_rc_config NULL
#endif
static const struct dvb_usb_device_properties rtl2831u_props = {
@@ -1379,7 +1355,7 @@
{ DVB_USB_DEVICE(USB_VID_REALTEK, 0x2838,
&rtl2832u_props, "Realtek RTL2832U reference design", NULL) },
{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1,
- &rtl2832u_props, "TerraTec Cinergy T Stick Black", NULL) },
+ &rtl2832u_props, "TerraTec Cinergy T Stick Black", RC_MAP_TERRATEC_SLIM) },
{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT,
&rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) },
{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK,
@@ -1403,11 +1379,15 @@
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd393,
&rtl2832u_props, "GIGABYTE U7300", NULL) },
{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1104,
- &rtl2832u_props, "Digivox Micro Hd", NULL) },
+ &rtl2832u_props, "MSI DIGIVOX Micro HD", NULL) },
{ DVB_USB_DEVICE(USB_VID_COMPRO, 0x0620,
&rtl2832u_props, "Compro VideoMate U620F", NULL) },
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394,
&rtl2832u_props, "MaxMedia HU394-T", NULL) },
+ { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a03,
+ &rtl2832u_props, "Leadtek WinFast DTV Dongle mini", NULL) },
+ { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A,
+ &rtl2832u_props, "Crypto ReDi PC 50 A", NULL) },
{ }
};
MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index 533a331..729b354 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -97,6 +97,12 @@
u8 val;
};
+struct rtl28xxu_reg_val_mask {
+ u16 reg;
+ u8 val;
+ u8 mask;
+};
+
/*
* memory map
*
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index 91e0119..ea2d5ee 100644
--- a/drivers/media/usb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -264,7 +264,7 @@
.demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */
.xtal_freq = 27000000,
- .inversion = IQ_SWAP_ON, /* 1 */
+ .inversion = IQ_SWAP_ON,
.lo_clk = 76500000,
.hi_clk = 99000000,
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index d1ddfa1..449a996 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -828,7 +828,7 @@
.block_sync_mode = STB0899_SYNC_FORCED, /* ? */
.xtal_freq = 27000000, /* Assume Hz ? */
- .inversion = IQ_SWAP_ON, /* ? */
+ .inversion = IQ_SWAP_ON,
.lo_clk = 76500000,
.hi_clk = 99000000,
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 83bfbe4..dc65742 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -37,7 +37,6 @@
#include <media/i2c-addr.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
#include "em28xx.h"
@@ -83,26 +82,26 @@
/* Reset for the most [analog] boards */
static struct em28xx_reg_seq default_analog[] = {
- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};
/* Reset for the most [digital] boards */
static struct em28xx_reg_seq default_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};
/* Board Hauppauge WinTV HVR 900 analog */
static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
- {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x2d, ~EM_GPIO_4, 10},
{0x05, 0xff, 0x10, 10},
{ -1, -1, -1, -1},
};
/* Board Hauppauge WinTV HVR 900 digital */
static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
- {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x04, 0x0f, 10},
{EM2880_R04_GPO, 0x0c, 0x0f, 10},
{ -1, -1, -1, -1},
@@ -110,14 +109,14 @@
/* Board Hauppauge WinTV HVR 900 (R2) digital */
static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
- {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x0c, 0x0f, 10},
{ -1, -1, -1, -1},
};
/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
- {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x69, ~EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};
@@ -128,11 +127,11 @@
/* Board - EM2882 Kworld 315U digital */
static struct em28xx_reg_seq em2882_kworld_315u_digital[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10},
{EM2880_R04_GPO, 0x04, 0xff, 10},
{EM2880_R04_GPO, 0x0c, 0xff, 10},
- {EM28XX_R08_GPIO, 0x7e, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0x7e, 0xff, 10},
{ -1, -1, -1, -1},
};
@@ -145,13 +144,13 @@
};
static struct em28xx_reg_seq kworld_330u_analog[] = {
- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x00, 0xff, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq kworld_330u_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x08, 0xff, 10},
{ -1, -1, -1, -1},
};
@@ -163,12 +162,12 @@
GOP3 - s5h1409 reset
*/
static struct em28xx_reg_seq evga_indtube_analog[] = {
- {EM28XX_R08_GPIO, 0x79, 0xff, 60},
+ {EM2820_R08_GPIO_CTRL, 0x79, 0xff, 60},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq evga_indtube_digital[] = {
- {EM28XX_R08_GPIO, 0x7a, 0xff, 1},
+ {EM2820_R08_GPIO_CTRL, 0x7a, 0xff, 1},
{EM2880_R04_GPO, 0x04, 0xff, 10},
{EM2880_R04_GPO, 0x0c, 0xff, 1},
{ -1, -1, -1, -1},
@@ -186,31 +185,31 @@
* EM_GPIO_7 - currently unknown
*/
static struct em28xx_reg_seq kworld_a340_digital[] = {
- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};
/* Pinnacle Hybrid Pro eb1a:2881 */
static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
- {EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0xfd, ~EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */
{EM2880_R04_GPO, 0x0c, 0xff, 1},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = {
- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x00, 0xff, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x08, 0xff, 10},
{ -1, -1, -1, -1},
};
@@ -219,66 +218,66 @@
GPIO4 - CU1216L NIM
Other GPIOs seems to be don't care. */
static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
- {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
- {EM28XX_R08_GPIO, 0xde, 0xff, 10},
- {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM28XX_R08_GPIO, 0x7f, 0xff, 10},
- {EM28XX_R08_GPIO, 0x6f, 0xff, 10},
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0xde, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0x7f, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6f, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
{-1, -1, -1, -1},
};
/* Callback for the most boards */
static struct em28xx_reg_seq default_tuner_gpio[] = {
- {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
- {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
- {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0, EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10},
{ -1, -1, -1, -1},
};
/* Mute/unmute */
static struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
- {EM28XX_R08_GPIO, 5, 7, 10},
+ {EM2820_R08_GPIO_CTRL, 5, 7, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
- {EM28XX_R08_GPIO, 4, 7, 10},
+ {EM2820_R08_GPIO_CTRL, 4, 7, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq compro_mute_gpio[] = {
- {EM28XX_R08_GPIO, 6, 7, 10},
+ {EM2820_R08_GPIO_CTRL, 6, 7, 10},
{ -1, -1, -1, -1},
};
/* Terratec AV350 */
static struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
- {EM28XX_R08_GPIO, 0xff, 0x7f, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0x7f, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq silvercrest_reg_seq[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM28XX_R08_GPIO, 0x01, 0xf7, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
+ {EM2820_R08_GPIO_CTRL, 0x01, 0xf7, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq vc211a_enable[] = {
- {EM28XX_R08_GPIO, 0xff, 0x07, 10},
- {EM28XX_R08_GPIO, 0xff, 0x0f, 10},
- {EM28XX_R08_GPIO, 0xff, 0x0b, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0x07, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0x0f, 10},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0x0b, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq dikom_dk300_digital[] = {
- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x08, 0xff, 10},
{ -1, -1, -1, -1},
};
@@ -286,14 +285,14 @@
/* Reset for the most [digital] boards */
static struct em28xx_reg_seq leadership_digital[] = {
- {EM2874_R80_GPIO, 0x70, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0x70, 0xff, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq leadership_reset[] = {
- {EM2874_R80_GPIO, 0xf0, 0xff, 10},
- {EM2874_R80_GPIO, 0xb0, 0xff, 10},
- {EM2874_R80_GPIO, 0xf0, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xb0, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10},
{ -1, -1, -1, -1},
};
@@ -302,25 +301,25 @@
* GPIO_7 - LED
*/
static struct em28xx_reg_seq pctv_290e[] = {
- {EM2874_R80_GPIO, 0x00, 0xff, 80},
- {EM2874_R80_GPIO, 0x40, 0xff, 80}, /* GPIO_6 = 1 */
- {EM2874_R80_GPIO, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 80},
+ {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 80}, /* GPIO_6 = 1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */
{-1, -1, -1, -1},
};
#if 0
static struct em28xx_reg_seq terratec_h5_gpio[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
- {EM2874_R80_GPIO, 0xf2, 0xff, 50},
- {EM2874_R80_GPIO, 0xf6, 0xff, 50},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 50},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq terratec_h5_digital[] = {
- {EM2874_R80_GPIO, 0xf6, 0xff, 10},
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
- {EM2874_R80_GPIO, 0xa6, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10},
{ -1, -1, -1, -1},
};
#endif
@@ -336,51 +335,52 @@
* GPIO_7 - LED (green LED)
*/
static struct em28xx_reg_seq pctv_460e[] = {
- {EM2874_R80_GPIO, 0x01, 0xff, 50},
+ {EM2874_R80_GPIO_P0_CTRL, 0x01, 0xff, 50},
{0x0d, 0xff, 0xff, 50},
- {EM2874_R80_GPIO, 0x41, 0xff, 50}, /* GPIO_6=1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x41, 0xff, 50}, /* GPIO_6=1 */
{0x0d, 0x42, 0xff, 50},
- {EM2874_R80_GPIO, 0x61, 0xff, 50}, /* GPIO_5=1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x61, 0xff, 50}, /* GPIO_5=1 */
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq c3tech_digital_duo_digital[] = {
- {EM2874_R80_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xfd, 0xff, 10}, /* xc5000 reset */
- {EM2874_R80_GPIO, 0xf9, 0xff, 35},
- {EM2874_R80_GPIO, 0xfd, 0xff, 10},
- {EM2874_R80_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xfe, 0xff, 10},
- {EM2874_R80_GPIO, 0xbe, 0xff, 10},
- {EM2874_R80_GPIO, 0xfe, 0xff, 20},
+ {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 10}, /* xc5000 reset */
+ {EM2874_R80_GPIO_P0_CTRL, 0xf9, 0xff, 35},
+ {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xbe, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 20},
{ -1, -1, -1, -1},
};
#if 0
static struct em28xx_reg_seq hauppauge_930c_gpio[] = {
- {EM2874_R80_GPIO, 0x6f, 0xff, 10},
- {EM2874_R80_GPIO, 0x4f, 0xff, 10}, /* xc5000 reset */
- {EM2874_R80_GPIO, 0x6f, 0xff, 10},
- {EM2874_R80_GPIO, 0x4f, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10}, /* xc5000 reset */
+ {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10},
{ -1, -1, -1, -1},
};
static struct em28xx_reg_seq hauppauge_930c_digital[] = {
- {EM2874_R80_GPIO, 0xf6, 0xff, 10},
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
- {EM2874_R80_GPIO, 0xa6, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10},
{ -1, -1, -1, -1},
};
#endif
/* 1b80:e425 MaxMedia UB425-TC
+ * 1b80:e1cc Delock 61959
* GPIO_6 - demod reset, 0=active
* GPIO_7 - LED, 0=active
*/
static struct em28xx_reg_seq maxmedia_ub425_tc[] = {
- {EM2874_R80_GPIO, 0x83, 0xff, 100},
- {EM2874_R80_GPIO, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */
- {EM2874_R80_GPIO, 0x43, 0xff, 000}, /* GPIO_7 = 0 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x83, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x43, 0xff, 000}, /* GPIO_7 = 0 */
{-1, -1, -1, -1},
};
@@ -391,9 +391,9 @@
* GPIO_7: LED, 1=active
*/
static struct em28xx_reg_seq pctv_510e[] = {
- {EM2874_R80_GPIO, 0x10, 0xff, 100},
- {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
- {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
{ -1, -1, -1, -1},
};
@@ -404,10 +404,10 @@
* GPIO_7: LED, 1=active
*/
static struct em28xx_reg_seq pctv_520e[] = {
- {EM2874_R80_GPIO, 0x10, 0xff, 100},
- {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
- {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
- {EM2874_R80_GPIO, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
+ {EM2874_R80_GPIO_P0_CTRL, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */
{ -1, -1, -1, -1},
};
@@ -2017,6 +2017,19 @@
.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
EM28XX_I2C_FREQ_400_KHZ,
},
+ /* 1b80:e1cc Delock 61959
+ * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
+ * mostly the same as MaxMedia UB-425-TC but different remote */
+ [EM2874_BOARD_DELOCK_61959] = {
+ .name = "Delock 61959",
+ .tuner_type = TUNER_ABSENT,
+ .tuner_gpio = maxmedia_ub425_tc,
+ .has_dvb = 1,
+ .ir_codes = RC_MAP_DELOCK_61959,
+ .def_i2c_bus = 1,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
+ EM28XX_I2C_FREQ_400_KHZ,
+ },
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
@@ -2178,6 +2191,8 @@
.driver_info = EM2884_BOARD_PCTV_510E },
{ USB_DEVICE(0x2013, 0x0251),
.driver_info = EM2884_BOARD_PCTV_520E },
+ { USB_DEVICE(0x1b80, 0xe1cc),
+ .driver_info = EM2874_BOARD_DELOCK_61959 },
{ },
};
MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2284,9 +2299,9 @@
break;
case EM2861_BOARD_KWORLD_PVRTV_300U:
case EM2880_BOARD_KWORLD_DVB_305U:
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x6d);
msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x7d);
msleep(10);
break;
case EM2870_BOARD_COMPRO_VIDEOMATE:
@@ -2296,45 +2311,45 @@
msleep(10);
em28xx_write_reg(dev, EM2880_R04_GPO, 0x01);
msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xdc);
mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
mdelay(70);
break;
case EM2870_BOARD_TERRATEC_XS_MT2060:
/* this device needs some gpio writes to get the DVB-T
demod work */
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
mdelay(70);
break;
case EM2870_BOARD_PINNACLE_PCTV_DVB:
/* this device needs some gpio writes to get the
DVB-T demod work */
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
mdelay(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
mdelay(70);
break;
case EM2820_BOARD_GADMEI_UTV310:
case EM2820_BOARD_MSI_VOX_USB_2:
/* enables audio for that devices */
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
break;
case EM2882_BOARD_KWORLD_ATSC_315U:
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
msleep(10);
em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
msleep(10);
@@ -2360,13 +2375,13 @@
break;
case EM2820_BOARD_IODATA_GVMVP_SZ:
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
msleep(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
msleep(70);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
msleep(70);
break;
}
@@ -2653,7 +2668,7 @@
dev->tuner_type = tv.tuner_type;
- if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
+ if (tv.audio_processor == TVEEPROM_AUDPROC_MSP) {
dev->i2s_speed = 2048000;
dev->board.has_msp34xx = 1;
}
@@ -2662,12 +2677,12 @@
case EM2882_BOARD_KWORLD_ATSC_315U:
em28xx_write_reg(dev, 0x0d, 0x42);
msleep(10);
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
msleep(10);
break;
case EM2820_BOARD_KWORLD_PVRTV2800RF:
/* GPIO enables sound on KWORLD PVR TV 2800RF */
- em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9);
+ em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf9);
break;
case EM2820_BOARD_UNKNOWN:
case EM2800_BOARD_UNKNOWN:
@@ -2881,10 +2896,6 @@
em28xx_set_model(dev);
- /* Set the default GPO/GPIO for legacy devices */
- dev->reg_gpo_num = EM2880_R04_GPO;
- dev->reg_gpio_num = EM28XX_R08_GPIO;
-
dev->wait_after_write = 5;
/* Based on the Chip ID, set the device configuration */
@@ -2932,13 +2943,11 @@
break;
case CHIP_ID_EM2874:
chip_name = "em2874";
- dev->reg_gpio_num = EM2874_R80_GPIO;
dev->wait_after_write = 0;
dev->eeprom_addrwidth_16bit = 1;
break;
case CHIP_ID_EM28174:
chip_name = "em28174";
- dev->reg_gpio_num = EM2874_R80_GPIO;
dev->wait_after_write = 0;
dev->eeprom_addrwidth_16bit = 1;
break;
@@ -2948,7 +2957,6 @@
break;
case CHIP_ID_EM2884:
chip_name = "em2884";
- dev->reg_gpio_num = EM2874_R80_GPIO;
dev->wait_after_write = 0;
dev->eeprom_addrwidth_16bit = 1;
break;
@@ -2977,11 +2985,6 @@
return 0;
}
- /* Prepopulate cached GPO register content */
- retval = em28xx_read_reg(dev, dev->reg_gpo_num);
- if (retval >= 0)
- dev->reg_gpo = retval;
-
em28xx_pre_card_setup(dev);
if (!dev->board.is_em2800) {
@@ -3071,7 +3074,7 @@
if (dev->board.has_msp34xx) {
/* Send a reset to other chips via gpio */
- retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+ retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
if (retval < 0) {
em28xx_errdev("%s: em28xx_write_reg - "
"msp34xx(1) failed! error [%d]\n",
@@ -3080,7 +3083,7 @@
}
msleep(3);
- retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+ retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
if (retval < 0) {
em28xx_errdev("%s: em28xx_write_reg - "
"msp34xx(2) failed! error [%d]\n",
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index a802128..fc157af 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -193,23 +193,7 @@
int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
{
- int rc;
-
- rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
-
- /* Stores GPO/GPIO values at the cache, if changed
- Only write values should be stored, since input on a GPIO
- register will return the input bits.
- Not sure what happens on reading GPO register.
- */
- if (rc >= 0) {
- if (reg == dev->reg_gpo_num)
- dev->reg_gpo = buf[0];
- else if (reg == dev->reg_gpio_num)
- dev->reg_gpio = buf[0];
- }
-
- return rc;
+ return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
}
EXPORT_SYMBOL_GPL(em28xx_write_regs);
@@ -231,14 +215,7 @@
int oldval;
u8 newval;
- /* Uses cache for gpo/gpio registers */
- if (reg == dev->reg_gpo_num)
- oldval = dev->reg_gpo;
- else if (reg == dev->reg_gpio_num)
- oldval = dev->reg_gpio;
- else
- oldval = em28xx_read_reg(dev, reg);
-
+ oldval = em28xx_read_reg(dev, reg);
if (oldval < 0)
return oldval;
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index b22f8fe..bb1e8dc 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -421,23 +421,23 @@
int i;
struct em28xx_reg_seq hauppauge_hvr930c_init[] = {
- {EM2874_R80_GPIO, 0xff, 0xff, 0x65},
- {EM2874_R80_GPIO, 0xfb, 0xff, 0x32},
- {EM2874_R80_GPIO, 0xff, 0xff, 0xb8},
+ {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0x65},
+ {EM2874_R80_GPIO_P0_CTRL, 0xfb, 0xff, 0x32},
+ {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0xb8},
{ -1, -1, -1, -1},
};
struct em28xx_reg_seq hauppauge_hvr930c_end[] = {
- {EM2874_R80_GPIO, 0xef, 0xff, 0x01},
- {EM2874_R80_GPIO, 0xaf, 0xff, 0x65},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x76},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x01},
- {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x40},
+ {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x01},
+ {EM2874_R80_GPIO_P0_CTRL, 0xaf, 0xff, 0x65},
+ {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x76},
+ {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x01},
+ {EM2874_R80_GPIO_P0_CTRL, 0xcf, 0xff, 0x0b},
+ {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x40},
- {EM2874_R80_GPIO, 0xcf, 0xff, 0x65},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x65},
- {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b},
- {EM2874_R80_GPIO, 0xef, 0xff, 0x65},
+ {EM2874_R80_GPIO_P0_CTRL, 0xcf, 0xff, 0x65},
+ {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x65},
+ {EM2874_R80_GPIO_P0_CTRL, 0xcf, 0xff, 0x0b},
+ {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x65},
{ -1, -1, -1, -1},
};
@@ -487,16 +487,16 @@
{
int i;
struct em28xx_reg_seq terratec_h5_init[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
- {EM2874_R80_GPIO, 0xf2, 0xff, 50},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100},
{ -1, -1, -1, -1},
};
struct em28xx_reg_seq terratec_h5_end[] = {
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
- {EM2874_R80_GPIO, 0xa6, 0xff, 50},
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 50},
+ {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100},
{ -1, -1, -1, -1},
};
struct {
@@ -543,15 +543,15 @@
* 0xb6: unknown (does not affect DVB-T).
*/
struct em28xx_reg_seq terratec_htc_stick_init[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
- {EM2874_R80_GPIO, 0xe6, 0xff, 50},
- {EM2874_R80_GPIO, 0xf6, 0xff, 100},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 50},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100},
{ -1, -1, -1, -1},
};
struct em28xx_reg_seq terratec_htc_stick_end[] = {
- {EM2874_R80_GPIO, 0xb6, 0xff, 100},
- {EM2874_R80_GPIO, 0xf6, 0xff, 50},
+ {EM2874_R80_GPIO_P0_CTRL, 0xb6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 50},
{ -1, -1, -1, -1},
};
@@ -590,16 +590,16 @@
int i;
struct em28xx_reg_seq terratec_htc_usb_xs_init[] = {
- {EM28XX_R08_GPIO, 0xff, 0xff, 10},
- {EM2874_R80_GPIO, 0xb2, 0xff, 100},
- {EM2874_R80_GPIO, 0xb2, 0xff, 50},
- {EM2874_R80_GPIO, 0xb6, 0xff, 100},
+ {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10},
+ {EM2874_R80_GPIO_P0_CTRL, 0xb2, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xb2, 0xff, 50},
+ {EM2874_R80_GPIO_P0_CTRL, 0xb6, 0xff, 100},
{ -1, -1, -1, -1},
};
struct em28xx_reg_seq terratec_htc_usb_xs_end[] = {
- {EM2874_R80_GPIO, 0xa6, 0xff, 100},
- {EM2874_R80_GPIO, 0xa6, 0xff, 50},
- {EM2874_R80_GPIO, 0xe6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 100},
+ {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 50},
+ {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100},
{ -1, -1, -1, -1},
};
@@ -1216,6 +1216,7 @@
dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus],
&em28xx_a8293_config);
break;
+ case EM2874_BOARD_DELOCK_61959:
case EM2874_BOARD_MAXMEDIA_UB425_TC:
/* attach demodulator */
dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk,
@@ -1235,8 +1236,8 @@
}
/* TODO: we need drx-3913k firmware in order to support DVB-T */
- em28xx_info("MaxMedia UB425-TC: only DVB-C supported by that " \
- "driver version\n");
+ em28xx_info("MaxMedia UB425-TC/Delock 61959: only DVB-C " \
+ "supported by that driver version\n");
break;
case EM2884_BOARD_PCTV_510E:
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 466b19d..ea181e4 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -32,7 +32,6 @@
#define EM28XX_SNAPSHOT_KEY KEY_CAMERA
#define EM28XX_SBUTTON_QUERY_INTERVAL 500
-#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20
static unsigned int ir_debug;
module_param(ir_debug, int, 0644);
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 622871d..0e04778 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -49,8 +49,9 @@
/* GPIO/GPO registers */
-#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */
-#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */
+#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */
+#define EM2820_R08_GPIO_CTRL 0x08 /* em2820-em2873/83 only */
+#define EM2820_R09_GPIO_STATE 0x09 /* em2820-em2873/83 only */
#define EM28XX_R06_I2C_CLK 0x06
@@ -67,7 +68,8 @@
#define EM28XX_R0A_CHIPID 0x0a
-#define EM28XX_R0C_USBSUSP 0x0c /* */
+#define EM28XX_R0C_USBSUSP 0x0c
+#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20 /* 1=button pressed, needs reset */
#define EM28XX_R0E_AUDIOSRC 0x0e
#define EM28XX_R0F_XCLK 0x0f
@@ -193,7 +195,20 @@
#define EM2874_R50_IR_CONFIG 0x50
#define EM2874_R51_IR 0x51
#define EM2874_R5F_TS_ENABLE 0x5f
-#define EM2874_R80_GPIO 0x80
+
+/* em2874/174/84, em25xx, em276x/7x/8x GPIO registers */
+/*
+ * NOTE: not all ports are bonded out;
+ * Some ports are multiplexed with special function I/O
+ */
+#define EM2874_R80_GPIO_P0_CTRL 0x80
+#define EM2874_R81_GPIO_P1_CTRL 0x81
+#define EM2874_R82_GPIO_P2_CTRL 0x82
+#define EM2874_R83_GPIO_P3_CTRL 0x83
+#define EM2874_R84_GPIO_P0_STATE 0x84
+#define EM2874_R85_GPIO_P1_STATE 0x85
+#define EM2874_R86_GPIO_P2_STATE 0x86
+#define EM2874_R87_GPIO_P3_STATE 0x87
/* em2874 IR config register (0x50) */
#define EM2874_IR_NEC 0x00
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 32d60e5..1a577ed 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -41,7 +41,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
#include <media/msp3400.h>
#include <media/tuner.h>
@@ -1309,28 +1308,6 @@
return 0;
}
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_BRIDGE) {
- if (chip->match.addr > 1)
- return -EINVAL;
- return 0;
- }
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
-
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
-
- return 0;
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int vidioc_g_chip_info(struct file *file, void *priv,
struct v4l2_dbg_chip_info *chip)
@@ -1366,14 +1343,9 @@
struct em28xx *dev = fh->dev;
int ret;
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_BRIDGE:
- if (reg->match.addr > 1)
- return -EINVAL;
- if (!reg->match.addr)
- break;
- /* fall-through */
- case V4L2_CHIP_MATCH_AC97:
+ if (reg->match.addr > 1)
+ return -EINVAL;
+ if (reg->match.addr) {
ret = em28xx_read_ac97(dev, reg->reg);
if (ret < 0)
return ret;
@@ -1381,15 +1353,6 @@
reg->val = ret;
reg->size = 1;
return 0;
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /* TODO: is this correct? */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
- return 0;
- default:
- return -EINVAL;
}
/* Match host */
@@ -1421,25 +1384,10 @@
struct em28xx *dev = fh->dev;
__le16 buf;
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_BRIDGE:
- if (reg->match.addr > 1)
- return -EINVAL;
- if (!reg->match.addr)
- break;
- /* fall-through */
- case V4L2_CHIP_MATCH_AC97:
- return em28xx_write_ac97(dev, reg->reg, reg->val);
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /* TODO: is this correct? */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
- return 0;
- default:
+ if (reg->match.addr > 1)
return -EINVAL;
- }
+ if (reg->match.addr)
+ return em28xx_write_ac97(dev, reg->reg, reg->val);
/* Match host */
buf = cpu_to_le16(reg->val);
@@ -1795,7 +1743,6 @@
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_chip_info = vidioc_g_chip_info,
.vidioc_g_register = vidioc_g_register,
@@ -1826,7 +1773,6 @@
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_chip_info = vidioc_g_chip_info,
.vidioc_g_register = vidioc_g_register,
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index a9323b6..205e903 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -130,6 +130,7 @@
#define EM2884_BOARD_PCTV_520E 86
#define EM2884_BOARD_TERRATEC_HTC_USB_XS 87
#define EM2884_BOARD_C3TECH_DIGITAL_DUO 88
+#define EM2874_BOARD_DELOCK_61959 89
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -636,12 +637,6 @@
enum em28xx_mode mode;
- /* register numbers for GPO/GPIO registers */
- u16 reg_gpo_num, reg_gpio_num;
-
- /* Caches GPO and GPIO registers */
- unsigned char reg_gpo, reg_gpio;
-
/* Snapshot button */
char snapshot_button_path[30]; /* path of the input dev */
struct input_dev *sbutton_input_dev;
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index 5995ec4..b7ae872 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -1029,8 +1029,19 @@
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_chip_info(struct file *file, void *priv,
+ struct v4l2_dbg_chip_info *chip)
+{
+ struct gspca_dev *gspca_dev = video_drvdata(file);
+
+ gspca_dev->usb_err = 0;
+ if (gspca_dev->sd_desc->get_chip_info)
+ return gspca_dev->sd_desc->get_chip_info(gspca_dev, chip);
+ return chip->match.addr ? -EINVAL : 0;
+}
+
static int vidioc_g_register(struct file *file, void *priv,
- struct v4l2_dbg_register *reg)
+ struct v4l2_dbg_register *reg)
{
struct gspca_dev *gspca_dev = video_drvdata(file);
@@ -1039,7 +1050,7 @@
}
static int vidioc_s_register(struct file *file, void *priv,
- const struct v4l2_dbg_register *reg)
+ const struct v4l2_dbg_register *reg)
{
struct gspca_dev *gspca_dev = video_drvdata(file);
@@ -1048,15 +1059,6 @@
}
#endif
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- gspca_dev->usb_err = 0;
- return gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
-}
-
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *fmtdesc)
{
@@ -1974,10 +1976,10 @@
.vidioc_enum_framesizes = vidioc_enum_framesizes,
.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_chip_info = vidioc_g_chip_info,
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
#endif
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
@@ -2086,14 +2088,10 @@
v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF);
v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF);
v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF);
- if (!gspca_dev->sd_desc->get_chip_ident)
- v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_CHIP_IDENT);
#ifdef CONFIG_VIDEO_ADV_DEBUG
- if (!gspca_dev->sd_desc->get_chip_ident ||
- !gspca_dev->sd_desc->get_register)
+ if (!gspca_dev->sd_desc->get_register)
v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_REGISTER);
- if (!gspca_dev->sd_desc->get_chip_ident ||
- !gspca_dev->sd_desc->set_register)
+ if (!gspca_dev->sd_desc->set_register)
v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_S_REGISTER);
#endif
if (!gspca_dev->sd_desc->get_jcomp)
diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
index ef8efeb..ac0b11f 100644
--- a/drivers/media/usb/gspca/gspca.h
+++ b/drivers/media/usb/gspca/gspca.h
@@ -78,8 +78,8 @@
struct v4l2_dbg_register *);
typedef int (*cam_set_reg_op) (struct gspca_dev *,
const struct v4l2_dbg_register *);
-typedef int (*cam_ident_op) (struct gspca_dev *,
- struct v4l2_dbg_chip_ident *);
+typedef int (*cam_chip_info_op) (struct gspca_dev *,
+ struct v4l2_dbg_chip_info *);
typedef void (*cam_streamparm_op) (struct gspca_dev *,
struct v4l2_streamparm *);
typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
@@ -112,8 +112,8 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
cam_set_reg_op set_register;
cam_get_reg_op get_register;
+ cam_chip_info_op get_chip_info;
#endif
- cam_ident_op get_chip_ident;
#if IS_ENABLED(CONFIG_INPUT)
cam_int_pkt_op int_pkt_scan;
/* other_input makes the gspca core create gspca_dev->input even when
diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c
index 6008c8d..a915096 100644
--- a/drivers/media/usb/gspca/pac7302.c
+++ b/drivers/media/usb/gspca/pac7302.c
@@ -93,7 +93,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/input.h>
-#include <media/v4l2-chip-ident.h>
#include "gspca.h"
/* Include pac common sof detection functions */
#include "pac_common.h"
@@ -849,8 +848,7 @@
* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
* long on the USB bus)
*/
- if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
- reg->match.addr == 0 &&
+ if (reg->match.addr == 0 &&
(reg->reg < 0x000000ff) &&
(reg->val <= 0x000000ff)
) {
@@ -871,20 +869,6 @@
}
return gspca_dev->usb_err;
}
-
-static int sd_chip_ident(struct gspca_dev *gspca_dev,
- struct v4l2_dbg_chip_ident *chip)
-{
- int ret = -EINVAL;
-
- if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
- chip->match.addr == 0) {
- chip->revision = 0;
- chip->ident = V4L2_IDENT_UNKNOWN;
- ret = 0;
- }
- return ret;
-}
#endif
#if IS_ENABLED(CONFIG_INPUT)
@@ -931,7 +915,6 @@
.dq_callback = do_autogain,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.set_register = sd_dbg_s_register,
- .get_chip_ident = sd_chip_ident,
#endif
#if IS_ENABLED(CONFIG_INPUT)
.int_pkt_scan = sd_int_pkt_scan,
diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c
index ead9a1f..f4453d5 100644
--- a/drivers/media/usb/gspca/sn9c20x.c
+++ b/drivers/media/usb/gspca/sn9c20x.c
@@ -27,7 +27,6 @@
#include "gspca.h"
#include "jpeg.h"
-#include <media/v4l2-chip-ident.h>
#include <linux/dmi.h>
MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
@@ -582,22 +581,6 @@
4, 2, 0, -1, -3, -5, -7, -9, -11
};
-static const u16 i2c_ident[] = {
- V4L2_IDENT_OV9650,
- V4L2_IDENT_OV9655,
- V4L2_IDENT_SOI968,
- V4L2_IDENT_OV7660,
- V4L2_IDENT_OV7670,
- V4L2_IDENT_MT9V011,
- V4L2_IDENT_MT9V111,
- V4L2_IDENT_MT9V112,
- V4L2_IDENT_MT9M001C12ST,
- V4L2_IDENT_MT9M111,
- V4L2_IDENT_MT9M112,
- V4L2_IDENT_HV7131R,
-[SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN,
-};
-
static const u16 bridge_init[][2] = {
{0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
{0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
@@ -1574,21 +1557,19 @@
{
struct sd *sd = (struct sd *) gspca_dev;
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- if (reg->match.addr != 0)
- return -EINVAL;
+ reg->size = 1;
+ switch (reg->match.addr) {
+ case 0:
if (reg->reg < 0x1000 || reg->reg > 0x11ff)
return -EINVAL;
reg_r(gspca_dev, reg->reg, 1);
reg->val = gspca_dev->usb_buf[0];
return gspca_dev->usb_err;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- if (reg->match.addr != sd->i2c_addr)
- return -EINVAL;
+ case 1:
if (sd->sensor >= SENSOR_MT9V011 &&
sd->sensor <= SENSOR_MT9M112) {
i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val);
+ reg->size = 2;
} else {
i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val);
}
@@ -1602,17 +1583,13 @@
{
struct sd *sd = (struct sd *) gspca_dev;
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- if (reg->match.addr != 0)
- return -EINVAL;
+ switch (reg->match.addr) {
+ case 0:
if (reg->reg < 0x1000 || reg->reg > 0x11ff)
return -EINVAL;
reg_w1(gspca_dev, reg->reg, reg->val);
return gspca_dev->usb_err;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- if (reg->match.addr != sd->i2c_addr)
- return -EINVAL;
+ case 1:
if (sd->sensor >= SENSOR_MT9V011 &&
sd->sensor <= SENSOR_MT9M112) {
i2c_w2(gspca_dev, reg->reg, reg->val);
@@ -1623,29 +1600,17 @@
}
return -EINVAL;
}
-#endif
-static int sd_chip_ident(struct gspca_dev *gspca_dev,
- struct v4l2_dbg_chip_ident *chip)
+static int sd_chip_info(struct gspca_dev *gspca_dev,
+ struct v4l2_dbg_chip_info *chip)
{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (chip->match.type) {
- case V4L2_CHIP_MATCH_HOST:
- if (chip->match.addr != 0)
- return -EINVAL;
- chip->revision = 0;
- chip->ident = V4L2_IDENT_SN9C20X;
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- if (chip->match.addr != sd->i2c_addr)
- return -EINVAL;
- chip->revision = 0;
- chip->ident = i2c_ident[sd->sensor];
- return 0;
- }
- return -EINVAL;
+ if (chip->match.addr > 1)
+ return -EINVAL;
+ if (chip->match.addr == 1)
+ strlcpy(chip->name, "sensor", sizeof(chip->name));
+ return 0;
}
+#endif
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
@@ -2356,8 +2321,8 @@
#ifdef CONFIG_VIDEO_ADV_DEBUG
.set_register = sd_dbg_s_register,
.get_register = sd_dbg_g_register,
+ .get_chip_info = sd_chip_info,
#endif
- .get_chip_ident = sd_chip_ident,
};
#define SN9C20X(sensor, i2c_addr, flags) \
diff --git a/drivers/media/usb/hdpvr/Kconfig b/drivers/media/usb/hdpvr/Kconfig
index de247f3..d73d9a1 100644
--- a/drivers/media/usb/hdpvr/Kconfig
+++ b/drivers/media/usb/hdpvr/Kconfig
@@ -1,7 +1,7 @@
config VIDEO_HDPVR
tristate "Hauppauge HD PVR support"
- depends on VIDEO_DEV
+ depends on VIDEO_DEV && VIDEO_V4L2
---help---
This is a video4linux driver for Hauppauge's HD PVR USB device.
diff --git a/drivers/media/usb/hdpvr/hdpvr-control.c b/drivers/media/usb/hdpvr/hdpvr-control.c
index ae8f229..6053661 100644
--- a/drivers/media/usb/hdpvr/hdpvr-control.c
+++ b/drivers/media/usb/hdpvr/hdpvr-control.c
@@ -45,20 +45,11 @@
return ret < 0 ? ret : 0;
}
-struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
+int get_video_info(struct hdpvr_device *dev, struct hdpvr_video_info *vidinf)
{
- struct hdpvr_video_info *vidinf = NULL;
-#ifdef HDPVR_DEBUG
- char print_buf[15];
-#endif
int ret;
- vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
- if (!vidinf) {
- v4l2_err(&dev->v4l2_dev, "out of memory\n");
- goto err;
- }
-
+ vidinf->valid = false;
mutex_lock(&dev->usbc_mutex);
ret = usb_control_msg(dev->udev,
usb_rcvctrlpipe(dev->udev, 0),
@@ -66,14 +57,10 @@
0x1400, 0x0003,
dev->usbc_buf, 5,
1000);
- if (ret == 5) {
- vidinf->width = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
- vidinf->height = dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
- vidinf->fps = dev->usbc_buf[4];
- }
#ifdef HDPVR_DEBUG
if (hdpvr_debug & MSG_INFO) {
+ char print_buf[15];
hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
sizeof(print_buf), 0);
v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
@@ -82,12 +69,15 @@
#endif
mutex_unlock(&dev->usbc_mutex);
- if (!vidinf->width || !vidinf->height || !vidinf->fps) {
- kfree(vidinf);
- vidinf = NULL;
- }
-err:
- return vidinf;
+ if (ret < 0)
+ return ret;
+
+ vidinf->width = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+ vidinf->height = dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
+ vidinf->fps = dev->usbc_buf[4];
+ vidinf->valid = vidinf->width && vidinf->height && vidinf->fps;
+
+ return 0;
}
int get_input_lines_info(struct hdpvr_device *dev)
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c
index 8247c19..cb69405 100644
--- a/drivers/media/usb/hdpvr/hdpvr-core.c
+++ b/drivers/media/usb/hdpvr/hdpvr-core.c
@@ -220,7 +220,6 @@
{
int ret;
u8 *buf;
- struct hdpvr_video_info *vidinf;
if (device_authorization(dev))
return -EACCES;
@@ -242,13 +241,6 @@
"control request returned %d\n", ret);
mutex_unlock(&dev->usbc_mutex);
- vidinf = get_video_info(dev);
- if (!vidinf)
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "no valid video signal or device init failed\n");
- else
- kfree(vidinf);
-
/* enable fan and bling leds */
mutex_lock(&dev->usbc_mutex);
buf[0] = 0x1;
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index 774ba0e..4f8567a 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -277,44 +277,50 @@
static int hdpvr_start_streaming(struct hdpvr_device *dev)
{
int ret;
- struct hdpvr_video_info *vidinf;
+ struct hdpvr_video_info vidinf;
if (dev->status == STATUS_STREAMING)
return 0;
- else if (dev->status != STATUS_IDLE)
+ if (dev->status != STATUS_IDLE)
return -EAGAIN;
- vidinf = get_video_info(dev);
+ ret = get_video_info(dev, &vidinf);
+ if (ret < 0)
+ return ret;
- if (vidinf) {
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "video signal: %dx%d@%dhz\n", vidinf->width,
- vidinf->height, vidinf->fps);
- kfree(vidinf);
-
- /* start streaming 2 request */
- ret = usb_control_msg(dev->udev,
- usb_sndctrlpipe(dev->udev, 0),
- 0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "encoder start control request returned %d\n", ret);
-
- hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
-
- dev->status = STATUS_STREAMING;
-
- INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
- queue_work(dev->workqueue, &dev->worker);
-
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
- "streaming started\n");
-
- return 0;
+ if (!vidinf.valid) {
+ msleep(250);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "no video signal at input %d\n", dev->options.video_input);
+ return -EAGAIN;
}
- msleep(250);
- v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
- "no video signal at input %d\n", dev->options.video_input);
- return -EAGAIN;
+
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "video signal: %dx%d@%dhz\n", vidinf.width,
+ vidinf.height, vidinf.fps);
+
+ /* start streaming 2 request */
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "encoder start control request returned %d\n", ret);
+ if (ret < 0)
+ return ret;
+
+ ret = hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+ if (ret)
+ return ret;
+
+ dev->status = STATUS_STREAMING;
+
+ INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
+ queue_work(dev->workqueue, &dev->worker);
+
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "streaming started\n");
+
+ return 0;
}
@@ -606,22 +612,20 @@
static int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a)
{
struct hdpvr_device *dev = video_drvdata(file);
- struct hdpvr_video_info *vid_info;
+ struct hdpvr_video_info vid_info;
struct hdpvr_fh *fh = _fh;
+ int ret;
- *a = V4L2_STD_ALL;
+ *a = V4L2_STD_UNKNOWN;
if (dev->options.video_input == HDPVR_COMPONENT)
return fh->legacy_mode ? 0 : -ENODATA;
- vid_info = get_video_info(dev);
- if (vid_info == NULL)
- return 0;
- if (vid_info->width == 720 &&
- (vid_info->height == 480 || vid_info->height == 576)) {
- *a = (vid_info->height == 480) ?
+ ret = get_video_info(dev, &vid_info);
+ if (vid_info.valid && vid_info.width == 720 &&
+ (vid_info.height == 480 || vid_info.height == 576)) {
+ *a = (vid_info.height == 480) ?
V4L2_STD_525_60 : V4L2_STD_625_50;
}
- kfree(vid_info);
- return 0;
+ return ret;
}
static int vidioc_s_dv_timings(struct file *file, void *_fh,
@@ -665,7 +669,7 @@
{
struct hdpvr_device *dev = video_drvdata(file);
struct hdpvr_fh *fh = _fh;
- struct hdpvr_video_info *vid_info;
+ struct hdpvr_video_info vid_info;
bool interlaced;
int ret = 0;
int i;
@@ -673,10 +677,12 @@
fh->legacy_mode = false;
if (dev->options.video_input)
return -ENODATA;
- vid_info = get_video_info(dev);
- if (vid_info == NULL)
+ ret = get_video_info(dev, &vid_info);
+ if (ret)
+ return ret;
+ if (!vid_info.valid)
return -ENOLCK;
- interlaced = vid_info->fps <= 30;
+ interlaced = vid_info.fps <= 30;
for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++) {
const struct v4l2_bt_timings *bt = &hdpvr_dv_timings[i].bt;
unsigned hsize;
@@ -688,17 +694,17 @@
bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch +
bt->height;
fps = (unsigned)bt->pixelclock / (hsize * vsize);
- if (bt->width != vid_info->width ||
- bt->height != vid_info->height ||
+ if (bt->width != vid_info.width ||
+ bt->height != vid_info.height ||
bt->interlaced != interlaced ||
- (fps != vid_info->fps && fps + 1 != vid_info->fps))
+ (fps != vid_info.fps && fps + 1 != vid_info.fps))
continue;
*timings = hdpvr_dv_timings[i];
break;
}
if (i == ARRAY_SIZE(hdpvr_dv_timings))
ret = -ERANGE;
- kfree(vid_info);
+
return ret;
}
@@ -988,6 +994,7 @@
{
struct hdpvr_device *dev = video_drvdata(file);
struct hdpvr_fh *fh = _fh;
+ int ret;
/*
* The original driver would always returns the current detected
@@ -1000,14 +1007,15 @@
* last set format.
*/
if (fh->legacy_mode) {
- struct hdpvr_video_info *vid_info;
+ struct hdpvr_video_info vid_info;
- vid_info = get_video_info(dev);
- if (!vid_info)
+ ret = get_video_info(dev, &vid_info);
+ if (ret < 0)
+ return ret;
+ if (!vid_info.valid)
return -EFAULT;
- f->fmt.pix.width = vid_info->width;
- f->fmt.pix.height = vid_info->height;
- kfree(vid_info);
+ f->fmt.pix.width = vid_info.width;
+ f->fmt.pix.height = vid_info.height;
} else {
f->fmt.pix.width = dev->width;
f->fmt.pix.height = dev->height;
diff --git a/drivers/media/usb/hdpvr/hdpvr.h b/drivers/media/usb/hdpvr/hdpvr.h
index 1478f3d..dc685d4 100644
--- a/drivers/media/usb/hdpvr/hdpvr.h
+++ b/drivers/media/usb/hdpvr/hdpvr.h
@@ -154,6 +154,7 @@
u16 width;
u16 height;
u8 fps;
+ bool valid;
};
enum {
@@ -303,7 +304,7 @@
int hdpvr_config_call(struct hdpvr_device *dev, uint value,
unsigned char valbuf);
-struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev);
+int get_video_info(struct hdpvr_device *dev, struct hdpvr_video_info *vid_info);
/* :0 s b8 81 1800 0003 0003 3 < */
/* :0 0 3 = 0301ff */
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index e11267f..c4d51d7 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -2704,6 +2704,10 @@
pvr2_hdw_render_useless(hdw);
}
+void pvr2_hdw_set_v4l2_dev(struct pvr2_hdw *hdw, struct video_device *vdev)
+{
+ vdev->v4l2_dev = &hdw->v4l2_dev;
+}
/* Destroy hardware interaction structure */
void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
@@ -5162,41 +5166,3 @@
} while(0); LOCK_GIVE(hdw->ctl_lock);
return result;
}
-
-
-int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
- const struct v4l2_dbg_match *match, u64 reg_id,
- int setFl, u64 *val_ptr)
-{
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct v4l2_dbg_register req;
- int stat = 0;
- int okFl = 0;
-
- if (!capable(CAP_SYS_ADMIN)) return -EPERM;
-
- req.match = *match;
- req.reg = reg_id;
- if (setFl) req.val = *val_ptr;
- /* It would be nice to know if a sub-device answered the request */
- v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
- if (!setFl) *val_ptr = req.val;
- if (okFl) {
- return stat;
- }
- return -EINVAL;
-#else
- return -ENOSYS;
-#endif
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
index 91bae93..4184707 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
@@ -22,6 +22,7 @@
#include <linux/usb.h>
#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
#include "pvrusb2-io.h"
#include "pvrusb2-ctrl.h"
@@ -138,6 +139,9 @@
/* Called when hardware has been unplugged */
void pvr2_hdw_disconnect(struct pvr2_hdw *);
+/* Sets v4l2_dev of a video_device struct */
+void pvr2_hdw_set_v4l2_dev(struct pvr2_hdw *, struct video_device *);
+
/* Get the number of defined controls */
unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
@@ -234,15 +238,6 @@
void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
enum pvr2_v4l_type index,int);
-/* Direct read/write access to chip's registers:
- match - specify criteria to identify target chip (this is a v4l dbg struct)
- reg_id - register number to access
- setFl - true to set the register, false to read it
- val_ptr - storage location for source / result. */
-int pvr2_hdw_register_access(struct pvr2_hdw *,
- const struct v4l2_dbg_match *match, u64 reg_id,
- int setFl, u64 *val_ptr);
-
/* The following entry points are all lower level things you normally don't
want to worry about. */
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-io.c b/drivers/media/usb/pvrusb2/pvrusb2-io.c
index 20b6ae0..1e35474 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-io.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-io.c
@@ -354,9 +354,9 @@
if (scnt < sp->buffer_slot_count) {
struct pvr2_buffer **nb = NULL;
if (scnt) {
- nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
+ nb = kmemdup(sp->buffers, scnt * sizeof(*nb),
+ GFP_KERNEL);
if (!nb) return -ENOMEM;
- memcpy(nb,sp->buffers,scnt * sizeof(*nb));
}
kfree(sp->buffers);
sp->buffers = nb;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index a8a65fa..7c280f3 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -31,6 +31,7 @@
#include <linux/videodev2.h>
#include <linux/module.h>
#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
@@ -800,36 +801,6 @@
return 0;
}
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int pvr2_g_register(struct file *file, void *priv, struct v4l2_dbg_register *req)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- u64 val;
- int ret;
-
- ret = pvr2_hdw_register_access(
- hdw, &req->match, req->reg,
- 0, &val);
- req->val = val;
- return ret;
-}
-
-static int pvr2_s_register(struct file *file, void *priv, const struct v4l2_dbg_register *req)
-{
- struct pvr2_v4l2_fh *fh = file->private_data;
- struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
- u64 val;
- int ret;
-
- val = req->val;
- ret = pvr2_hdw_register_access(
- hdw, &req->match, req->reg,
- 1, &val);
- return ret;
-}
-#endif
-
static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
.vidioc_querycap = pvr2_querycap,
.vidioc_g_priority = pvr2_g_priority,
@@ -864,10 +835,6 @@
.vidioc_g_ext_ctrls = pvr2_g_ext_ctrls,
.vidioc_s_ext_ctrls = pvr2_s_ext_ctrls,
.vidioc_try_ext_ctrls = pvr2_try_ext_ctrls,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = pvr2_g_register,
- .vidioc_s_register = pvr2_s_register,
-#endif
};
static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
@@ -904,8 +871,8 @@
static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
{
if (!dip) return;
- if (!dip->devbase.parent) return;
- dip->devbase.parent = NULL;
+ if (!dip->devbase.v4l2_dev->dev) return;
+ dip->devbase.v4l2_dev->dev = NULL;
device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
}
@@ -1298,7 +1265,6 @@
struct pvr2_v4l2 *vp,
int v4l_type)
{
- struct usb_device *usbdev;
int mindevnum;
int unit_number;
struct pvr2_hdw *hdw;
@@ -1306,7 +1272,6 @@
dip->v4lp = vp;
hdw = vp->channel.mc_head->hdw;
- usbdev = pvr2_hdw_get_dev(hdw);
dip->v4l_type = v4l_type;
switch (v4l_type) {
case VFL_TYPE_GRABBER:
@@ -1355,7 +1320,7 @@
if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
mindevnum = nr_ptr[unit_number];
}
- dip->devbase.parent = &usbdev->dev;
+ pvr2_hdw_set_v4l2_dev(hdw, &dip->devbase);
if ((video_register_device(&dip->devbase,
dip->v4l_type, mindevnum) < 0) &&
(video_register_device(&dip->devbase,
diff --git a/drivers/media/usb/sn9c102/sn9c102.h b/drivers/media/usb/sn9c102/sn9c102.h
index 2bc153e..8a917f06 100644
--- a/drivers/media/usb/sn9c102/sn9c102.h
+++ b/drivers/media/usb/sn9c102/sn9c102.h
@@ -25,6 +25,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/spinlock.h>
@@ -100,6 +101,8 @@
struct sn9c102_device {
struct video_device* v4ldev;
+ struct v4l2_device v4l2_dev;
+
enum sn9c102_bridge bridge;
struct sn9c102_sensor sensor;
diff --git a/drivers/media/usb/sn9c102/sn9c102_core.c b/drivers/media/usb/sn9c102/sn9c102_core.c
index c957e9a..2cb44de 100644
--- a/drivers/media/usb/sn9c102/sn9c102_core.c
+++ b/drivers/media/usb/sn9c102/sn9c102_core.c
@@ -1737,6 +1737,7 @@
video_device_node_name(cam->v4ldev));
video_set_drvdata(cam->v4ldev, NULL);
video_unregister_device(cam->v4ldev);
+ v4l2_device_unregister(&cam->v4l2_dev);
usb_put_dev(cam->usbdev);
kfree(cam->control_buffer);
kfree(cam);
@@ -3254,6 +3255,13 @@
cam->usbdev = udev;
+ /* register v4l2_device early so it can be used for printks */
+ if (v4l2_device_register(&intf->dev, &cam->v4l2_dev)) {
+ dev_err(&intf->dev, "v4l2_device_register failed\n");
+ err = -ENOMEM;
+ goto fail;
+ }
+
if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
DBG(1, "kzalloc() failed");
err = -ENOMEM;
@@ -3325,7 +3333,7 @@
strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
cam->v4ldev->fops = &sn9c102_fops;
cam->v4ldev->release = video_device_release;
- cam->v4ldev->parent = &udev->dev;
+ cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
init_completion(&cam->probe);
@@ -3377,6 +3385,7 @@
kfree(cam->control_buffer);
if (cam->v4ldev)
video_device_release(cam->v4ldev);
+ v4l2_device_unregister(&cam->v4l2_dev);
kfree(cam);
}
return err;
@@ -3407,6 +3416,8 @@
wake_up_interruptible_all(&cam->wait_open);
+ v4l2_device_disconnect(&cam->v4l2_dev);
+
kref_put(&cam->kref, sn9c102_release_resources);
up_write(&sn9c102_dev_lock);
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c
index a59153d2..876fc26 100644
--- a/drivers/media/usb/stk1160/stk1160-v4l.c
+++ b/drivers/media/usb/stk1160/stk1160-v4l.c
@@ -31,7 +31,6 @@
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
#include <media/videobuf2-vmalloc.h>
#include <media/saa7115.h>
@@ -454,19 +453,6 @@
return 0;
}
-static int vidioc_g_chip_ident(struct file *file, void *priv,
- struct v4l2_dbg_chip_ident *chip)
-{
- switch (chip->match.type) {
- case V4L2_CHIP_MATCH_BRIDGE:
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int vidioc_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg)
@@ -475,19 +461,6 @@
int rc;
u8 val;
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /* TODO: is this correct? */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
- return 0;
- default:
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
- }
-
/* Match host */
rc = stk1160_read_reg(dev, reg->reg, &val);
reg->val = val;
@@ -501,19 +474,6 @@
{
struct stk1160 *dev = video_drvdata(file);
- switch (reg->match.type) {
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
- return 0;
- case V4L2_CHIP_MATCH_I2C_ADDR:
- /* TODO: is this correct? */
- v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
- return 0;
- default:
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
- }
-
/* Match host */
return stk1160_write_reg(dev, reg->reg, cpu_to_le16(reg->val));
}
@@ -543,7 +503,6 @@
.vidioc_log_status = v4l2_ctrl_log_status,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c
index 307d8c5..1ccaadd 100644
--- a/drivers/media/usb/tm6000/tm6000-cards.c
+++ b/drivers/media/usb/tm6000/tm6000-cards.c
@@ -1114,7 +1114,7 @@
/* Default values for STD and resolutions */
dev->width = 720;
dev->height = 480;
- dev->norm = V4L2_STD_PAL_M;
+ dev->norm = V4L2_STD_NTSC_M;
/* Configure tuner */
tm6000_config_tuner(dev);
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index a78de1d..cc1aa14 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -1076,6 +1076,15 @@
return 0;
}
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+ struct tm6000_fh *fh = priv;
+ struct tm6000_core *dev = fh->dev;
+
+ *norm = dev->norm;
+ return 0;
+}
+
static const char *iname[] = {
[TM6000_INPUT_TV] = "Television",
[TM6000_INPUT_COMPOSITE1] = "Composite 1",
@@ -1134,7 +1143,7 @@
dev->input = i;
- rc = vidioc_s_std(file, priv, dev->vfd->current_norm);
+ rc = vidioc_s_std(file, priv, dev->norm);
return rc;
}
@@ -1547,6 +1556,7 @@
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_s_std = vidioc_s_std,
+ .vidioc_g_std = vidioc_g_std,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
@@ -1570,7 +1580,6 @@
.ioctl_ops = &video_ioctl_ops,
.release = video_device_release,
.tvnorms = TM6000_STD,
- .current_norm = V4L2_STD_NTSC_M,
};
static const struct v4l2_file_operations radio_fops = {
diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
index 21b9049..f8a60c1 100644
--- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
@@ -1768,6 +1768,8 @@
i2c_del_adapter(&ttusb->i2c_adap);
err_unregister_adapter:
dvb_unregister_adapter (&ttusb->adapter);
+ ttusb_free_iso_urbs(ttusb);
+ kfree(ttusb);
return result;
}
diff --git a/drivers/media/usb/usbtv/Kconfig b/drivers/media/usb/usbtv/Kconfig
new file mode 100644
index 0000000..8864436
--- /dev/null
+++ b/drivers/media/usb/usbtv/Kconfig
@@ -0,0 +1,10 @@
+config VIDEO_USBTV
+ tristate "USBTV007 video capture support"
+ depends on VIDEO_DEV
+ select VIDEOBUF2_VMALLOC
+
+ ---help---
+ This is a video4linux2 driver for USBTV007 based video capture devices.
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbtv
diff --git a/drivers/media/usb/usbtv/Makefile b/drivers/media/usb/usbtv/Makefile
new file mode 100644
index 0000000..28b872f
--- /dev/null
+++ b/drivers/media/usb/usbtv/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_USBTV) += usbtv.o
diff --git a/drivers/media/usb/usbtv/usbtv.c b/drivers/media/usb/usbtv/usbtv.c
new file mode 100644
index 0000000..bf43f87
--- /dev/null
+++ b/drivers/media/usb/usbtv/usbtv.c
@@ -0,0 +1,696 @@
+/*
+ * Fushicai USBTV007 Video Grabber Driver
+ *
+ * Product web site:
+ * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
+ *
+ * Following LWN articles were very useful in construction of this driver:
+ * Video4Linux2 API series: http://lwn.net/Articles/203924/
+ * videobuf2 API explanation: http://lwn.net/Articles/447435/
+ * Thanks go to Jonathan Corbet for providing this quality documentation.
+ * He is awesome.
+ *
+ * Copyright (c) 2013 Lubomir Rintel
+ * All rights reserved.
+ * No physical hardware was harmed running Windows during the
+ * reverse-engineering activity
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h>
+
+/* Hardware. */
+#define USBTV_VIDEO_ENDP 0x81
+#define USBTV_BASE 0xc000
+#define USBTV_REQUEST_REG 12
+
+/* Number of concurrent isochronous urbs submitted.
+ * Higher numbers was seen to overly saturate the USB bus. */
+#define USBTV_ISOC_TRANSFERS 16
+#define USBTV_ISOC_PACKETS 8
+
+#define USBTV_WIDTH 720
+#define USBTV_HEIGHT 480
+
+#define USBTV_CHUNK_SIZE 256
+#define USBTV_CHUNK 240
+#define USBTV_CHUNKS (USBTV_WIDTH * USBTV_HEIGHT \
+ / 2 / USBTV_CHUNK)
+
+/* Chunk header. */
+#define USBTV_MAGIC_OK(chunk) ((be32_to_cpu(chunk[0]) & 0xff000000) \
+ == 0x88000000)
+#define USBTV_FRAME_ID(chunk) ((be32_to_cpu(chunk[0]) & 0x00ff0000) >> 16)
+#define USBTV_ODD(chunk) ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15)
+#define USBTV_CHUNK_NO(chunk) (be32_to_cpu(chunk[0]) & 0x00000fff)
+
+/* A single videobuf2 frame buffer. */
+struct usbtv_buf {
+ struct vb2_buffer vb;
+ struct list_head list;
+};
+
+/* Per-device structure. */
+struct usbtv {
+ struct device *dev;
+ struct usb_device *udev;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct vb2_queue vb2q;
+ struct mutex v4l2_lock;
+ struct mutex vb2q_lock;
+
+ /* List of videobuf2 buffers protected by a lock. */
+ spinlock_t buflock;
+ struct list_head bufs;
+
+ /* Number of currently processed frame, useful find
+ * out when a new one begins. */
+ u32 frame_id;
+
+ int iso_size;
+ unsigned int sequence;
+ struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
+};
+
+static int usbtv_setup_capture(struct usbtv *usbtv)
+{
+ int ret;
+ int pipe = usb_rcvctrlpipe(usbtv->udev, 0);
+ int i;
+ static const u16 protoregs[][2] = {
+ /* These seem to enable the device. */
+ { USBTV_BASE + 0x0008, 0x0001 },
+ { USBTV_BASE + 0x01d0, 0x00ff },
+ { USBTV_BASE + 0x01d9, 0x0002 },
+
+ /* These seem to influence color parameters, such as
+ * brightness, etc. */
+ { USBTV_BASE + 0x0239, 0x0040 },
+ { USBTV_BASE + 0x0240, 0x0000 },
+ { USBTV_BASE + 0x0241, 0x0000 },
+ { USBTV_BASE + 0x0242, 0x0002 },
+ { USBTV_BASE + 0x0243, 0x0080 },
+ { USBTV_BASE + 0x0244, 0x0012 },
+ { USBTV_BASE + 0x0245, 0x0090 },
+ { USBTV_BASE + 0x0246, 0x0000 },
+
+ { USBTV_BASE + 0x0278, 0x002d },
+ { USBTV_BASE + 0x0279, 0x000a },
+ { USBTV_BASE + 0x027a, 0x0032 },
+ { 0xf890, 0x000c },
+ { 0xf894, 0x0086 },
+
+ { USBTV_BASE + 0x00ac, 0x00c0 },
+ { USBTV_BASE + 0x00ad, 0x0000 },
+ { USBTV_BASE + 0x00a2, 0x0012 },
+ { USBTV_BASE + 0x00a3, 0x00e0 },
+ { USBTV_BASE + 0x00a4, 0x0028 },
+ { USBTV_BASE + 0x00a5, 0x0082 },
+ { USBTV_BASE + 0x00a7, 0x0080 },
+ { USBTV_BASE + 0x0000, 0x0014 },
+ { USBTV_BASE + 0x0006, 0x0003 },
+ { USBTV_BASE + 0x0090, 0x0099 },
+ { USBTV_BASE + 0x0091, 0x0090 },
+ { USBTV_BASE + 0x0094, 0x0068 },
+ { USBTV_BASE + 0x0095, 0x0070 },
+ { USBTV_BASE + 0x009c, 0x0030 },
+ { USBTV_BASE + 0x009d, 0x00c0 },
+ { USBTV_BASE + 0x009e, 0x00e0 },
+ { USBTV_BASE + 0x0019, 0x0006 },
+ { USBTV_BASE + 0x008c, 0x00ba },
+ { USBTV_BASE + 0x0101, 0x00ff },
+ { USBTV_BASE + 0x010c, 0x00b3 },
+ { USBTV_BASE + 0x01b2, 0x0080 },
+ { USBTV_BASE + 0x01b4, 0x00a0 },
+ { USBTV_BASE + 0x014c, 0x00ff },
+ { USBTV_BASE + 0x014d, 0x00ca },
+ { USBTV_BASE + 0x0113, 0x0053 },
+ { USBTV_BASE + 0x0119, 0x008a },
+ { USBTV_BASE + 0x013c, 0x0003 },
+ { USBTV_BASE + 0x0150, 0x009c },
+ { USBTV_BASE + 0x0151, 0x0071 },
+ { USBTV_BASE + 0x0152, 0x00c6 },
+ { USBTV_BASE + 0x0153, 0x0084 },
+ { USBTV_BASE + 0x0154, 0x00bc },
+ { USBTV_BASE + 0x0155, 0x00a0 },
+ { USBTV_BASE + 0x0156, 0x00a0 },
+ { USBTV_BASE + 0x0157, 0x009c },
+ { USBTV_BASE + 0x0158, 0x001f },
+ { USBTV_BASE + 0x0159, 0x0006 },
+ { USBTV_BASE + 0x015d, 0x0000 },
+
+ { USBTV_BASE + 0x0284, 0x0088 },
+ { USBTV_BASE + 0x0003, 0x0004 },
+ { USBTV_BASE + 0x001a, 0x0079 },
+ { USBTV_BASE + 0x0100, 0x00d3 },
+ { USBTV_BASE + 0x010e, 0x0068 },
+ { USBTV_BASE + 0x010f, 0x009c },
+ { USBTV_BASE + 0x0112, 0x00f0 },
+ { USBTV_BASE + 0x0115, 0x0015 },
+ { USBTV_BASE + 0x0117, 0x0000 },
+ { USBTV_BASE + 0x0118, 0x00fc },
+ { USBTV_BASE + 0x012d, 0x0004 },
+ { USBTV_BASE + 0x012f, 0x0008 },
+ { USBTV_BASE + 0x0220, 0x002e },
+ { USBTV_BASE + 0x0225, 0x0008 },
+ { USBTV_BASE + 0x024e, 0x0002 },
+ { USBTV_BASE + 0x024f, 0x0001 },
+ { USBTV_BASE + 0x0254, 0x005f },
+ { USBTV_BASE + 0x025a, 0x0012 },
+ { USBTV_BASE + 0x025b, 0x0001 },
+ { USBTV_BASE + 0x0263, 0x001c },
+ { USBTV_BASE + 0x0266, 0x0011 },
+ { USBTV_BASE + 0x0267, 0x0005 },
+ { USBTV_BASE + 0x024e, 0x0002 },
+ { USBTV_BASE + 0x024f, 0x0002 },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(protoregs); i++) {
+ u16 index = protoregs[i][0];
+ u16 value = protoregs[i][1];
+
+ ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Called for each 256-byte image chunk.
+ * First word identifies the chunk, followed by 240 words of image
+ * data and padding. */
+static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
+{
+ int frame_id, odd, chunk_no;
+ u32 *frame;
+ struct usbtv_buf *buf;
+ unsigned long flags;
+
+ /* Ignore corrupted lines. */
+ if (!USBTV_MAGIC_OK(chunk))
+ return;
+ frame_id = USBTV_FRAME_ID(chunk);
+ odd = USBTV_ODD(chunk);
+ chunk_no = USBTV_CHUNK_NO(chunk);
+
+ /* Deinterlace. TODO: Use interlaced frame format. */
+ chunk_no = (chunk_no - chunk_no % 3) * 2 + chunk_no % 3;
+ chunk_no += !odd * 3;
+
+ if (chunk_no >= USBTV_CHUNKS)
+ return;
+
+ /* Beginning of a frame. */
+ if (chunk_no == 0)
+ usbtv->frame_id = frame_id;
+
+ spin_lock_irqsave(&usbtv->buflock, flags);
+ if (list_empty(&usbtv->bufs)) {
+ /* No free buffers. Userspace likely too slow. */
+ spin_unlock_irqrestore(&usbtv->buflock, flags);
+ return;
+ }
+
+ /* First available buffer. */
+ buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list);
+ frame = vb2_plane_vaddr(&buf->vb, 0);
+
+ /* Copy the chunk. */
+ memcpy(&frame[chunk_no * USBTV_CHUNK], &chunk[1],
+ USBTV_CHUNK * sizeof(chunk[1]));
+
+ /* Last chunk in a frame, signalling an end */
+ if (usbtv->frame_id && chunk_no == USBTV_CHUNKS-1) {
+ int size = vb2_plane_size(&buf->vb, 0);
+
+ buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
+ buf->vb.v4l2_buf.sequence = usbtv->sequence++;
+ v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+ vb2_set_plane_payload(&buf->vb, 0, size);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+ list_del(&buf->list);
+ }
+
+ spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+/* Got image data. Each packet contains a number of 256-word chunks we
+ * compose the image from. */
+static void usbtv_iso_cb(struct urb *ip)
+{
+ int ret;
+ int i;
+ struct usbtv *usbtv = (struct usbtv *)ip->context;
+
+ switch (ip->status) {
+ /* All fine. */
+ case 0:
+ break;
+ /* Device disconnected or capture stopped? */
+ case -ENODEV:
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ESHUTDOWN:
+ return;
+ /* Unknown error. Retry. */
+ default:
+ dev_warn(usbtv->dev, "Bad response for ISO request.\n");
+ goto resubmit;
+ }
+
+ for (i = 0; i < ip->number_of_packets; i++) {
+ int size = ip->iso_frame_desc[i].actual_length;
+ unsigned char *data = ip->transfer_buffer +
+ ip->iso_frame_desc[i].offset;
+ int offset;
+
+ for (offset = 0; USBTV_CHUNK_SIZE * offset < size; offset++)
+ usbtv_image_chunk(usbtv,
+ (u32 *)&data[USBTV_CHUNK_SIZE * offset]);
+ }
+
+resubmit:
+ ret = usb_submit_urb(ip, GFP_ATOMIC);
+ if (ret < 0)
+ dev_warn(usbtv->dev, "Could not resubmit ISO URB\n");
+}
+
+static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv)
+{
+ struct urb *ip;
+ int size = usbtv->iso_size;
+ int i;
+
+ ip = usb_alloc_urb(USBTV_ISOC_PACKETS, GFP_KERNEL);
+ if (ip == NULL)
+ return NULL;
+
+ ip->dev = usbtv->udev;
+ ip->context = usbtv;
+ ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP);
+ ip->interval = 1;
+ ip->transfer_flags = URB_ISO_ASAP;
+ ip->transfer_buffer = kzalloc(size * USBTV_ISOC_PACKETS,
+ GFP_KERNEL);
+ ip->complete = usbtv_iso_cb;
+ ip->number_of_packets = USBTV_ISOC_PACKETS;
+ ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS;
+ for (i = 0; i < USBTV_ISOC_PACKETS; i++) {
+ ip->iso_frame_desc[i].offset = size * i;
+ ip->iso_frame_desc[i].length = size;
+ }
+
+ return ip;
+}
+
+static void usbtv_stop(struct usbtv *usbtv)
+{
+ int i;
+ unsigned long flags;
+
+ /* Cancel running transfers. */
+ for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
+ struct urb *ip = usbtv->isoc_urbs[i];
+ if (ip == NULL)
+ continue;
+ usb_kill_urb(ip);
+ kfree(ip->transfer_buffer);
+ usb_free_urb(ip);
+ usbtv->isoc_urbs[i] = NULL;
+ }
+
+ /* Return buffers to userspace. */
+ spin_lock_irqsave(&usbtv->buflock, flags);
+ while (!list_empty(&usbtv->bufs)) {
+ struct usbtv_buf *buf = list_first_entry(&usbtv->bufs,
+ struct usbtv_buf, list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ list_del(&buf->list);
+ }
+ spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+static int usbtv_start(struct usbtv *usbtv)
+{
+ int i;
+ int ret;
+
+ ret = usb_set_interface(usbtv->udev, 0, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = usbtv_setup_capture(usbtv);
+ if (ret < 0)
+ return ret;
+
+ ret = usb_set_interface(usbtv->udev, 0, 1);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
+ struct urb *ip;
+
+ ip = usbtv_setup_iso_transfer(usbtv);
+ if (ip == NULL) {
+ ret = -ENOMEM;
+ goto start_fail;
+ }
+ usbtv->isoc_urbs[i] = ip;
+
+ ret = usb_submit_urb(ip, GFP_KERNEL);
+ if (ret < 0)
+ goto start_fail;
+ }
+
+ return 0;
+
+start_fail:
+ usbtv_stop(usbtv);
+ return ret;
+}
+
+struct usb_device_id usbtv_id_table[] = {
+ { USB_DEVICE(0x1b71, 0x3002) },
+ {}
+};
+MODULE_DEVICE_TABLE(usb, usbtv_id_table);
+
+static int usbtv_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct usbtv *dev = video_drvdata(file);
+
+ strlcpy(cap->driver, "usbtv", sizeof(cap->driver));
+ strlcpy(cap->card, "usbtv", sizeof(cap->card));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE;
+ cap->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+static int usbtv_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i)
+{
+ if (i->index > 0)
+ return -EINVAL;
+
+ strlcpy(i->name, "Composite", sizeof(i->name));
+ i->type = V4L2_INPUT_TYPE_CAMERA;
+ i->std = V4L2_STD_525_60;
+ return 0;
+}
+
+static int usbtv_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ if (f->index > 0)
+ return -EINVAL;
+
+ strlcpy(f->description, "16 bpp YUY2, 4:2:2, packed",
+ sizeof(f->description));
+ f->pixelformat = V4L2_PIX_FMT_YUYV;
+ return 0;
+}
+
+static int usbtv_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ f->fmt.pix.width = USBTV_WIDTH;
+ f->fmt.pix.height = USBTV_HEIGHT;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ f->fmt.pix.bytesperline = USBTV_WIDTH * 2;
+ f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height);
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ f->fmt.pix.priv = 0;
+ return 0;
+}
+
+static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+ *norm = V4L2_STD_525_60;
+ return 0;
+}
+
+static int usbtv_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int usbtv_s_input(struct file *file, void *priv, unsigned int i)
+{
+ if (i > 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
+{
+ if (norm & V4L2_STD_525_60)
+ return 0;
+ return -EINVAL;
+}
+
+struct v4l2_ioctl_ops usbtv_ioctl_ops = {
+ .vidioc_querycap = usbtv_querycap,
+ .vidioc_enum_input = usbtv_enum_input,
+ .vidioc_enum_fmt_vid_cap = usbtv_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = usbtv_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = usbtv_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = usbtv_fmt_vid_cap,
+ .vidioc_g_std = usbtv_g_std,
+ .vidioc_s_std = usbtv_s_std,
+ .vidioc_g_input = usbtv_g_input,
+ .vidioc_s_input = usbtv_s_input,
+
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+};
+
+struct v4l2_file_operations usbtv_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = vb2_fop_mmap,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .read = vb2_fop_read,
+ .poll = vb2_fop_poll,
+};
+
+static int usbtv_queue_setup(struct vb2_queue *vq,
+ const struct v4l2_format *v4l_fmt, unsigned int *nbuffers,
+ unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
+{
+ if (*nbuffers < 2)
+ *nbuffers = 2;
+ *nplanes = 1;
+ sizes[0] = USBTV_CHUNK * USBTV_CHUNKS * sizeof(u32);
+
+ return 0;
+}
+
+static void usbtv_buf_queue(struct vb2_buffer *vb)
+{
+ struct usbtv *usbtv = vb2_get_drv_priv(vb->vb2_queue);
+ struct usbtv_buf *buf = container_of(vb, struct usbtv_buf, vb);
+ unsigned long flags;
+
+ if (usbtv->udev == NULL) {
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+ return;
+ }
+
+ spin_lock_irqsave(&usbtv->buflock, flags);
+ list_add_tail(&buf->list, &usbtv->bufs);
+ spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+ struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+ if (usbtv->udev == NULL)
+ return -ENODEV;
+
+ return usbtv_start(usbtv);
+}
+
+static int usbtv_stop_streaming(struct vb2_queue *vq)
+{
+ struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+ if (usbtv->udev == NULL)
+ return -ENODEV;
+
+ usbtv_stop(usbtv);
+ return 0;
+}
+
+struct vb2_ops usbtv_vb2_ops = {
+ .queue_setup = usbtv_queue_setup,
+ .buf_queue = usbtv_buf_queue,
+ .start_streaming = usbtv_start_streaming,
+ .stop_streaming = usbtv_stop_streaming,
+};
+
+static void usbtv_release(struct v4l2_device *v4l2_dev)
+{
+ struct usbtv *usbtv = container_of(v4l2_dev, struct usbtv, v4l2_dev);
+
+ v4l2_device_unregister(&usbtv->v4l2_dev);
+ vb2_queue_release(&usbtv->vb2q);
+ kfree(usbtv);
+}
+
+static int usbtv_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int ret;
+ int size;
+ struct device *dev = &intf->dev;
+ struct usbtv *usbtv;
+
+ /* Checks that the device is what we think it is. */
+ if (intf->num_altsetting != 2)
+ return -ENODEV;
+ if (intf->altsetting[1].desc.bNumEndpoints != 4)
+ return -ENODEV;
+
+ /* Packet size is split into 11 bits of base size and count of
+ * extra multiplies of it.*/
+ size = usb_endpoint_maxp(&intf->altsetting[1].endpoint[0].desc);
+ size = (size & 0x07ff) * (((size & 0x1800) >> 11) + 1);
+
+ /* Device structure */
+ usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL);
+ if (usbtv == NULL)
+ return -ENOMEM;
+ usbtv->dev = dev;
+ usbtv->udev = usb_get_dev(interface_to_usbdev(intf));
+ usbtv->iso_size = size;
+ spin_lock_init(&usbtv->buflock);
+ mutex_init(&usbtv->v4l2_lock);
+ mutex_init(&usbtv->vb2q_lock);
+ INIT_LIST_HEAD(&usbtv->bufs);
+
+ /* videobuf2 structure */
+ usbtv->vb2q.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ usbtv->vb2q.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+ usbtv->vb2q.drv_priv = usbtv;
+ usbtv->vb2q.buf_struct_size = sizeof(struct usbtv_buf);
+ usbtv->vb2q.ops = &usbtv_vb2_ops;
+ usbtv->vb2q.mem_ops = &vb2_vmalloc_memops;
+ usbtv->vb2q.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ usbtv->vb2q.lock = &usbtv->vb2q_lock;
+ ret = vb2_queue_init(&usbtv->vb2q);
+ if (ret < 0) {
+ dev_warn(dev, "Could not initialize videobuf2 queue\n");
+ goto usbtv_fail;
+ }
+
+ /* v4l2 structure */
+ usbtv->v4l2_dev.release = usbtv_release;
+ ret = v4l2_device_register(dev, &usbtv->v4l2_dev);
+ if (ret < 0) {
+ dev_warn(dev, "Could not register v4l2 device\n");
+ goto v4l2_fail;
+ }
+
+ usb_set_intfdata(intf, usbtv);
+
+ /* Video structure */
+ strlcpy(usbtv->vdev.name, "usbtv", sizeof(usbtv->vdev.name));
+ usbtv->vdev.v4l2_dev = &usbtv->v4l2_dev;
+ usbtv->vdev.release = video_device_release_empty;
+ usbtv->vdev.fops = &usbtv_fops;
+ usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops;
+ usbtv->vdev.tvnorms = V4L2_STD_525_60;
+ usbtv->vdev.queue = &usbtv->vb2q;
+ usbtv->vdev.lock = &usbtv->v4l2_lock;
+ set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags);
+ video_set_drvdata(&usbtv->vdev, usbtv);
+ ret = video_register_device(&usbtv->vdev, VFL_TYPE_GRABBER, -1);
+ if (ret < 0) {
+ dev_warn(dev, "Could not register video device\n");
+ goto vdev_fail;
+ }
+
+ dev_info(dev, "Fushicai USBTV007 Video Grabber\n");
+ return 0;
+
+vdev_fail:
+ v4l2_device_unregister(&usbtv->v4l2_dev);
+v4l2_fail:
+ vb2_queue_release(&usbtv->vb2q);
+usbtv_fail:
+ kfree(usbtv);
+
+ return ret;
+}
+
+static void usbtv_disconnect(struct usb_interface *intf)
+{
+ struct usbtv *usbtv = usb_get_intfdata(intf);
+
+ mutex_lock(&usbtv->vb2q_lock);
+ mutex_lock(&usbtv->v4l2_lock);
+
+ usbtv_stop(usbtv);
+ usb_set_intfdata(intf, NULL);
+ video_unregister_device(&usbtv->vdev);
+ v4l2_device_disconnect(&usbtv->v4l2_dev);
+ usb_put_dev(usbtv->udev);
+ usbtv->udev = NULL;
+
+ mutex_unlock(&usbtv->v4l2_lock);
+ mutex_unlock(&usbtv->vb2q_lock);
+
+ v4l2_device_put(&usbtv->v4l2_dev);
+}
+
+MODULE_AUTHOR("Lubomir Rintel");
+MODULE_DESCRIPTION("Fushicai USBTV007 Video Grabber Driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+struct usb_driver usbtv_usb_driver = {
+ .name = "usbtv",
+ .id_table = usbtv_id_table,
+ .probe = usbtv_probe,
+ .disconnect = usbtv_disconnect,
+};
+
+module_usb_driver(usbtv_usb_driver);
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index d34c2af..5c9e312 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -467,8 +467,6 @@
struct usb_usbvision *usbvision = video_drvdata(file);
int err_code;
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
/* NT100x has a 8-bit register space */
err_code = usbvision_read_reg(usbvision, reg->reg&0xff);
if (err_code < 0) {
@@ -488,8 +486,6 @@
struct usb_usbvision *usbvision = video_drvdata(file);
int err_code;
- if (!v4l2_chip_match_host(®->match))
- return -EINVAL;
/* NT100x has a 8-bit register space */
err_code = usbvision_write_reg(usbvision, reg->reg & 0xff, reg->val);
if (err_code < 0) {
@@ -608,6 +604,14 @@
return 0;
}
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+ struct usb_usbvision *usbvision = video_drvdata(file);
+
+ *id = usbvision->tvnorm_id;
+ return 0;
+}
+
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *vt)
{
@@ -1248,6 +1252,7 @@
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
.vidioc_s_std = vidioc_s_std,
+ .vidioc_g_std = vidioc_g_std,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
@@ -1274,7 +1279,6 @@
.name = "usbvision-video",
.release = video_device_release,
.tvnorms = USBVISION_NORMS,
- .current_norm = V4L2_STD_PAL
};
@@ -1307,9 +1311,6 @@
.name = "usbvision-radio",
.release = video_device_release,
.ioctl_ops = &usbvision_radio_ioctl_ops,
-
- .tvnorms = USBVISION_NORMS,
- .current_norm = V4L2_STD_PAL
};
@@ -1459,6 +1460,7 @@
usbvision_remove_sysfs(usbvision->vdev);
usbvision_unregister_video(usbvision);
+ kfree(usbvision->alt_max_pkt_size);
usb_free_urb(usbvision->ctrl_urb);
@@ -1574,6 +1576,7 @@
usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
dev_err(&intf->dev, "usbvision: out of memory!\n");
+ usbvision_release(usbvision);
return -ENOMEM;
}
diff --git a/drivers/media/usb/uvc/Kconfig b/drivers/media/usb/uvc/Kconfig
index 541c9f1..6ed85efa 100644
--- a/drivers/media/usb/uvc/Kconfig
+++ b/drivers/media/usb/uvc/Kconfig
@@ -1,5 +1,6 @@
config USB_VIDEO_CLASS
tristate "USB Video Class (UVC)"
+ depends on VIDEO_V4L2
select VIDEOBUF2_VMALLOC
---help---
Support for the USB Video Class (UVC). Currently only video
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 5dbefa6..81695d4 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1836,8 +1836,8 @@
INIT_LIST_HEAD(&dev->chains);
INIT_LIST_HEAD(&dev->streams);
atomic_set(&dev->nstreams, 0);
- atomic_set(&dev->users, 0);
atomic_set(&dev->nmappings, 0);
+ mutex_init(&dev->lock);
dev->udev = usb_get_dev(udev);
dev->intf = usb_get_intf(intf);
@@ -1950,8 +1950,13 @@
/* Controls are cached on the fly so they don't need to be saved. */
if (intf->cur_altsetting->desc.bInterfaceSubClass ==
- UVC_SC_VIDEOCONTROL)
- return uvc_status_suspend(dev);
+ UVC_SC_VIDEOCONTROL) {
+ mutex_lock(&dev->lock);
+ if (dev->users)
+ uvc_status_stop(dev);
+ mutex_unlock(&dev->lock);
+ return 0;
+ }
list_for_each_entry(stream, &dev->streams, list) {
if (stream->intf == intf)
@@ -1973,14 +1978,20 @@
if (intf->cur_altsetting->desc.bInterfaceSubClass ==
UVC_SC_VIDEOCONTROL) {
- if (reset) {
- int ret = uvc_ctrl_resume_device(dev);
+ int ret = 0;
+ if (reset) {
+ ret = uvc_ctrl_resume_device(dev);
if (ret < 0)
return ret;
}
- return uvc_status_resume(dev);
+ mutex_lock(&dev->lock);
+ if (dev->users)
+ ret = uvc_status_start(dev, GFP_NOIO);
+ mutex_unlock(&dev->lock);
+
+ return ret;
}
list_for_each_entry(stream, &dev->streams, list) {
@@ -2163,6 +2174,24 @@
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_DEF },
+ /* Dell Alienware X51 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x05a9,
+ .idProduct = 0x2643,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_DEF },
+ /* Dell Studio Hybrid 140g (OmniVision webcam) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x05a9,
+ .idProduct = 0x264a,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_DEF },
/* Apple Built-In iSight */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index b749277..f552ab9 100644
--- a/drivers/media/usb/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
@@ -206,32 +206,15 @@
uvc_input_cleanup(dev);
}
-int uvc_status_start(struct uvc_device *dev)
+int uvc_status_start(struct uvc_device *dev, gfp_t flags)
{
if (dev->int_urb == NULL)
return 0;
- return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+ return usb_submit_urb(dev->int_urb, flags);
}
void uvc_status_stop(struct uvc_device *dev)
{
usb_kill_urb(dev->int_urb);
}
-
-int uvc_status_suspend(struct uvc_device *dev)
-{
- if (atomic_read(&dev->users))
- usb_kill_urb(dev->int_urb);
-
- return 0;
-}
-
-int uvc_status_resume(struct uvc_device *dev)
-{
- if (dev->int_urb == NULL || atomic_read(&dev->users) == 0)
- return 0;
-
- return usb_submit_urb(dev->int_urb, GFP_NOIO);
-}
-
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index b2dc326..3afff92 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -498,16 +498,20 @@
return -ENOMEM;
}
- if (atomic_inc_return(&stream->dev->users) == 1) {
- ret = uvc_status_start(stream->dev);
+ mutex_lock(&stream->dev->lock);
+ if (stream->dev->users == 0) {
+ ret = uvc_status_start(stream->dev, GFP_KERNEL);
if (ret < 0) {
- atomic_dec(&stream->dev->users);
+ mutex_unlock(&stream->dev->lock);
usb_autopm_put_interface(stream->dev->intf);
kfree(handle);
return ret;
}
}
+ stream->dev->users++;
+ mutex_unlock(&stream->dev->lock);
+
v4l2_fh_init(&handle->vfh, stream->vdev);
v4l2_fh_add(&handle->vfh);
handle->chain = stream->chain;
@@ -538,8 +542,10 @@
kfree(handle);
file->private_data = NULL;
- if (atomic_dec_return(&stream->dev->users) == 0)
+ mutex_lock(&stream->dev->lock);
+ if (--stream->dev->users == 0)
uvc_status_stop(stream->dev);
+ mutex_unlock(&stream->dev->lock);
usb_autopm_put_interface(stream->dev->intf);
return 0;
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index af505fd..9e35982 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -514,7 +514,8 @@
char name[32];
enum uvc_device_state state;
- atomic_t users;
+ struct mutex lock; /* Protects users */
+ unsigned int users;
atomic_t nmappings;
/* Video control interface */
@@ -660,10 +661,8 @@
/* Status */
extern int uvc_status_init(struct uvc_device *dev);
extern void uvc_status_cleanup(struct uvc_device *dev);
-extern int uvc_status_start(struct uvc_device *dev);
+extern int uvc_status_start(struct uvc_device *dev, gfp_t flags);
extern void uvc_status_stop(struct uvc_device *dev);
-extern int uvc_status_suspend(struct uvc_device *dev);
-extern int uvc_status_resume(struct uvc_device *dev);
/* Controls */
extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index aa50c46..4c33b8d 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -5,7 +5,8 @@
tuner-objs := tuner-core.o
videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
- v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
+ v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o \
+ v4l2-async.o
ifeq ($(CONFIG_COMPAT),y)
videodev-objs += v4l2-compat-ioctl32.o
endif
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
new file mode 100644
index 0000000..aae2417
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -0,0 +1,284 @@
+/*
+ * V4L2 asynchronous subdevice registration API
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
+{
+#if IS_ENABLED(CONFIG_I2C)
+ struct i2c_client *client = i2c_verify_client(dev);
+ return client &&
+ asd->bus_type == V4L2_ASYNC_BUS_I2C &&
+ asd->match.i2c.adapter_id == client->adapter->nr &&
+ asd->match.i2c.address == client->addr;
+#else
+ return false;
+#endif
+}
+
+static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
+{
+ return asd->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
+ !strcmp(asd->match.platform.name, dev_name(dev));
+}
+
+static LIST_HEAD(subdev_list);
+static LIST_HEAD(notifier_list);
+static DEFINE_MUTEX(list_lock);
+
+static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
+ struct v4l2_async_subdev_list *asdl)
+{
+ struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+ struct v4l2_async_subdev *asd;
+ bool (*match)(struct device *,
+ struct v4l2_async_subdev *);
+
+ list_for_each_entry(asd, ¬ifier->waiting, list) {
+ /* bus_type has been verified valid before */
+ switch (asd->bus_type) {
+ case V4L2_ASYNC_BUS_CUSTOM:
+ match = asd->match.custom.match;
+ if (!match)
+ /* Match always */
+ return asd;
+ break;
+ case V4L2_ASYNC_BUS_PLATFORM:
+ match = match_platform;
+ break;
+ case V4L2_ASYNC_BUS_I2C:
+ match = match_i2c;
+ break;
+ default:
+ /* Cannot happen, unless someone breaks us */
+ WARN_ON(true);
+ return NULL;
+ }
+
+ /* match cannot be NULL here */
+ if (match(sd->dev, asd))
+ return asd;
+ }
+
+ return NULL;
+}
+
+static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
+ struct v4l2_async_subdev_list *asdl,
+ struct v4l2_async_subdev *asd)
+{
+ struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+ int ret;
+
+ /* Remove from the waiting list */
+ list_del(&asd->list);
+ asdl->asd = asd;
+ asdl->notifier = notifier;
+
+ if (notifier->bound) {
+ ret = notifier->bound(notifier, sd, asd);
+ if (ret < 0)
+ return ret;
+ }
+ /* Move from the global subdevice list to notifier's done */
+ list_move(&asdl->list, ¬ifier->done);
+
+ ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
+ if (ret < 0) {
+ if (notifier->unbind)
+ notifier->unbind(notifier, sd, asd);
+ return ret;
+ }
+
+ if (list_empty(¬ifier->waiting) && notifier->complete)
+ return notifier->complete(notifier);
+
+ return 0;
+}
+
+static void v4l2_async_cleanup(struct v4l2_async_subdev_list *asdl)
+{
+ struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+
+ v4l2_device_unregister_subdev(sd);
+ /* Subdevice driver will reprobe and put asdl back onto the list */
+ list_del_init(&asdl->list);
+ asdl->asd = NULL;
+ sd->dev = NULL;
+}
+
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+ struct v4l2_async_notifier *notifier)
+{
+ struct v4l2_async_subdev_list *asdl, *tmp;
+ struct v4l2_async_subdev *asd;
+ int i;
+
+ if (!notifier->num_subdevs || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
+ return -EINVAL;
+
+ notifier->v4l2_dev = v4l2_dev;
+ INIT_LIST_HEAD(¬ifier->waiting);
+ INIT_LIST_HEAD(¬ifier->done);
+
+ for (i = 0; i < notifier->num_subdevs; i++) {
+ asd = notifier->subdev[i];
+
+ switch (asd->bus_type) {
+ case V4L2_ASYNC_BUS_CUSTOM:
+ case V4L2_ASYNC_BUS_PLATFORM:
+ case V4L2_ASYNC_BUS_I2C:
+ break;
+ default:
+ dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
+ "Invalid bus-type %u on %p\n",
+ asd->bus_type, asd);
+ return -EINVAL;
+ }
+ list_add_tail(&asd->list, ¬ifier->waiting);
+ }
+
+ mutex_lock(&list_lock);
+
+ /* Keep also completed notifiers on the list */
+ list_add(¬ifier->list, ¬ifier_list);
+
+ list_for_each_entry_safe(asdl, tmp, &subdev_list, list) {
+ int ret;
+
+ asd = v4l2_async_belongs(notifier, asdl);
+ if (!asd)
+ continue;
+
+ ret = v4l2_async_test_notify(notifier, asdl, asd);
+ if (ret < 0) {
+ mutex_unlock(&list_lock);
+ return ret;
+ }
+ }
+
+ mutex_unlock(&list_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_async_notifier_register);
+
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+{
+ struct v4l2_async_subdev_list *asdl, *tmp;
+ unsigned int notif_n_subdev = notifier->num_subdevs;
+ unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
+ struct device *dev[n_subdev];
+ int i = 0;
+
+ mutex_lock(&list_lock);
+
+ list_del(¬ifier->list);
+
+ list_for_each_entry_safe(asdl, tmp, ¬ifier->done, list) {
+ struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+
+ dev[i] = get_device(sd->dev);
+
+ v4l2_async_cleanup(asdl);
+
+ /* If we handled USB devices, we'd have to lock the parent too */
+ device_release_driver(dev[i++]);
+
+ if (notifier->unbind)
+ notifier->unbind(notifier, sd, sd->asdl.asd);
+ }
+
+ mutex_unlock(&list_lock);
+
+ while (i--) {
+ struct device *d = dev[i];
+
+ if (d && device_attach(d) < 0) {
+ const char *name = "(none)";
+ int lock = device_trylock(d);
+
+ if (lock && d->driver)
+ name = d->driver->name;
+ dev_err(d, "Failed to re-probe to %s\n", name);
+ if (lock)
+ device_unlock(d);
+ }
+ put_device(d);
+ }
+ /*
+ * Don't care about the waiting list, it is initialised and populated
+ * upon notifier registration.
+ */
+}
+EXPORT_SYMBOL(v4l2_async_notifier_unregister);
+
+int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+{
+ struct v4l2_async_subdev_list *asdl = &sd->asdl;
+ struct v4l2_async_notifier *notifier;
+
+ mutex_lock(&list_lock);
+
+ INIT_LIST_HEAD(&asdl->list);
+
+ list_for_each_entry(notifier, ¬ifier_list, list) {
+ struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, asdl);
+ if (asd) {
+ int ret = v4l2_async_test_notify(notifier, asdl, asd);
+ mutex_unlock(&list_lock);
+ return ret;
+ }
+ }
+
+ /* None matched, wait for hot-plugging */
+ list_add(&asdl->list, &subdev_list);
+
+ mutex_unlock(&list_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_async_register_subdev);
+
+void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
+{
+ struct v4l2_async_subdev_list *asdl = &sd->asdl;
+ struct v4l2_async_notifier *notifier = asdl->notifier;
+
+ if (!asdl->asd) {
+ if (!list_empty(&asdl->list))
+ v4l2_async_cleanup(asdl);
+ return;
+ }
+
+ mutex_lock(&list_lock);
+
+ list_add(&asdl->asd->list, ¬ifier->waiting);
+
+ v4l2_async_cleanup(asdl);
+
+ if (notifier->unbind)
+ notifier->unbind(notifier, sd, sd->asdl.asd);
+
+ mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL(v4l2_async_unregister_subdev);
diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c
new file mode 100644
index 0000000..b67de86
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-clk.c
@@ -0,0 +1,242 @@
+/*
+ * V4L2 clock service
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/atomic.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <media/v4l2-clk.h>
+#include <media/v4l2-subdev.h>
+
+static DEFINE_MUTEX(clk_lock);
+static LIST_HEAD(clk_list);
+
+static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id)
+{
+ struct v4l2_clk *clk;
+
+ list_for_each_entry(clk, &clk_list, list) {
+ if (strcmp(dev_id, clk->dev_id))
+ continue;
+
+ if (!id || !clk->id || !strcmp(clk->id, id))
+ return clk;
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+
+struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id)
+{
+ struct v4l2_clk *clk;
+
+ mutex_lock(&clk_lock);
+ clk = v4l2_clk_find(dev_name(dev), id);
+
+ if (!IS_ERR(clk))
+ atomic_inc(&clk->use_count);
+ mutex_unlock(&clk_lock);
+
+ return clk;
+}
+EXPORT_SYMBOL(v4l2_clk_get);
+
+void v4l2_clk_put(struct v4l2_clk *clk)
+{
+ struct v4l2_clk *tmp;
+
+ if (IS_ERR(clk))
+ return;
+
+ mutex_lock(&clk_lock);
+
+ list_for_each_entry(tmp, &clk_list, list)
+ if (tmp == clk)
+ atomic_dec(&clk->use_count);
+
+ mutex_unlock(&clk_lock);
+}
+EXPORT_SYMBOL(v4l2_clk_put);
+
+static int v4l2_clk_lock_driver(struct v4l2_clk *clk)
+{
+ struct v4l2_clk *tmp;
+ int ret = -ENODEV;
+
+ mutex_lock(&clk_lock);
+
+ list_for_each_entry(tmp, &clk_list, list)
+ if (tmp == clk) {
+ ret = !try_module_get(clk->ops->owner);
+ if (ret)
+ ret = -EFAULT;
+ break;
+ }
+
+ mutex_unlock(&clk_lock);
+
+ return ret;
+}
+
+static void v4l2_clk_unlock_driver(struct v4l2_clk *clk)
+{
+ module_put(clk->ops->owner);
+}
+
+int v4l2_clk_enable(struct v4l2_clk *clk)
+{
+ int ret = v4l2_clk_lock_driver(clk);
+
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&clk->lock);
+
+ if (++clk->enable == 1 && clk->ops->enable) {
+ ret = clk->ops->enable(clk);
+ if (ret < 0)
+ clk->enable--;
+ }
+
+ mutex_unlock(&clk->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_enable);
+
+/*
+ * You might Oops if you try to disabled a disabled clock, because then the
+ * driver isn't locked and could have been unloaded by now, so, don't do that
+ */
+void v4l2_clk_disable(struct v4l2_clk *clk)
+{
+ int enable;
+
+ mutex_lock(&clk->lock);
+
+ enable = --clk->enable;
+ if (WARN(enable < 0, "Unbalanced %s() on %s:%s!\n", __func__,
+ clk->dev_id, clk->id))
+ clk->enable++;
+ else if (!enable && clk->ops->disable)
+ clk->ops->disable(clk);
+
+ mutex_unlock(&clk->lock);
+
+ v4l2_clk_unlock_driver(clk);
+}
+EXPORT_SYMBOL(v4l2_clk_disable);
+
+unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk)
+{
+ int ret = v4l2_clk_lock_driver(clk);
+
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&clk->lock);
+ if (!clk->ops->get_rate)
+ ret = -ENOSYS;
+ else
+ ret = clk->ops->get_rate(clk);
+ mutex_unlock(&clk->lock);
+
+ v4l2_clk_unlock_driver(clk);
+
+ return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_get_rate);
+
+int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate)
+{
+ int ret = v4l2_clk_lock_driver(clk);
+
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&clk->lock);
+ if (!clk->ops->set_rate)
+ ret = -ENOSYS;
+ else
+ ret = clk->ops->set_rate(clk, rate);
+ mutex_unlock(&clk->lock);
+
+ v4l2_clk_unlock_driver(clk);
+
+ return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_set_rate);
+
+struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
+ const char *dev_id,
+ const char *id, void *priv)
+{
+ struct v4l2_clk *clk;
+ int ret;
+
+ if (!ops || !dev_id)
+ return ERR_PTR(-EINVAL);
+
+ clk = kzalloc(sizeof(struct v4l2_clk), GFP_KERNEL);
+ if (!clk)
+ return ERR_PTR(-ENOMEM);
+
+ clk->id = kstrdup(id, GFP_KERNEL);
+ clk->dev_id = kstrdup(dev_id, GFP_KERNEL);
+ if ((id && !clk->id) || !clk->dev_id) {
+ ret = -ENOMEM;
+ goto ealloc;
+ }
+ clk->ops = ops;
+ clk->priv = priv;
+ atomic_set(&clk->use_count, 0);
+ mutex_init(&clk->lock);
+
+ mutex_lock(&clk_lock);
+ if (!IS_ERR(v4l2_clk_find(dev_id, id))) {
+ mutex_unlock(&clk_lock);
+ ret = -EEXIST;
+ goto eexist;
+ }
+ list_add_tail(&clk->list, &clk_list);
+ mutex_unlock(&clk_lock);
+
+ return clk;
+
+eexist:
+ealloc:
+ kfree(clk->id);
+ kfree(clk->dev_id);
+ kfree(clk);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(v4l2_clk_register);
+
+void v4l2_clk_unregister(struct v4l2_clk *clk)
+{
+ if (WARN(atomic_read(&clk->use_count),
+ "%s(): Refusing to unregister ref-counted %s:%s clock!\n",
+ __func__, clk->dev_id, clk->id))
+ return;
+
+ mutex_lock(&clk_lock);
+ list_del(&clk->list);
+ mutex_unlock(&clk_lock);
+
+ kfree(clk->id);
+ kfree(clk->dev_id);
+ kfree(clk);
+}
+EXPORT_SYMBOL(v4l2_clk_unregister);
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 3fed63f..a95e5e2 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -61,7 +61,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
#include <linux/videodev2.h>
@@ -227,62 +226,9 @@
}
EXPORT_SYMBOL(v4l2_ctrl_next);
-int v4l2_chip_match_host(const struct v4l2_dbg_match *match)
-{
- switch (match->type) {
- case V4L2_CHIP_MATCH_BRIDGE:
- return match->addr == 0;
- default:
- return 0;
- }
-}
-EXPORT_SYMBOL(v4l2_chip_match_host);
-
-#if IS_ENABLED(CONFIG_I2C)
-int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match)
-{
- int len;
-
- if (c == NULL || match == NULL)
- return 0;
-
- switch (match->type) {
- case V4L2_CHIP_MATCH_I2C_DRIVER:
- if (c->driver == NULL || c->driver->driver.name == NULL)
- return 0;
- len = strlen(c->driver->driver.name);
- return len && !strncmp(c->driver->driver.name, match->name, len);
- case V4L2_CHIP_MATCH_I2C_ADDR:
- return c->addr == match->addr;
- case V4L2_CHIP_MATCH_SUBDEV:
- return 1;
- default:
- return 0;
- }
-}
-EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
-
-int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip,
- u32 ident, u32 revision)
-{
- if (!v4l2_chip_match_i2c_client(c, &chip->match))
- return 0;
- if (chip->ident == V4L2_IDENT_NONE) {
- chip->ident = ident;
- chip->revision = revision;
- }
- else {
- chip->ident = V4L2_IDENT_AMBIGUOUS;
- chip->revision = 0;
- }
- return 0;
-}
-EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
-
-/* ----------------------------------------------------------------- */
-
/* I2C Helper functions */
+#if IS_ENABLED(CONFIG_I2C)
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops)
@@ -291,6 +237,7 @@
sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
/* the owner is the same as the i2c_client's driver owner */
sd->owner = client->driver->driver.owner;
+ sd->dev = &client->dev;
/* i2c_client and v4l2_subdev point to one another */
v4l2_set_subdevdata(sd, client);
i2c_set_clientdata(client, sd);
@@ -301,8 +248,6 @@
}
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
-
-
/* Load an i2c sub-device. */
struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
struct i2c_adapter *adapter, struct i2c_board_info *info,
@@ -426,6 +371,7 @@
sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
/* the owner is the same as the spi_device's driver owner */
sd->owner = spi->dev.driver->owner;
+ sd->dev = &spi->dev;
/* spi_device and v4l2_subdev point to one another */
v4l2_set_subdevdata(sd, spi);
spi_set_drvdata(spi, sd);
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index f129551..8f7a6a4 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -1074,7 +1074,6 @@
case VIDIOC_TRY_DECODER_CMD:
case VIDIOC_DBG_S_REGISTER:
case VIDIOC_DBG_G_REGISTER:
- case VIDIOC_DBG_G_CHIP_IDENT:
case VIDIOC_S_HW_FREQ_SEEK:
case VIDIOC_S_DV_TIMINGS:
case VIDIOC_G_DV_TIMINGS:
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 5923c5d..c8859d6 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -495,8 +495,8 @@
};
/**
- * get_index - assign stream index number based on parent device
- * @vdev: video_device to assign index number to, vdev->parent should be assigned
+ * get_index - assign stream index number based on v4l2_dev
+ * @vdev: video_device to assign index number to, vdev->v4l2_dev should be assigned
*
* Note that when this is called the new device has not yet been registered
* in the video_device array, but it was able to obtain a minor number.
@@ -514,15 +514,11 @@
static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
int i;
- /* Some drivers do not set the parent. In that case always return 0. */
- if (vdev->parent == NULL)
- return 0;
-
bitmap_zero(used, VIDEO_NUM_DEVICES);
for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
if (video_device[i] != NULL &&
- video_device[i]->parent == vdev->parent) {
+ video_device[i]->v4l2_dev == vdev->v4l2_dev) {
set_bit(video_device[i]->index, used);
}
}
@@ -596,7 +592,6 @@
set_bit(_IOC_NR(VIDIOC_DBG_G_REGISTER), valid_ioctls);
set_bit(_IOC_NR(VIDIOC_DBG_S_REGISTER), valid_ioctls);
#endif
- SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident);
/* yes, really vidioc_subscribe_event */
SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event);
SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event);
@@ -675,9 +670,8 @@
SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
if (ops->vidioc_s_std)
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
- if (ops->vidioc_g_std || vdev->current_norm)
- set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
+ SET_VALID_IOCTL(ops, VIDIOC_G_STD, vidioc_g_std);
if (is_rx) {
SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
@@ -705,7 +699,7 @@
if (ops->vidioc_cropcap || ops->vidioc_g_selection)
set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER &&
- (ops->vidioc_g_std || vdev->current_norm)))
+ ops->vidioc_g_std))
set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
@@ -777,6 +771,9 @@
/* the release callback MUST be present */
if (WARN_ON(!vdev->release))
return -EINVAL;
+ /* the v4l2_dev pointer MUST be present */
+ if (WARN_ON(!vdev->v4l2_dev))
+ return -EINVAL;
/* v4l2_fh support */
spin_lock_init(&vdev->fh_lock);
@@ -804,16 +801,14 @@
vdev->vfl_type = type;
vdev->cdev = NULL;
- if (vdev->v4l2_dev) {
- if (vdev->v4l2_dev->dev)
- vdev->parent = vdev->v4l2_dev->dev;
- if (vdev->ctrl_handler == NULL)
- vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
- /* If the prio state pointer is NULL, then use the v4l2_device
- prio state. */
- if (vdev->prio == NULL)
- vdev->prio = &vdev->v4l2_dev->prio;
- }
+ if (vdev->dev_parent == NULL)
+ vdev->dev_parent = vdev->v4l2_dev->dev;
+ if (vdev->ctrl_handler == NULL)
+ vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
+ /* If the prio state pointer is NULL, then use the v4l2_device
+ prio state. */
+ if (vdev->prio == NULL)
+ vdev->prio = &vdev->v4l2_dev->prio;
/* Part 2: find a free minor, device node number and device index. */
#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
@@ -898,8 +893,7 @@
/* Part 4: register the device with sysfs */
vdev->dev.class = &video_class;
vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
- if (vdev->parent)
- vdev->dev.parent = vdev->parent;
+ vdev->dev.parent = vdev->dev_parent;
dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
ret = device_register(&vdev->dev);
if (ret < 0) {
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index 8ed5da2..02d1b63 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -44,7 +44,8 @@
v4l2_dev->dev = dev;
if (dev == NULL) {
/* If dev == NULL, then name must be filled in by the caller */
- WARN_ON(!v4l2_dev->name[0]);
+ if (WARN_ON(!v4l2_dev->name[0]))
+ return -EINVAL;
return 0;
}
@@ -105,7 +106,9 @@
{
struct v4l2_subdev *sd, *next;
- if (v4l2_dev == NULL)
+ /* Just return if v4l2_dev is NULL or if it was already
+ * unregistered before. */
+ if (v4l2_dev == NULL || !v4l2_dev->name[0])
return;
v4l2_device_disconnect(v4l2_dev);
@@ -135,6 +138,8 @@
}
#endif
}
+ /* Mark as unregistered, thus preventing duplicate unregistrations */
+ v4l2_dev->name[0] = '\0';
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister);
@@ -269,8 +274,10 @@
sd->v4l2_dev = NULL;
#if defined(CONFIG_MEDIA_CONTROLLER)
- if (v4l2_dev->mdev)
+ if (v4l2_dev->mdev) {
+ media_entity_remove_links(&sd->entity);
media_device_unregister_entity(&sd->entity);
+ }
#endif
video_unregister_device(sd->devnode);
module_put(sd->owner);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 7658586..68e6b5e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -26,7 +26,6 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
#include <media/videobuf2-core.h>
/* Zero out the end of the struct pointed to by p. Everything after, but
@@ -619,20 +618,6 @@
pr_info("pts=%llu\n", p->stop.pts);
}
-static void v4l_print_dbg_chip_ident(const void *arg, bool write_only)
-{
- const struct v4l2_dbg_chip_ident *p = arg;
-
- pr_cont("type=%u, ", p->match.type);
- if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
- pr_cont("name=%.*s, ",
- (int)sizeof(p->match.name), p->match.name);
- else
- pr_cont("addr=%u, ", p->match.addr);
- pr_cont("chip_ident=%u, revision=0x%x\n",
- p->ident, p->revision);
-}
-
static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
{
const struct v4l2_dbg_chip_info *p = arg;
@@ -1359,40 +1344,18 @@
return 0;
}
-static int v4l_g_std(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct video_device *vfd = video_devdata(file);
- v4l2_std_id *id = arg;
-
- /* Calls the specific handler */
- if (ops->vidioc_g_std)
- return ops->vidioc_g_std(file, fh, arg);
- if (vfd->current_norm) {
- *id = vfd->current_norm;
- return 0;
- }
- return -ENOTTY;
-}
-
static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct video_device *vfd = video_devdata(file);
v4l2_std_id id = *(v4l2_std_id *)arg, norm;
- int ret;
norm = id & vfd->tvnorms;
if (vfd->tvnorms && !norm) /* Check if std is supported */
return -EINVAL;
/* Calls the specific handler */
- ret = ops->vidioc_s_std(file, fh, norm);
-
- /* Updates standard information */
- if (ret >= 0)
- vfd->current_norm = norm;
- return ret;
+ return ops->vidioc_s_std(file, fh, norm);
}
static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
@@ -1402,10 +1365,10 @@
v4l2_std_id *p = arg;
/*
- * If nothing detected, it should return all supported
- * standard.
- * Drivers just need to mask the std argument, in order
- * to remove the standards that don't apply from the mask.
+ * If no signal is detected, then the driver should return
+ * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
+ * any standards that do not apply removed.
+ *
* This means that tuners, audio and video decoders can join
* their efforts to improve the standards detection.
*/
@@ -1495,7 +1458,6 @@
static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
- struct video_device *vfd = video_devdata(file);
struct v4l2_streamparm *p = arg;
v4l2_std_id std;
int ret = check_fmt(file, p->type);
@@ -1504,16 +1466,13 @@
return ret;
if (ops->vidioc_g_parm)
return ops->vidioc_g_parm(file, fh, p);
- std = vfd->current_norm;
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
return -EINVAL;
p->parm.capture.readbuffers = 2;
- if (is_valid_ioctl(vfd, VIDIOC_G_STD) && ops->vidioc_g_std)
- ret = ops->vidioc_g_std(file, fh, &std);
+ ret = ops->vidioc_g_std(file, fh, &std);
if (ret == 0)
- v4l2_video_std_frame_period(std,
- &p->parm.capture.timeperframe);
+ v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
return ret;
}
@@ -1802,7 +1761,8 @@
return v4l2_subdev_call(sd, core, g_register, p);
return -EINVAL;
}
- if (ops->vidioc_g_register)
+ if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
+ (ops->vidioc_g_chip_info || p->match.addr == 0))
return ops->vidioc_g_register(file, fh, p);
return -EINVAL;
#else
@@ -1829,7 +1789,8 @@
return v4l2_subdev_call(sd, core, s_register, p);
return -EINVAL;
}
- if (ops->vidioc_s_register)
+ if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
+ (ops->vidioc_g_chip_info || p->match.addr == 0))
return ops->vidioc_s_register(file, fh, p);
return -EINVAL;
#else
@@ -1837,18 +1798,6 @@
#endif
}
-static int v4l_dbg_g_chip_ident(const struct v4l2_ioctl_ops *ops,
- struct file *file, void *fh, void *arg)
-{
- struct v4l2_dbg_chip_ident *p = arg;
-
- p->ident = V4L2_IDENT_NONE;
- p->revision = 0;
- if (p->match.type == V4L2_CHIP_MATCH_SUBDEV)
- return -EINVAL;
- return ops->vidioc_g_chip_ident(file, fh, p);
-}
-
static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
@@ -1864,12 +1813,7 @@
p->flags |= V4L2_CHIP_FL_WRITABLE;
if (ops->vidioc_g_register)
p->flags |= V4L2_CHIP_FL_READABLE;
- if (vfd->v4l2_dev)
- strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
- else if (vfd->parent)
- strlcpy(p->name, vfd->parent->driver->name, sizeof(p->name));
- else
- strlcpy(p->name, "bridge", sizeof(p->name));
+ strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
if (ops->vidioc_g_chip_info)
return ops->vidioc_g_chip_info(file, fh, arg);
if (p->match.addr)
@@ -2048,7 +1992,7 @@
IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
- IOCTL_INFO_FNC(VIDIOC_G_STD, v4l_g_std, v4l_print_std, 0),
+ IOCTL_INFO_STD(VIDIOC_G_STD, vidioc_g_std, v4l_print_std, 0),
IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
@@ -2098,7 +2042,6 @@
IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
- IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_IDENT, v4l_dbg_g_chip_ident, v4l_print_dbg_chip_ident, 0),
IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO),
IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c
index 67f572c..65411adc 100644
--- a/drivers/media/v4l2-core/videobuf-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf-dma-contig.c
@@ -66,11 +66,14 @@
static void videobuf_vm_open(struct vm_area_struct *vma)
{
struct videobuf_mapping *map = vma->vm_private_data;
+ struct videobuf_queue *q = map->q;
- dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
+ dev_dbg(q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
map, map->count, vma->vm_start, vma->vm_end);
+ videobuf_queue_lock(q);
map->count++;
+ videobuf_queue_unlock(q);
}
static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -82,12 +85,11 @@
dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
map, map->count, vma->vm_start, vma->vm_end);
- map->count--;
- if (0 == map->count) {
+ videobuf_queue_lock(q);
+ if (!--map->count) {
struct videobuf_dma_contig_memory *mem;
dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
- videobuf_queue_lock(q);
/* We need first to cancel streams, before unmapping */
if (q->streaming)
@@ -126,8 +128,8 @@
kfree(map);
- videobuf_queue_unlock(q);
}
+ videobuf_queue_unlock(q);
}
static const struct vm_operations_struct videobuf_vm_ops = {
@@ -303,14 +305,9 @@
goto error;
/* Try to remap memory */
-
size = vma->vm_end - vma->vm_start;
- size = (size < mem->size) ? size : mem->size;
-
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- retval = remap_pfn_range(vma, vma->vm_start,
- mem->dma_handle >> PAGE_SHIFT,
- size, vma->vm_page_prot);
+ retval = vm_iomap_memory(vma, vma->vm_start, size);
if (retval) {
dev_err(q->dev, "mmap: remap failed with error %d. ",
retval);
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 828e7c1..9db674c 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -338,11 +338,14 @@
static void videobuf_vm_open(struct vm_area_struct *vma)
{
struct videobuf_mapping *map = vma->vm_private_data;
+ struct videobuf_queue *q = map->q;
dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map,
map->count, vma->vm_start, vma->vm_end);
+ videobuf_queue_lock(q);
map->count++;
+ videobuf_queue_unlock(q);
}
static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -355,10 +358,9 @@
dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map,
map->count, vma->vm_start, vma->vm_end);
- map->count--;
- if (0 == map->count) {
+ videobuf_queue_lock(q);
+ if (!--map->count) {
dprintk(1, "munmap %p q=%p\n", map, q);
- videobuf_queue_lock(q);
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
continue;
@@ -374,9 +376,9 @@
q->bufs[i]->baddr = 0;
q->ops->buf_release(q, q->bufs[i]);
}
- videobuf_queue_unlock(q);
kfree(map);
}
+ videobuf_queue_unlock(q);
return;
}
diff --git a/drivers/media/v4l2-core/videobuf-vmalloc.c b/drivers/media/v4l2-core/videobuf-vmalloc.c
index 2ff7fcc..1365c65 100644
--- a/drivers/media/v4l2-core/videobuf-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf-vmalloc.c
@@ -54,11 +54,14 @@
static void videobuf_vm_open(struct vm_area_struct *vma)
{
struct videobuf_mapping *map = vma->vm_private_data;
+ struct videobuf_queue *q = map->q;
dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map,
map->count, vma->vm_start, vma->vm_end);
+ videobuf_queue_lock(q);
map->count++;
+ videobuf_queue_unlock(q);
}
static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -70,12 +73,11 @@
dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map,
map->count, vma->vm_start, vma->vm_end);
- map->count--;
- if (0 == map->count) {
+ videobuf_queue_lock(q);
+ if (!--map->count) {
struct videobuf_vmalloc_memory *mem;
dprintk(1, "munmap %p q=%p\n", map, q);
- videobuf_queue_lock(q);
/* We need first to cancel streams, before unmapping */
if (q->streaming)
@@ -114,8 +116,8 @@
kfree(map);
- videobuf_queue_unlock(q);
}
+ videobuf_queue_unlock(q);
return;
}
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index e3bdc3b..9fc4bab 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2194,8 +2194,10 @@
*/
for (i = 0; i < q->num_buffers; i++) {
fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
- if (fileio->bufs[i].vaddr == NULL)
+ if (fileio->bufs[i].vaddr == NULL) {
+ ret = -EINVAL;
goto err_reqbufs;
+ }
fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
}
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index 05673ed..766a071 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1751,10 +1751,10 @@
*/
void vpfe_ipipe_unregister_entities(struct vpfe_ipipe_device *vpfe_ipipe)
{
- /* cleanup entity */
- media_entity_cleanup(&vpfe_ipipe->subdev.entity);
/* unregister subdev */
v4l2_device_unregister_subdev(&vpfe_ipipe->subdev);
+ /* cleanup entity */
+ media_entity_cleanup(&vpfe_ipipe->subdev.entity);
}
/*
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index b2f4ef8..59540cd 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -947,10 +947,10 @@
/* unregister video device */
vpfe_video_unregister(&ipipeif->video_in);
- /* cleanup entity */
- media_entity_cleanup(&ipipeif->subdev.entity);
/* unregister subdev */
v4l2_device_unregister_subdev(&ipipeif->subdev);
+ /* cleanup entity */
+ media_entity_cleanup(&ipipeif->subdev.entity);
}
int
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index 5829360f..ff48fce 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1750,10 +1750,10 @@
void vpfe_isif_unregister_entities(struct vpfe_isif_device *isif)
{
vpfe_video_unregister(&isif->video_out);
- /* cleanup entity */
- media_entity_cleanup(&isif->subdev.entity);
/* unregister subdev */
v4l2_device_unregister_subdev(&isif->subdev);
+ /* cleanup entity */
+ media_entity_cleanup(&isif->subdev.entity);
}
static void isif_restore_defaults(struct vpfe_isif_device *isif)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 126f84c..8e13bd4 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1777,14 +1777,14 @@
vpfe_video_unregister(&vpfe_rsz->resizer_a.video_out);
vpfe_video_unregister(&vpfe_rsz->resizer_b.video_out);
- /* cleanup entity */
- media_entity_cleanup(&vpfe_rsz->crop_resizer.subdev.entity);
- media_entity_cleanup(&vpfe_rsz->resizer_a.subdev.entity);
- media_entity_cleanup(&vpfe_rsz->resizer_b.subdev.entity);
/* unregister subdev */
v4l2_device_unregister_subdev(&vpfe_rsz->crop_resizer.subdev);
v4l2_device_unregister_subdev(&vpfe_rsz->resizer_a.subdev);
v4l2_device_unregister_subdev(&vpfe_rsz->resizer_b.subdev);
+ /* cleanup entity */
+ media_entity_cleanup(&vpfe_rsz->crop_resizer.subdev.entity);
+ media_entity_cleanup(&vpfe_rsz->resizer_a.subdev.entity);
+ media_entity_cleanup(&vpfe_rsz->resizer_b.subdev.entity);
}
/*
@@ -1865,12 +1865,12 @@
vpfe_video_unregister(&resizer->resizer_b.video_out);
out_video_out2_register:
vpfe_video_unregister(&resizer->resizer_a.video_out);
- media_entity_cleanup(&resizer->crop_resizer.subdev.entity);
- media_entity_cleanup(&resizer->resizer_a.subdev.entity);
- media_entity_cleanup(&resizer->resizer_b.subdev.entity);
v4l2_device_unregister_subdev(&resizer->crop_resizer.subdev);
v4l2_device_unregister_subdev(&resizer->resizer_a.subdev);
v4l2_device_unregister_subdev(&resizer->resizer_b.subdev);
+ media_entity_cleanup(&resizer->crop_resizer.subdev.entity);
+ media_entity_cleanup(&resizer->resizer_a.subdev.entity);
+ media_entity_cleanup(&resizer->resizer_b.subdev.entity);
return ret;
}
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index ba913f1..24d98a6 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -39,7 +39,7 @@
struct vpfe_device *vpfe_dev = video->vpfe_dev;
struct media_pad *remote;
- remote = media_entity_remote_source(&vpfe_dev->vpfe_isif.pads[0]);
+ remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
if (remote == NULL) {
pr_err("Invalid media connection to isif/ccdc\n");
return NULL;
@@ -56,7 +56,7 @@
struct media_pad *remote;
int i;
- remote = media_entity_remote_source(&vpfe_dev->vpfe_isif.pads[0]);
+ remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
if (remote == NULL) {
pr_err("Invalid media connection to isif/ccdc\n");
return -EINVAL;
@@ -89,7 +89,7 @@
static struct v4l2_subdev *
vpfe_video_remote_subdev(struct vpfe_video_device *video, u32 *pad)
{
- struct media_pad *remote = media_entity_remote_source(&video->pad);
+ struct media_pad *remote = media_entity_remote_pad(&video->pad);
if (remote == NULL || remote->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
return NULL;
@@ -114,7 +114,7 @@
return -EINVAL;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- remote = media_entity_remote_source(&video->pad);
+ remote = media_entity_remote_pad(&video->pad);
fmt.pad = remote->index;
ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
@@ -245,7 +245,7 @@
return -EPIPE;
/* Retrieve the source format */
- pad = media_entity_remote_source(pad);
+ pad = media_entity_remote_pad(pad);
if (pad == NULL ||
pad->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
break;
@@ -667,7 +667,7 @@
return -EINVAL;
}
/* get the remote pad */
- remote = media_entity_remote_source(&video->pad);
+ remote = media_entity_remote_pad(&video->pad);
if (remote == NULL) {
v4l2_err(&vpfe_dev->v4l2_dev,
"invalid remote pad for video node\n");
@@ -1614,7 +1614,7 @@
void vpfe_video_unregister(struct vpfe_video_device *video)
{
if (video_is_registered(&video->video_dev)) {
- media_entity_cleanup(&video->video_dev.entity);
video_unregister_device(&video->video_dev);
+ media_entity_cleanup(&video->video_dev.entity);
}
}
diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index c32e0ac..90d6ac4 100644
--- a/drivers/staging/media/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
@@ -829,7 +829,6 @@
.minor = -1,
.release = video_device_release,
.tvnorms = DT3155_CURRENT_NORM,
- .current_norm = DT3155_CURRENT_NORM,
};
/* same as in drivers/base/dma-coherent.c */
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 50066e0..46ed832 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -1124,7 +1124,7 @@
case GO7007_BOARDID_LIFEVIEW_LR192:
printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
"is not supported. Sorry!\n");
- return 0;
+ return -ENODEV;
name = "Lifeview TV Walker Ultra";
board = &board_lifeview_lr192;
break;
@@ -1140,7 +1140,7 @@
default:
printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
(unsigned int)id->driver_info);
- return 0;
+ return -ENODEV;
}
go = go7007_alloc(&board->main_info, &intf->dev);
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index 0a2c45d..4afa7da 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -911,8 +911,8 @@
if (retval) {
dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n",
__func__, retval);
- mutex_unlock(&context->ctx_lock);
- goto exit;
+ alloc_status = 8;
+ goto unlock;
}
usb_set_intfdata(interface, context);
@@ -937,6 +937,8 @@
alloc_status_switch:
switch (alloc_status) {
+ case 8:
+ lirc_unregister_driver(driver->minor);
case 7:
usb_free_urb(tx_urb);
case 6:
@@ -959,7 +961,6 @@
retval = 0;
}
-exit:
mutex_unlock(&driver_lock);
return retval;
diff --git a/drivers/staging/media/solo6x10/solo6x10-tw28.c b/drivers/staging/media/solo6x10/solo6x10-tw28.c
index ad00e2b..af65ea6 100644
--- a/drivers/staging/media/solo6x10/solo6x10-tw28.c
+++ b/drivers/staging/media/solo6x10/solo6x10-tw28.c
@@ -513,62 +513,82 @@
#define FIRST_ACTIVE_LINE 0x0008
#define LAST_ACTIVE_LINE 0x0102
-static void saa7128_setup(struct solo_dev *solo_dev)
+static void saa712x_write_regs(struct solo_dev *dev, const uint8_t *vals,
+ int start, int n)
{
- int i;
- unsigned char regs[128] = {
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ for (;start < n; start++, vals++) {
+ /* Skip read-only registers */
+ switch (start) {
+ /* case 0x00 ... 0x25: */
+ case 0x2e ... 0x37:
+ case 0x60:
+ case 0x7d:
+ continue;
+ }
+ solo_i2c_writebyte(dev, SOLO_I2C_SAA, 0x46, start, *vals);
+ }
+}
+
+#define SAA712x_reg7c (0x80 | ((LAST_ACTIVE_LINE & 0x100) >> 2) \
+ | ((FIRST_ACTIVE_LINE & 0x100) >> 4))
+
+static void saa712x_setup(struct solo_dev *dev)
+{
+ const int reg_start = 0x26;
+ const uint8_t saa7128_regs_ntsc[] = {
+ /* :0x26 */
+ 0x0d, 0x00,
+ /* :0x28 */
+ 0x59, 0x1d, 0x75, 0x3f, 0x06, 0x3f,
+ /* :0x2e XXX: read-only */
+ 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x1C, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
- 0x59, 0x1d, 0x75, 0x3f, 0x06, 0x3f, 0x00, 0x00,
- 0x1c, 0x33, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00,
+ /* :0x38 */
0x1a, 0x1a, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* :0x40 */
0x00, 0x00, 0x00, 0x68, 0x10, 0x97, 0x4c, 0x18,
0x9b, 0x93, 0x9f, 0xff, 0x7c, 0x34, 0x3f, 0x3f,
+ /* :0x50 */
0x3f, 0x83, 0x83, 0x80, 0x0d, 0x0f, 0xc3, 0x06,
0x02, 0x80, 0x71, 0x77, 0xa7, 0x67, 0x66, 0x2e,
+ /* :0x60 */
0x7b, 0x11, 0x4f, 0x1f, 0x7c, 0xf0, 0x21, 0x77,
- 0x41, 0x88, 0x41, 0x12, 0xed, 0x10, 0x10, 0x00,
+ 0x41, 0x88, 0x41, 0x52, 0xed, 0x10, 0x10, 0x00,
+ /* :0x70 */
0x41, 0xc3, 0x00, 0x3e, 0xb8, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x08, 0xff, 0x80, 0x00, 0xff, 0xff,
+ 0x00, 0x00, FIRST_ACTIVE_LINE, LAST_ACTIVE_LINE & 0xff,
+ SAA712x_reg7c, 0x00, 0xff, 0xff,
+ }, saa7128_regs_pal[] = {
+ /* :0x26 */
+ 0x0d, 0x00,
+ /* :0x28 */
+ 0xe1, 0x1d, 0x75, 0x3f, 0x06, 0x3f,
+ /* :0x2e XXX: read-only */
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* :0x38 */
+ 0x1a, 0x1a, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* :0x40 */
+ 0x00, 0x00, 0x00, 0x68, 0x10, 0x97, 0x4c, 0x18,
+ 0x9b, 0x93, 0x9f, 0xff, 0x7c, 0x34, 0x3f, 0x3f,
+ /* :0x50 */
+ 0x3f, 0x83, 0x83, 0x80, 0x0d, 0x0f, 0xc3, 0x06,
+ 0x02, 0x80, 0x0f, 0x77, 0xa7, 0x67, 0x66, 0x2e,
+ /* :0x60 */
+ 0x7b, 0x02, 0x35, 0xcb, 0x8a, 0x09, 0x2a, 0x77,
+ 0x41, 0x88, 0x41, 0x52, 0xf1, 0x10, 0x20, 0x00,
+ /* :0x70 */
+ 0x41, 0xc3, 0x00, 0x3e, 0xb8, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x12, 0x30,
+ SAA712x_reg7c | 0x40, 0x00, 0xff, 0xff,
};
- regs[0x7A] = FIRST_ACTIVE_LINE & 0xff;
- regs[0x7B] = LAST_ACTIVE_LINE & 0xff;
- regs[0x7C] = ((1 << 7) |
- (((LAST_ACTIVE_LINE >> 8) & 1) << 6) |
- (((FIRST_ACTIVE_LINE >> 8) & 1) << 4));
-
- /* PAL: XXX: We could do a second set of regs to avoid this */
- if (solo_dev->video_type != SOLO_VO_FMT_TYPE_NTSC) {
- regs[0x28] = 0xE1;
-
- regs[0x5A] = 0x0F;
- regs[0x61] = 0x02;
- regs[0x62] = 0x35;
- regs[0x63] = 0xCB;
- regs[0x64] = 0x8A;
- regs[0x65] = 0x09;
- regs[0x66] = 0x2A;
-
- regs[0x6C] = 0xf1;
- regs[0x6E] = 0x20;
-
- regs[0x7A] = 0x06 + 12;
- regs[0x7b] = 0x24 + 12;
- regs[0x7c] |= 1 << 6;
- }
-
- /* First 0x25 bytes are read-only? */
- for (i = 0x26; i < 128; i++) {
- if (i == 0x60 || i == 0x7D)
- continue;
- solo_i2c_writebyte(solo_dev, SOLO_I2C_SAA, 0x46, i, regs[i]);
- }
-
- return;
+ if (dev->video_type == SOLO_VO_FMT_TYPE_PAL)
+ saa712x_write_regs(dev, saa7128_regs_pal, reg_start,
+ sizeof(saa7128_regs_pal));
+ else
+ saa712x_write_regs(dev, saa7128_regs_ntsc, reg_start,
+ sizeof(saa7128_regs_ntsc));
}
int solo_tw28_init(struct solo_dev *solo_dev)
@@ -609,7 +629,7 @@
return -EINVAL;
}
- saa7128_setup(solo_dev);
+ saa712x_setup(solo_dev);
for (i = 0; i < solo_dev->tw28_cnt; i++) {
if ((solo_dev->tw2865 & (1 << i)))
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
index 98e2902..a4c5896 100644
--- a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
@@ -996,12 +996,11 @@
struct v4l2_streamparm *sp)
{
struct solo_enc_dev *solo_enc = video_drvdata(file);
- struct solo_dev *solo_dev = solo_enc->solo_dev;
struct v4l2_captureparm *cp = &sp->parm.capture;
cp->capability = V4L2_CAP_TIMEPERFRAME;
cp->timeperframe.numerator = solo_enc->interval;
- cp->timeperframe.denominator = solo_dev->fps;
+ cp->timeperframe.denominator = solo_enc->solo_dev->fps;
cp->capturemode = 0;
/* XXX: Shouldn't we be able to get/set this from videobuf? */
cp->readbuffers = 2;
@@ -1009,36 +1008,29 @@
return 0;
}
+static inline int calc_interval(u8 fps, u32 n, u32 d)
+{
+ if (!n || !d)
+ return 1;
+ if (d == fps)
+ return n;
+ n *= fps;
+ return min(15U, n / d + (n % d >= (fps >> 1)));
+}
+
static int solo_s_parm(struct file *file, void *priv,
struct v4l2_streamparm *sp)
{
struct solo_enc_dev *solo_enc = video_drvdata(file);
- struct solo_dev *solo_dev = solo_enc->solo_dev;
- struct v4l2_captureparm *cp = &sp->parm.capture;
+ struct v4l2_fract *t = &sp->parm.capture.timeperframe;
+ u8 fps = solo_enc->solo_dev->fps;
if (vb2_is_streaming(&solo_enc->vidq))
return -EBUSY;
- if ((cp->timeperframe.numerator == 0) ||
- (cp->timeperframe.denominator == 0)) {
- /* reset framerate */
- cp->timeperframe.numerator = 1;
- cp->timeperframe.denominator = solo_dev->fps;
- }
-
- if (cp->timeperframe.denominator != solo_dev->fps)
- cp->timeperframe.denominator = solo_dev->fps;
-
- if (cp->timeperframe.numerator > 15)
- cp->timeperframe.numerator = 15;
-
- solo_enc->interval = cp->timeperframe.numerator;
-
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->readbuffers = 2;
-
+ solo_enc->interval = calc_interval(fps, t->numerator, t->denominator);
solo_update_mode(solo_enc);
- return 0;
+ return solo_g_parm(file, priv, sp);
}
static long solo_enc_default(struct file *file, void *fh,
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index 5f91c7a..e2a1f50 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -406,7 +406,7 @@
if (video == NULL)
return -ENOMEM;
- video->parent = &cdev->gadget->dev;
+ video->v4l2_dev = &uvc->v4l2_dev;
video->fops = &uvc_v4l2_fops;
video->release = video_device_release;
strlcpy(video->name, cdev->gadget->name, sizeof(video->name));
@@ -563,6 +563,7 @@
INFO(cdev, "uvc_function_unbind\n");
video_unregister_device(uvc->vdev);
+ v4l2_device_unregister(&uvc->v4l2_dev);
uvc->control_ep->driver_data = NULL;
uvc->video.ep->driver_data = NULL;
@@ -690,6 +691,11 @@
if ((ret = usb_function_deactivate(f)) < 0)
goto error;
+ if (v4l2_device_register(&cdev->gadget->dev, &uvc->v4l2_dev)) {
+ printk(KERN_INFO "v4l2_device_register failed\n");
+ goto error;
+ }
+
/* Initialise video. */
ret = uvc_video_init(&uvc->video);
if (ret < 0)
@@ -705,6 +711,7 @@
return 0;
error:
+ v4l2_device_unregister(&uvc->v4l2_dev);
if (uvc->vdev)
video_device_release(uvc->vdev);
diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h
index 817e9e1..7a9111d 100644
--- a/drivers/usb/gadget/uvc.h
+++ b/drivers/usb/gadget/uvc.h
@@ -57,6 +57,7 @@
#include <linux/videodev2.h>
#include <linux/version.h>
#include <media/v4l2-fh.h>
+#include <media/v4l2-device.h>
#include "uvc_queue.h"
@@ -145,6 +146,7 @@
struct uvc_device
{
struct video_device *vdev;
+ struct v4l2_device v4l2_dev;
enum uvc_state state;
struct usb_function func;
struct uvc_video video;
diff --git a/include/media/davinci/vpbe_osd.h b/include/media/davinci/vpbe_osd.h
index 42628fc..de59364 100644
--- a/include/media/davinci/vpbe_osd.h
+++ b/include/media/davinci/vpbe_osd.h
@@ -82,9 +82,9 @@
PIXFMT_4BPP,
PIXFMT_8BPP,
PIXFMT_RGB565,
- PIXFMT_YCbCrI,
+ PIXFMT_YCBCRI,
PIXFMT_RGB888,
- PIXFMT_YCrCbI,
+ PIXFMT_YCRCBI,
PIXFMT_NV12,
PIXFMT_OSD_ATTR,
};
diff --git a/include/media/media-device.h b/include/media/media-device.h
index eaade98..12155a9 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -45,6 +45,7 @@
* @entities: List of registered entities
* @lock: Entities list lock
* @graph_mutex: Entities graph operation lock
+ * @link_notify: Link state change notification callback
*
* This structure represents an abstract high-level media device. It allows easy
* access to entities and provides basic media device-level support. The
@@ -75,10 +76,14 @@
/* Serializes graph operations. */
struct mutex graph_mutex;
- int (*link_notify)(struct media_pad *source,
- struct media_pad *sink, u32 flags);
+ int (*link_notify)(struct media_link *link, u32 flags,
+ unsigned int notification);
};
+/* Supported link_notify @notification values. */
+#define MEDIA_DEV_NOTIFY_PRE_LINK_CH 0
+#define MEDIA_DEV_NOTIFY_POST_LINK_CH 1
+
/* media_devnode to media_device */
#define to_media_device(node) container_of(node, struct media_device, devnode)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 0c16f51..06bacf9 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -128,11 +128,14 @@
int media_entity_create_link(struct media_entity *source, u16 source_pad,
struct media_entity *sink, u16 sink_pad, u32 flags);
+void __media_entity_remove_links(struct media_entity *entity);
+void media_entity_remove_links(struct media_entity *entity);
+
int __media_entity_setup_link(struct media_link *link, u32 flags);
int media_entity_setup_link(struct media_link *link, u32 flags);
struct media_link *media_entity_find_link(struct media_pad *source,
struct media_pad *sink);
-struct media_pad *media_entity_remote_source(struct media_pad *pad);
+struct media_pad *media_entity_remote_pad(struct media_pad *pad);
struct media_entity *media_entity_get(struct media_entity *entity);
void media_entity_put(struct media_entity *entity);
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 5d5d3a3..6628f5d 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -111,6 +111,7 @@
#define RC_MAP_BUDGET_CI_OLD "rc-budget-ci-old"
#define RC_MAP_CINERGY_1400 "rc-cinergy-1400"
#define RC_MAP_CINERGY "rc-cinergy"
+#define RC_MAP_DELOCK_61959 "rc-delock-61959"
#define RC_MAP_DIB0700_NEC_TABLE "rc-dib0700-nec"
#define RC_MAP_DIB0700_RC5_TABLE "rc-dib0700-rc5"
#define RC_MAP_DIGITALNOW_TINYTWIN "rc-digitalnow-tinytwin"
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
index f509690..b975c28 100644
--- a/include/media/s5p_fimc.h
+++ b/include/media/s5p_fimc.h
@@ -13,6 +13,7 @@
#define S5P_FIMC_H_
#include <media/media-entity.h>
+#include <media/v4l2-dev.h>
#include <media/v4l2-mediabus.h>
/*
@@ -115,6 +116,7 @@
* @color: the driver's private color format id
* @memplanes: number of physically non-contiguous data planes
* @colplanes: number of physically contiguous data planes
+ * @colorspace: v4l2 colorspace (V4L2_COLORSPACE_*)
* @depth: per plane driver's private 'number of bits per pixel'
* @mdataplanes: bitmask indicating meta data plane(s), (1 << plane_no)
* @flags: flags indicating which operation mode format applies to
@@ -126,6 +128,7 @@
u32 color;
u16 memplanes;
u16 colplanes;
+ u8 colorspace;
u8 depth[FIMC_MAX_PLANES];
u16 mdataplanes;
u16 flags;
@@ -140,37 +143,40 @@
#define FMT_FLAGS_YUV (1 << 7)
};
-enum fimc_subdev_index {
- IDX_SENSOR,
- IDX_CSIS,
- IDX_FLITE,
- IDX_IS_ISP,
- IDX_FIMC,
- IDX_MAX,
-};
-
-struct media_pipeline;
-struct v4l2_subdev;
-
-struct fimc_pipeline {
- struct v4l2_subdev *subdevs[IDX_MAX];
- struct media_pipeline *m_pipeline;
-};
+struct exynos_media_pipeline;
/*
- * Media pipeline operations to be called from within the fimc(-lite)
- * video node when it is the last entity of the pipeline. Implemented
- * by corresponding media device driver.
+ * Media pipeline operations to be called from within a video node, i.e. the
+ * last entity within the pipeline. Implemented by related media device driver.
*/
-struct fimc_pipeline_ops {
- int (*open)(struct fimc_pipeline *p, struct media_entity *me,
- bool resume);
- int (*close)(struct fimc_pipeline *p);
- int (*set_stream)(struct fimc_pipeline *p, bool state);
+struct exynos_media_pipeline_ops {
+ int (*prepare)(struct exynos_media_pipeline *p,
+ struct media_entity *me);
+ int (*unprepare)(struct exynos_media_pipeline *p);
+ int (*open)(struct exynos_media_pipeline *p, struct media_entity *me,
+ bool resume);
+ int (*close)(struct exynos_media_pipeline *p);
+ int (*set_stream)(struct exynos_media_pipeline *p, bool state);
};
-#define fimc_pipeline_call(f, op, p, args...) \
- (!(f) ? -ENODEV : (((f)->pipeline_ops && (f)->pipeline_ops->op) ? \
- (f)->pipeline_ops->op((p), ##args) : -ENOIOCTLCMD))
+struct exynos_video_entity {
+ struct video_device vdev;
+ struct exynos_media_pipeline *pipe;
+};
+
+struct exynos_media_pipeline {
+ struct media_pipeline mp;
+ const struct exynos_media_pipeline_ops *ops;
+};
+
+static inline struct exynos_video_entity *vdev_to_exynos_video_entity(
+ struct video_device *vdev)
+{
+ return container_of(vdev, struct exynos_video_entity, vdev);
+}
+
+#define fimc_pipeline_call(ent, op, args...) \
+ (!(ent) ? -ENOENT : (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
+ (ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD)) \
#endif /* S5P_FIMC_H_ */
diff --git a/include/media/sh_mobile_ceu.h b/include/media/sh_mobile_ceu.h
index 6fdb6ad..7f57056 100644
--- a/include/media/sh_mobile_ceu.h
+++ b/include/media/sh_mobile_ceu.h
@@ -22,6 +22,8 @@
int max_width;
int max_height;
struct sh_mobile_ceu_companion *csi2;
+ struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */
+ unsigned int *asd_sizes; /* 0-terminated array pf asd group sizes */
};
#endif /* __ASM_SH_MOBILE_CEU_H__ */
diff --git a/include/media/sh_mobile_csi2.h b/include/media/sh_mobile_csi2.h
index c586c4f..14030db 100644
--- a/include/media/sh_mobile_csi2.h
+++ b/include/media/sh_mobile_csi2.h
@@ -33,6 +33,7 @@
unsigned char lanes; /* bitmask[3:0] */
unsigned char channel; /* 0..3 */
struct platform_device *pdev; /* client platform device */
+ const char *name; /* async matching: client name */
};
struct v4l2_device;
@@ -42,7 +43,6 @@
unsigned int flags;
struct sh_csi2_client_config *clients;
int num_clients;
- struct v4l2_device *v4l2_dev;
};
#endif
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index ff77d08..34d2414 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -19,11 +19,13 @@
#include <linux/videodev2.h>
#include <media/videobuf-core.h>
#include <media/videobuf2-core.h>
+#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
struct file;
struct soc_camera_desc;
+struct soc_camera_async_client;
struct soc_camera_device {
struct list_head list; /* list of all registered devices */
@@ -49,6 +51,10 @@
/* soc_camera.c private count. Only accessed with .host_lock held */
int use_count;
struct file *streamer; /* stream owner */
+ struct v4l2_clk *clk;
+ /* Asynchronous subdevice management */
+ struct soc_camera_async_client *sasc;
+ /* video buffer queue */
union {
struct videobuf_queue vb_vidq;
struct vb2_queue vb2_vidq;
@@ -58,21 +64,38 @@
/* Host supports programmable stride */
#define SOCAM_HOST_CAP_STRIDE (1 << 0)
+enum soc_camera_subdev_role {
+ SOCAM_SUBDEV_DATA_SOURCE = 1,
+ SOCAM_SUBDEV_DATA_SINK,
+ SOCAM_SUBDEV_DATA_PROCESSOR,
+};
+
+struct soc_camera_async_subdev {
+ struct v4l2_async_subdev asd;
+ enum soc_camera_subdev_role role;
+};
+
struct soc_camera_host {
struct v4l2_device v4l2_dev;
struct list_head list;
- struct mutex host_lock; /* Protect pipeline modifications */
+ struct mutex host_lock; /* Main synchronisation lock */
+ struct mutex clk_lock; /* Protect pipeline modifications */
unsigned char nr; /* Host number */
u32 capabilities;
+ struct soc_camera_device *icd; /* Currently attached client */
void *priv;
const char *drv_name;
struct soc_camera_host_ops *ops;
+ struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */
+ unsigned int *asd_sizes; /* 0-terminated array of asd group sizes */
};
struct soc_camera_host_ops {
struct module *owner;
int (*add)(struct soc_camera_device *);
void (*remove)(struct soc_camera_device *);
+ int (*clock_start)(struct soc_camera_host *);
+ void (*clock_stop)(struct soc_camera_host *);
/*
* .get_formats() is called for each client device format, but
* .put_formats() is only called once. Further, if any of the calls to
@@ -157,6 +180,7 @@
};
/*
+ * Platform data for "soc-camera-pdrv"
* This MUST be kept binary-identical to struct soc_camera_link below, until
* it is completely replaced by this one, after which we can split it into its
* two components.
@@ -322,14 +346,17 @@
unsigned long soc_camera_apply_board_flags(struct soc_camera_subdev_desc *ssdd,
const struct v4l2_mbus_config *cfg);
-int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd);
-int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd);
+int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd);
+int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+ struct v4l2_clk *clk);
+int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+ struct v4l2_clk *clk);
static inline int soc_camera_set_power(struct device *dev,
- struct soc_camera_subdev_desc *ssdd, bool on)
+ struct soc_camera_subdev_desc *ssdd, struct v4l2_clk *clk, bool on)
{
- return on ? soc_camera_power_on(dev, ssdd)
- : soc_camera_power_off(dev, ssdd);
+ return on ? soc_camera_power_on(dev, ssdd, clk)
+ : soc_camera_power_off(dev, ssdd, clk);
}
/* This is only temporary here - until v4l2-subdev begins to link to video_device */
@@ -346,9 +373,9 @@
return client->dev.platform_data;
}
-static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(const struct video_device *vdev)
+static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(struct video_device *vdev)
{
- struct soc_camera_device *icd = dev_get_drvdata(vdev->parent);
+ struct soc_camera_device *icd = video_get_drvdata(vdev);
return soc_camera_to_subdev(icd);
}
diff --git a/include/media/ths7303.h b/include/media/ths7303.h
index 980ec51..a7b4929 100644
--- a/include/media/ths7303.h
+++ b/include/media/ths7303.h
@@ -30,13 +30,11 @@
* @ch_1: Bias value for channel one.
* @ch_2: Bias value for channel two.
* @ch_3: Bias value for channel three.
- * @init_enable: initalize on init.
*/
struct ths7303_platform_data {
u8 ch_1;
u8 ch_2;
u8 ch_3;
- u8 init_enable;
};
#endif
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
index a8ad75a..4a1191a 100644
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -1,6 +1,17 @@
/*
*/
+enum tveeprom_audio_processor {
+ /* No audio processor present */
+ TVEEPROM_AUDPROC_NONE,
+ /* The audio processor is internal to the video processor */
+ TVEEPROM_AUDPROC_INTERNAL,
+ /* The audio processor is a MSPXXXX device */
+ TVEEPROM_AUDPROC_MSP,
+ /* The audio processor is another device */
+ TVEEPROM_AUDPROC_OTHER,
+};
+
struct tveeprom {
u32 has_radio;
/* If has_ir == 0, then it is unknown what the IR capabilities are,
diff --git a/include/media/tvp7002.h b/include/media/tvp7002.h
index ee43534..fadb6af 100644
--- a/include/media/tvp7002.h
+++ b/include/media/tvp7002.h
@@ -26,31 +26,29 @@
#ifndef _TVP7002_H_
#define _TVP7002_H_
-/* Platform-dependent data
- *
- * clk_polarity:
- * 0 -> data clocked out on rising edge of DATACLK signal
- * 1 -> data clocked out on falling edge of DATACLK signal
- * hs_polarity:
- * 0 -> active low HSYNC output
- * 1 -> active high HSYNC output
- * sog_polarity:
- * 0 -> normal operation
- * 1 -> operation with polarity inverted
- * vs_polarity:
- * 0 -> active low VSYNC output
- * 1 -> active high VSYNC output
- * fid_polarity:
- * 0 -> the field ID output is set to logic 1 for an odd
- * field (field 1) and set to logic 0 for an even
- * field (field 0).
- * 1 -> operation with polarity inverted.
+#define TVP7002_MODULE_NAME "tvp7002"
+
+/**
+ * struct tvp7002_config - Platform dependent data
+ *@clk_polarity: Clock polarity
+ * 0 - Data clocked out on rising edge of DATACLK signal
+ * 1 - Data clocked out on falling edge of DATACLK signal
+ *@hs_polarity: HSYNC polarity
+ * 0 - Active low HSYNC output, 1 - Active high HSYNC output
+ *@vs_polarity: VSYNC Polarity
+ * 0 - Active low VSYNC output, 1 - Active high VSYNC output
+ *@fid_polarity: Active-high Field ID polarity.
+ * 0 - The field ID output is set to logic 1 for an odd field
+ * (field 1) and set to logic 0 for an even field (field 0).
+ * 1 - Operation with polarity inverted.
+ *@sog_polarity: Active high Sync on Green output polarity.
+ * 0 - Normal operation, 1 - Operation with polarity inverted
*/
struct tvp7002_config {
- u8 clk_polarity;
- u8 hs_polarity;
- u8 vs_polarity;
- u8 fid_polarity;
- u8 sog_polarity;
+ bool clk_polarity;
+ bool hs_polarity;
+ bool vs_polarity;
+ bool fid_polarity;
+ bool sog_polarity;
};
#endif
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
new file mode 100644
index 0000000..c3ec6ac
--- /dev/null
+++ b/include/media/v4l2-async.h
@@ -0,0 +1,105 @@
+/*
+ * V4L2 asynchronous subdevice registration API
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef V4L2_ASYNC_H
+#define V4L2_ASYNC_H
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+struct device;
+struct v4l2_device;
+struct v4l2_subdev;
+struct v4l2_async_notifier;
+
+/* A random max subdevice number, used to allocate an array on stack */
+#define V4L2_MAX_SUBDEVS 128U
+
+enum v4l2_async_bus_type {
+ V4L2_ASYNC_BUS_CUSTOM,
+ V4L2_ASYNC_BUS_PLATFORM,
+ V4L2_ASYNC_BUS_I2C,
+};
+
+/**
+ * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
+ * @bus_type: subdevice bus type to select the appropriate matching method
+ * @match: union of per-bus type matching data sets
+ * @list: used to link struct v4l2_async_subdev objects, waiting to be
+ * probed, to a notifier->waiting list
+ */
+struct v4l2_async_subdev {
+ enum v4l2_async_bus_type bus_type;
+ union {
+ struct {
+ const char *name;
+ } platform;
+ struct {
+ int adapter_id;
+ unsigned short address;
+ } i2c;
+ struct {
+ bool (*match)(struct device *,
+ struct v4l2_async_subdev *);
+ void *priv;
+ } custom;
+ } match;
+
+ /* v4l2-async core private: not to be used by drivers */
+ struct list_head list;
+};
+
+/**
+ * v4l2_async_subdev_list - provided by subdevices
+ * @list: links struct v4l2_async_subdev_list objects to a global list
+ * before probing, and onto notifier->done after probing
+ * @asd: pointer to respective struct v4l2_async_subdev
+ * @notifier: pointer to managing notifier
+ */
+struct v4l2_async_subdev_list {
+ struct list_head list;
+ struct v4l2_async_subdev *asd;
+ struct v4l2_async_notifier *notifier;
+};
+
+/**
+ * v4l2_async_notifier - v4l2_device notifier data
+ * @num_subdevs:number of subdevices
+ * @subdev: array of pointers to subdevice descriptors
+ * @v4l2_dev: pointer to struct v4l2_device
+ * @waiting: list of struct v4l2_async_subdev, waiting for their drivers
+ * @done: list of struct v4l2_async_subdev_list, already probed
+ * @list: member in a global list of notifiers
+ * @bound: a subdevice driver has successfully probed one of subdevices
+ * @complete: all subdevices have been probed successfully
+ * @unbind: a subdevice is leaving
+ */
+struct v4l2_async_notifier {
+ unsigned int num_subdevs;
+ struct v4l2_async_subdev **subdev;
+ struct v4l2_device *v4l2_dev;
+ struct list_head waiting;
+ struct list_head done;
+ struct list_head list;
+ int (*bound)(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd);
+ int (*complete)(struct v4l2_async_notifier *notifier);
+ void (*unbind)(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd);
+};
+
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+ struct v4l2_async_notifier *notifier);
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
+int v4l2_async_register_subdev(struct v4l2_subdev *sd);
+void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
+#endif
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
deleted file mode 100644
index c259b36..0000000
--- a/include/media/v4l2-chip-ident.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- v4l2 chip identifiers header
-
- This header provides a list of chip identifiers that can be returned
- through the VIDIOC_DBG_G_CHIP_IDENT ioctl.
-
- Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef V4L2_CHIP_IDENT_H_
-#define V4L2_CHIP_IDENT_H_
-
-/* VIDIOC_DBG_G_CHIP_IDENT: identifies the actual chip installed on the board */
-
-/* KEEP THIS LIST ORDERED BY ID!
- Otherwise it will be hard to see which ranges are already in use when
- adding support to a new chip family. */
-enum {
- /* general idents: reserved range 0-49 */
- V4L2_IDENT_NONE = 0, /* No chip matched */
- V4L2_IDENT_AMBIGUOUS = 1, /* Match too general, multiple chips matched */
- V4L2_IDENT_UNKNOWN = 2, /* Chip found, but cannot identify */
-
- /* module tvaudio: reserved range 50-99 */
- V4L2_IDENT_TVAUDIO = 50, /* A tvaudio chip, unknown which it is exactly */
-
- /* Sony IMX074 */
- V4L2_IDENT_IMX074 = 74,
-
- /* module saa7110: just ident 100 */
- V4L2_IDENT_SAA7110 = 100,
-
- /* module saa7115: reserved range 101-149 */
- V4L2_IDENT_SAA7111 = 101,
- V4L2_IDENT_SAA7111A = 102,
- V4L2_IDENT_SAA7113 = 103,
- V4L2_IDENT_SAA7114 = 104,
- V4L2_IDENT_SAA7115 = 105,
- V4L2_IDENT_SAA7118 = 108,
-
- /* module saa7127: reserved range 150-199 */
- V4L2_IDENT_SAA7127 = 157,
- V4L2_IDENT_SAA7129 = 159,
-
- /* module cx25840: reserved range 200-249 */
- V4L2_IDENT_CX25836 = 236,
- V4L2_IDENT_CX25837 = 237,
- V4L2_IDENT_CX25840 = 240,
- V4L2_IDENT_CX25841 = 241,
- V4L2_IDENT_CX25842 = 242,
- V4L2_IDENT_CX25843 = 243,
-
- /* OmniVision sensors: reserved range 250-299 */
- V4L2_IDENT_OV7670 = 250,
- V4L2_IDENT_OV7720 = 251,
- V4L2_IDENT_OV7725 = 252,
- V4L2_IDENT_OV7660 = 253,
- V4L2_IDENT_OV9650 = 254,
- V4L2_IDENT_OV9655 = 255,
- V4L2_IDENT_SOI968 = 256,
- V4L2_IDENT_OV9640 = 257,
- V4L2_IDENT_OV6650 = 258,
- V4L2_IDENT_OV2640 = 259,
- V4L2_IDENT_OV9740 = 260,
- V4L2_IDENT_OV5642 = 261,
-
- /* module saa7146: reserved range 300-309 */
- V4L2_IDENT_SAA7146 = 300,
-
- /* Conexant MPEG encoder/decoders: reserved range 400-420 */
- V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */
- V4L2_IDENT_CX23415 = 415,
- V4L2_IDENT_CX23416 = 416,
- V4L2_IDENT_CX23417 = 417,
- V4L2_IDENT_CX23418 = 418,
-
- /* module bt819: reserved range 810-819 */
- V4L2_IDENT_BT815A = 815,
- V4L2_IDENT_BT817A = 817,
- V4L2_IDENT_BT819A = 819,
-
- /* module au0828 */
- V4L2_IDENT_AU0828 = 828,
-
- /* module bttv: ident 848 + 849 */
- V4L2_IDENT_BT848 = 848,
- V4L2_IDENT_BT849 = 849,
-
- /* module bt856: just ident 856 */
- V4L2_IDENT_BT856 = 856,
-
- /* module bt866: just ident 866 */
- V4L2_IDENT_BT866 = 866,
-
- /* module bttv: ident 878 + 879 */
- V4L2_IDENT_BT878 = 878,
- V4L2_IDENT_BT879 = 879,
-
- /* module ks0127: reserved range 1120-1129 */
- V4L2_IDENT_KS0122S = 1122,
- V4L2_IDENT_KS0127 = 1127,
- V4L2_IDENT_KS0127B = 1128,
-
- /* module indycam: just ident 2000 */
- V4L2_IDENT_INDYCAM = 2000,
-
- /* module vp27smpx: just ident 2700 */
- V4L2_IDENT_VP27SMPX = 2700,
-
- /* module vpx3220: reserved range: 3210-3229 */
- V4L2_IDENT_VPX3214C = 3214,
- V4L2_IDENT_VPX3216B = 3216,
- V4L2_IDENT_VPX3220A = 3220,
-
- /* VX855 just ident 3409 */
- /* Other via devs could use 3314, 3324, 3327, 3336, 3364, 3353 */
- V4L2_IDENT_VIA_VX855 = 3409,
-
- /* module tvp5150 */
- V4L2_IDENT_TVP5150 = 5150,
-
- /* module saa5246a: just ident 5246 */
- V4L2_IDENT_SAA5246A = 5246,
-
- /* module saa5249: just ident 5249 */
- V4L2_IDENT_SAA5249 = 5249,
-
- /* module cs5345: just ident 5345 */
- V4L2_IDENT_CS5345 = 5345,
-
- /* module tea6415c: just ident 6415 */
- V4L2_IDENT_TEA6415C = 6415,
-
- /* module tea6420: just ident 6420 */
- V4L2_IDENT_TEA6420 = 6420,
-
- /* module saa6588: just ident 6588 */
- V4L2_IDENT_SAA6588 = 6588,
-
- /* module vs6624: just ident 6624 */
- V4L2_IDENT_VS6624 = 6624,
-
- /* module saa6752hs: reserved range 6750-6759 */
- V4L2_IDENT_SAA6752HS = 6752,
- V4L2_IDENT_SAA6752HS_AC3 = 6753,
-
- /* modules tef6862: just ident 6862 */
- V4L2_IDENT_TEF6862 = 6862,
-
- /* module tvp7002: just ident 7002 */
- V4L2_IDENT_TVP7002 = 7002,
-
- /* module adv7170: just ident 7170 */
- V4L2_IDENT_ADV7170 = 7170,
-
- /* module adv7175: just ident 7175 */
- V4L2_IDENT_ADV7175 = 7175,
-
- /* module adv7180: just ident 7180 */
- V4L2_IDENT_ADV7180 = 7180,
-
- /* module adv7183: just ident 7183 */
- V4L2_IDENT_ADV7183 = 7183,
-
- /* module saa7185: just ident 7185 */
- V4L2_IDENT_SAA7185 = 7185,
-
- /* module saa7191: just ident 7191 */
- V4L2_IDENT_SAA7191 = 7191,
-
- /* module ths7303: just ident 7303 */
- V4L2_IDENT_THS7303 = 7303,
-
- /* module adv7343: just ident 7343 */
- V4L2_IDENT_ADV7343 = 7343,
-
- /* module ths7353: just ident 7353 */
- V4L2_IDENT_THS7353 = 7353,
-
- /* module adv7393: just ident 7393 */
- V4L2_IDENT_ADV7393 = 7393,
-
- /* module adv7604: just ident 7604 */
- V4L2_IDENT_ADV7604 = 7604,
-
- /* module saa7706h: just ident 7706 */
- V4L2_IDENT_SAA7706H = 7706,
-
- /* module mt9v011, just ident 8243 */
- V4L2_IDENT_MT9V011 = 8243,
-
- /* module wm8739: just ident 8739 */
- V4L2_IDENT_WM8739 = 8739,
-
- /* module wm8775: just ident 8775 */
- V4L2_IDENT_WM8775 = 8775,
-
- /* Marvell controllers starting at 8801 */
- V4L2_IDENT_CAFE = 8801,
- V4L2_IDENT_ARMADA610 = 8802,
-
- /* AKM AK8813/AK8814 */
- V4L2_IDENT_AK8813 = 8813,
- V4L2_IDENT_AK8814 = 8814,
-
- /* module cx23885 and cx25840 */
- V4L2_IDENT_CX23885 = 8850,
- V4L2_IDENT_CX23885_AV = 8851, /* Integrated A/V decoder */
- V4L2_IDENT_CX23887 = 8870,
- V4L2_IDENT_CX23887_AV = 8871, /* Integrated A/V decoder */
- V4L2_IDENT_CX23888 = 8880,
- V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */
- V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */
-
- /* module ad9389b: just ident 9389 */
- V4L2_IDENT_AD9389B = 9389,
-
- /* module tda9840: just ident 9840 */
- V4L2_IDENT_TDA9840 = 9840,
-
- /* module tw9910: just ident 9910 */
- V4L2_IDENT_TW9910 = 9910,
-
- /* module sn9c20x: just ident 10000 */
- V4L2_IDENT_SN9C20X = 10000,
-
- /* module cx231xx and cx25840 */
- V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */
- V4L2_IDENT_CX23100 = 23100,
- V4L2_IDENT_CX23101 = 23101,
- V4L2_IDENT_CX23102 = 23102,
-
- /* module msp3400: reserved range 34000-34999 for msp34xx */
- V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only
- use internally (tveeprom.c). */
-
- V4L2_IDENT_MSP3400B = 34002,
- V4L2_IDENT_MSP3400C = 34003,
- V4L2_IDENT_MSP3400D = 34004,
- V4L2_IDENT_MSP3400G = 34007,
- V4L2_IDENT_MSP3401G = 34017,
- V4L2_IDENT_MSP3402G = 34027,
- V4L2_IDENT_MSP3405D = 34054,
- V4L2_IDENT_MSP3405G = 34057,
- V4L2_IDENT_MSP3407D = 34074,
- V4L2_IDENT_MSP3407G = 34077,
-
- V4L2_IDENT_MSP3410B = 34102,
- V4L2_IDENT_MSP3410C = 34103,
- V4L2_IDENT_MSP3410D = 34104,
- V4L2_IDENT_MSP3410G = 34107,
- V4L2_IDENT_MSP3411G = 34117,
- V4L2_IDENT_MSP3412G = 34127,
- V4L2_IDENT_MSP3415D = 34154,
- V4L2_IDENT_MSP3415G = 34157,
- V4L2_IDENT_MSP3417D = 34174,
- V4L2_IDENT_MSP3417G = 34177,
-
- V4L2_IDENT_MSP3420G = 34207,
- V4L2_IDENT_MSP3421G = 34217,
- V4L2_IDENT_MSP3422G = 34227,
- V4L2_IDENT_MSP3425G = 34257,
- V4L2_IDENT_MSP3427G = 34277,
-
- V4L2_IDENT_MSP3430G = 34307,
- V4L2_IDENT_MSP3431G = 34317,
- V4L2_IDENT_MSP3435G = 34357,
- V4L2_IDENT_MSP3437G = 34377,
-
- V4L2_IDENT_MSP3440G = 34407,
- V4L2_IDENT_MSP3441G = 34417,
- V4L2_IDENT_MSP3442G = 34427,
- V4L2_IDENT_MSP3445G = 34457,
- V4L2_IDENT_MSP3447G = 34477,
-
- V4L2_IDENT_MSP3450G = 34507,
- V4L2_IDENT_MSP3451G = 34517,
- V4L2_IDENT_MSP3452G = 34527,
- V4L2_IDENT_MSP3455G = 34557,
- V4L2_IDENT_MSP3457G = 34577,
-
- V4L2_IDENT_MSP3460G = 34607,
- V4L2_IDENT_MSP3461G = 34617,
- V4L2_IDENT_MSP3465G = 34657,
- V4L2_IDENT_MSP3467G = 34677,
-
- /* module msp3400: reserved range 44000-44999 for msp44xx */
- V4L2_IDENT_MSP4400G = 44007,
- V4L2_IDENT_MSP4408G = 44087,
- V4L2_IDENT_MSP4410G = 44107,
- V4L2_IDENT_MSP4418G = 44187,
- V4L2_IDENT_MSP4420G = 44207,
- V4L2_IDENT_MSP4428G = 44287,
- V4L2_IDENT_MSP4440G = 44407,
- V4L2_IDENT_MSP4448G = 44487,
- V4L2_IDENT_MSP4450G = 44507,
- V4L2_IDENT_MSP4458G = 44587,
-
- /* Micron CMOS sensor chips: 45000-45099 */
- V4L2_IDENT_MT9M001C12ST = 45000,
- V4L2_IDENT_MT9M001C12STM = 45005,
- V4L2_IDENT_MT9M111 = 45007,
- V4L2_IDENT_MT9M112 = 45008,
- V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */
- V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */
- V4L2_IDENT_MT9T031 = 45020,
- V4L2_IDENT_MT9T111 = 45021,
- V4L2_IDENT_MT9T112 = 45022,
- V4L2_IDENT_MT9V111 = 45031,
- V4L2_IDENT_MT9V112 = 45032,
-
- /* HV7131R CMOS sensor: just ident 46000 */
- V4L2_IDENT_HV7131R = 46000,
-
- /* Sharp RJ54N1CB0C, 0xCB0C = 51980 */
- V4L2_IDENT_RJ54N1CB0C = 51980,
-
- /* module m52790: just ident 52790 */
- V4L2_IDENT_M52790 = 52790,
-
- /* module cs53132a: just ident 53132 */
- V4L2_IDENT_CS53l32A = 53132,
-
- /* modules upd61151 MPEG2 encoder: just ident 54000 */
- V4L2_IDENT_UPD61161 = 54000,
- /* modules upd61152 MPEG2 encoder with AC3: just ident 54001 */
- V4L2_IDENT_UPD61162 = 54001,
-
- /* module upd64031a: just ident 64031 */
- V4L2_IDENT_UPD64031A = 64031,
-
- /* module upd64083: just ident 64083 */
- V4L2_IDENT_UPD64083 = 64083,
-
- /* Don't just add new IDs at the end: KEEP THIS LIST ORDERED BY ID! */
-};
-
-#endif
diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h
new file mode 100644
index 0000000..0503a90
--- /dev/null
+++ b/include/media/v4l2-clk.h
@@ -0,0 +1,54 @@
+/*
+ * V4L2 clock service
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ATTENTION: This is a temporary API and it shall be replaced by the generic
+ * clock API, when the latter becomes widely available.
+ */
+
+#ifndef MEDIA_V4L2_CLK_H
+#define MEDIA_V4L2_CLK_H
+
+#include <linux/atomic.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+struct module;
+struct device;
+
+struct v4l2_clk {
+ struct list_head list;
+ const struct v4l2_clk_ops *ops;
+ const char *dev_id;
+ const char *id;
+ int enable;
+ struct mutex lock; /* Protect the enable count */
+ atomic_t use_count;
+ void *priv;
+};
+
+struct v4l2_clk_ops {
+ struct module *owner;
+ int (*enable)(struct v4l2_clk *clk);
+ void (*disable)(struct v4l2_clk *clk);
+ unsigned long (*get_rate)(struct v4l2_clk *clk);
+ int (*set_rate)(struct v4l2_clk *clk, unsigned long);
+};
+
+struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
+ const char *dev_name,
+ const char *name, void *priv);
+void v4l2_clk_unregister(struct v4l2_clk *clk);
+struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id);
+void v4l2_clk_put(struct v4l2_clk *clk);
+int v4l2_clk_enable(struct v4l2_clk *clk);
+void v4l2_clk_disable(struct v4l2_clk *clk);
+unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk);
+int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate);
+
+#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 1d93c48..015ff82 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -100,16 +100,6 @@
/* ------------------------------------------------------------------------- */
-/* Register/chip ident helper function */
-
-struct i2c_client; /* forward reference */
-int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match);
-int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip,
- u32 ident, u32 revision);
-int v4l2_chip_match_host(const struct v4l2_dbg_match *match);
-
-/* ------------------------------------------------------------------------- */
-
/* I2C Helper functions */
struct i2c_driver;
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 95d1c91..c768c9f 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -96,9 +96,9 @@
struct device dev; /* v4l device */
struct cdev *cdev; /* character device */
- /* Set either parent or v4l2_dev if your driver uses v4l2_device */
- struct device *parent; /* device parent */
struct v4l2_device *v4l2_dev; /* v4l2_device parent */
+ /* Only set parent if that can't be deduced from v4l2_dev */
+ struct device *dev_parent; /* device parent */
/* Control handler associated with this device node. May be NULL. */
struct v4l2_ctrl_handler *ctrl_handler;
@@ -129,7 +129,6 @@
/* Video standard vars */
v4l2_std_id tvnorms; /* Supported tv norms */
- v4l2_std_id current_norm; /* Current tvnorm */
/* callbacks */
void (*release)(struct video_device *vdev);
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index e6aa231..0286c95 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -220,8 +220,6 @@
vidioc_int_reset_num,
/* VIDIOC_INT_INIT */
vidioc_int_init_num,
- /* VIDIOC_DBG_G_CHIP_IDENT */
- vidioc_int_g_chip_ident_num,
/*
*
@@ -303,6 +301,5 @@
V4L2_INT_WRAPPER_0(reset);
V4L2_INT_WRAPPER_0(init);
-V4L2_INT_WRAPPER_1(g_chip_ident, int, *);
#endif
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 931652f..e0b74a4 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -247,8 +247,6 @@
int (*vidioc_g_chip_info) (struct file *file, void *fh,
struct v4l2_dbg_chip_info *chip);
#endif
- int (*vidioc_g_chip_ident) (struct file *file, void *fh,
- struct v4l2_dbg_chip_ident *chip);
int (*vidioc_enum_framesizes) (struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 5298d67..3250cc5 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -24,6 +24,7 @@
#include <linux/types.h>
#include <linux/v4l2-subdev.h>
#include <media/media-entity.h>
+#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-fh.h>
@@ -88,7 +89,6 @@
/* Core ops: it is highly recommended to implement at least these ops:
- g_chip_ident
log_status
g_register
s_register
@@ -145,7 +145,6 @@
performed later. It must not sleep. *Called from an IRQ context*.
*/
struct v4l2_subdev_core_ops {
- int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
int (*log_status)(struct v4l2_subdev *sd);
int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n,
struct v4l2_subdev_io_pin_config *pincfg);
@@ -585,8 +584,17 @@
void *host_priv;
/* subdev device node */
struct video_device *devnode;
+ /* pointer to the physical device, if any */
+ struct device *dev;
+ struct v4l2_async_subdev_list asdl;
};
+static inline struct v4l2_subdev *v4l2_async_to_subdev(
+ struct v4l2_async_subdev_list *asdl)
+{
+ return container_of(asdl, struct v4l2_subdev, asdl);
+}
+
#define media_entity_to_v4l2_subdev(ent) \
container_of(ent, struct v4l2_subdev, entity)
#define vdev_to_v4l2_subdev(vdev) \
@@ -660,7 +668,7 @@
/* Call an ops of a v4l2_subdev, doing the right checks against
NULL pointers.
- Example: err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+ Example: err = v4l2_subdev_call(sd, core, s_std, norm);
*/
#define v4l2_subdev_call(sd, o, f, args...) \
(!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ? \
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 69bd5bb..e90a88a 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -53,13 +53,13 @@
#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */
-#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */
+#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator controls */
#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */
#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */
#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009e0000 /* Image source controls */
#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */
#define V4L2_CTRL_CLASS_DV 0x00a00000 /* Digital Video controls */
-#define V4L2_CTRL_CLASS_FM_RX 0x00a10000 /* Digital Video controls */
+#define V4L2_CTRL_CLASS_FM_RX 0x00a10000 /* FM Receiver controls */
/* User-class control IDs */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index f40b41c..95ef455 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -395,7 +395,7 @@
#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
-#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES */
+#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 part 2 ES */
#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */
#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
@@ -555,7 +555,7 @@
__u32 jpeg_markers; /* Which markers should go into the JPEG
* output. Unless you exactly know what
* you do, leave them untouched.
- * Inluding less markers will make the
+ * Including less markers will make the
* resulting code smaller, but there will
* be fewer applications which can read it.
* The presence of the APP and COM marker
@@ -567,7 +567,7 @@
#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
- * allways use APP0 */
+ * always use APP0 */
};
/*
@@ -900,7 +900,7 @@
/*
* "Common" PAL - This macro is there to be compatible with the old
* V4L1 concept of "PAL": /BGDKHI.
- * Several PAL standards are mising here: /M, /N and /Nc
+ * Several PAL standards are missing here: /M, /N and /Nc
*/
#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
V4L2_STD_PAL_DK |\
@@ -1787,11 +1787,13 @@
/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
#define V4L2_CHIP_MATCH_BRIDGE 0 /* Match against chip ID on the bridge (0 for the bridge) */
+#define V4L2_CHIP_MATCH_SUBDEV 4 /* Match against subdev index */
+
+/* The following four defines are no longer in use */
#define V4L2_CHIP_MATCH_HOST V4L2_CHIP_MATCH_BRIDGE
#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */
#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
-#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */
-#define V4L2_CHIP_MATCH_SUBDEV 4 /* Match against subdev index */
+#define V4L2_CHIP_MATCH_AC97 3 /* Match against ancillary AC97 chip */
struct v4l2_dbg_match {
__u32 type; /* Match type */
@@ -1808,13 +1810,6 @@
__u64 val;
} __attribute__ ((packed));
-/* VIDIOC_DBG_G_CHIP_IDENT */
-struct v4l2_dbg_chip_ident {
- struct v4l2_dbg_match match;
- __u32 ident; /* chip identifier as specified in <media/v4l2-chip-ident.h> */
- __u32 revision; /* chip revision, chip specific */
-} __attribute__ ((packed));
-
#define V4L2_CHIP_FL_READABLE (1 << 0)
#define V4L2_CHIP_FL_WRITABLE (1 << 1)
@@ -1915,12 +1910,6 @@
#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register)
-/* Experimental, meant for debugging, testing and internal use.
- Never use this ioctl in applications!
- Note: this ioctl is deprecated in favor of VIDIOC_DBG_G_CHIP_INFO and
- will go away in the future. */
-#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident)
-
#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)