提交 85865511 编写于 作者: L Linus Torvalds

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
  ...
......@@ -77,7 +77,7 @@ Description: Read/Write attribute file that controls memory scrubbing.
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 @@ Description: This attribute file displays the information about the last
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 @@ Description: This attribute file will display the size of dimm or rank.
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 @@ Description: This attribute file will display what type of Error detection
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 @@ Description: This control file allows this DIMM to have a label assigned
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
......
......@@ -2254,7 +2254,7 @@ video encoding.</para>
<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 @@ that used it. It was originally scheduled for removal in 2.6.35.
</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 @@ and may change in the future.</para>
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
......
......@@ -140,6 +140,14 @@ structs, ioctls) must be noted in more detail in the history chapter
(compat.xml), along with the possible impact on existing drivers and
applications. -->
<revision>
<revnumber>3.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>
......@@ -493,7 +501,7 @@ and discussions on the V4L mailing list.</revremark>
</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 @@ and discussions on the V4L mailing list.</revremark>
<!-- 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;
......
<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, &eg; 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>
......@@ -73,8 +73,7 @@ fields of a &v4l2-dbg-chip-info;
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 @@ to the <structfield>type</structfield> field.</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>
to the <structfield>type</structfield> field. Currently unused.</entry>
</row>
</tbody>
</tgroup>
......@@ -182,21 +181,6 @@ is set, then the driver supports reading registers from the device. If
<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. 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>
......
......@@ -76,7 +76,7 @@ compiled with the <constant>CONFIG_VIDEO_ADV_DEBUG</constant> option
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 @@ written into the register.</para>
<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>,
......@@ -101,40 +101,10 @@ on the TV card. The number zero always selects the host chip, &eg; the
chip connected to the PCI or USB bus. You can find out which chips are
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 @@ 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-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 @@ access instructions.</para>
<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 @@ to the <structfield>type</structfield> field.</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>
to the <structfield>type</structfield> field. Currently unused.</entry>
</row>
</tbody>
</tgroup>
......@@ -198,6 +168,11 @@ to the <structfield>type</structfield> field.</entry>
<entry><structfield>match</structfield></entry>
<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>
......@@ -213,7 +188,7 @@ register.</entry>
</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>
......@@ -226,21 +201,6 @@ register.</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>
......
......@@ -54,7 +54,8 @@ standard automatically. To do so, applications call <constant>
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>
......
......@@ -2,8 +2,10 @@ Exynos4x12/Exynos5 SoC series camera host interface (FIMC-LITE)
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;
......
* 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>;
};
};
};
...
};
* 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>;
};
};
};
...
};
......@@ -127,22 +127,22 @@ Example:
};
};
};
};
/* 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>;
};
};
};
};
......
......@@ -5,8 +5,8 @@ Required properties:
- 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;
......
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>;
};
......@@ -265,7 +265,7 @@ connected to another pad through an enabled link
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.
......
......@@ -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)
......@@ -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]
......@@ -86,6 +86,6 @@ tuner=85 - Philips FQ1236 MK5
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
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 @@ data from LCD controller (FIMD) through the SoC internal writeback data
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 @@ Not currently supported:
=====================
- 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 @@ or retrieve the information from /dev/media? with help of the media-ctl tool:
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 \
......
......@@ -246,7 +246,6 @@ may be NULL if the subdev driver does not support anything from that category.
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 @@ that width, height and the media bus pixel code are equal on both source and
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 @@ Afterwards the subdev module can be unloaded and sd->dev == NULL.
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 @@ controlled through GPIO pins. This distinction is only relevant when setting
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 @@ of the video device exits.
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 @@ You should also set these fields:
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 @@ available event type is 'class base + 1'.
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.
......@@ -247,7 +247,6 @@ i2c_client 结构体,i2c_set_clientdata() 函数可用于保存一个 v4l2_sub
这些结构体定义如下:
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 @@ subdev->dev 域就指向了 v4l2_device。
注册之设备后,可通过以下方式直接调用其操作函数:
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。
......
......@@ -1165,15 +1165,6 @@ L: linux-media@vger.kernel.org
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: include/net/ax25.h
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: Documentation/filesystems/btrfs.txt
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: drivers/media/common/cx2341x*
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 @@ S: Maintained
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 @@ S: Maintained
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 @@ S: Maintained
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 @@ S: Maintained
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 @@ S: Maintained
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 @@ S: Odd Fixes
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/regulator/s5m*.c
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 @@ S: Odd Fixes
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 @@ S: Maintained
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 @@ S: Odd fixes
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: include/linux/shmem_fs.h
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 @@ S: Maintained
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
......
......@@ -509,7 +509,6 @@ struct ths7303_platform_data ths7303_pdata = {
.ch_1 = 3,
.ch_2 = 3,
.ch_3 = 3,
.init_enable = 1,
};
static struct amp_config_info vpbe_amp = {
......
......@@ -680,10 +680,7 @@ int dma_buf_debugfs_create_file(const char *name,
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)
......
#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 @@ static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type ty
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 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.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_video_ioctl_ops = {
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,
......
......@@ -1154,7 +1154,7 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
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 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
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);
......
......@@ -140,6 +140,7 @@ static void smsdvb_stats_not_ready(struct dvb_frontend *fe)
case DEVICE_MODE_ISDBT:
case DEVICE_MODE_ISDBT_BDA:
n_layers = 4;
break;
default:
n_layers = 1;
}
......
......@@ -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 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
* 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 @@ hauppauge_tuner_fmt[] =
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 @@ hauppauge_tuner[] =
{ 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 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
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 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
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 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
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 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
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);
......
......@@ -377,10 +377,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
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 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
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;
......
......@@ -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
......@@ -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_s_ctrl(struct v4l2_ctrl *ctrl)
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, &reg->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_g_register(struct v4l2_subdev *sd,
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, &reg->match))
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
au8522_writereg(state, reg->reg, reg->val & 0xff);
return 0;
}
......@@ -636,20 +625,10 @@ static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
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,
......
......@@ -3406,7 +3406,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
{
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 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
}
}
return ret;
return 0;
}
static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
......
......@@ -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
......
......@@ -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 @@ enum OperationMode {
OM_DVBT
};
enum DRXPowerMode {
enum drx_power_mode {
DRX_POWER_UP = 0,
DRX_POWER_MODE_1,
DRX_POWER_MODE_2,
......@@ -77,24 +77,29 @@ enum DRXPowerMode {
};
/** /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 @@ enum EDrxkState {
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 @@ enum EDrxkCoefArrayIndex {
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 @@ enum EDrxkConstellation {
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 @@ enum {
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 @@ enum DRXFftmode_t {
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 drxk_state {
struct mutex mutex;
u32 m_Instance; /**< Channel 1,2,3 or 4 */
int m_ChunkSize;
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 */
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 */
u32 m_IqmFsRateOfs; /**< 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
u32 m_instance; /* Channel 1,2,3 or 4 */
int m_chunk_size;
u8 chunk[256];
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 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_iqm_fs_rate_ofs; /* frequency shift as written to DRXK register (28bit fixpoint) */
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) */
bool m_disableTEIhandling;
bool m_RfAgcPol;
bool m_IfAgcPol;
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;
enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
u16 m_GPIO;
u16 m_GPIOCfg;
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 */
u16 m_agcFastClipCtrlDelay;
bool m_adcCompPassed;
/* 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_disable_te_ihandling;
bool m_rf_agc_pol;
bool m_if_agc_pol;
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 drxk_cfg_dvbt_sqi_speed m_sqi_speed;
u16 m_gpio;
u16 m_gpio_cfg;
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_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 @@ struct drxk_state {
* 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;
......
......@@ -226,8 +226,8 @@ static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
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 @@ static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
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 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
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 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
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 @@ static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
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 @@ static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
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 @@ static enum stb0899_status stb0899_check_range(struct stb0899_state *state)
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 @@ enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state)
"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 @@ enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
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 @@ enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
}
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);
stb0899_dvbs2_reacquire(state);
internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
i++;
}
/* 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++;
}
}
/*
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 @@ enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
/* 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);
......
......@@ -1618,19 +1618,18 @@ static struct dvb_frontend_ops stb0899_ops = {
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) {
......
......@@ -45,9 +45,8 @@ struct stb0899_s2_reg {
};
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
......
......@@ -245,6 +245,15 @@ config VIDEO_KS0127
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 @@ config VIDEO_AK881X
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
......
......@@ -34,6 +34,7 @@ obj-$(CONFIG_VIDEO_BT856) += bt856.o
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_AS3645A) += as3645a.o
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
......@@ -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 @@ static const struct v4l2_ctrl_ops ad9389b_ctrl_ops = {
#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, &reg->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_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
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, &reg->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 int ad9389b_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
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 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
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 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
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 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
media_entity_cleanup(&sd->entity);
err_hdl:
v4l2_ctrl_handler_free(&state->hdl);
err_free:
kfree(state);
return err;
}
......@@ -1302,15 +1280,14 @@ static int ad9389b_remove(struct i2c_client *client)
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);
......
......@@ -417,7 +417,7 @@ static int adp1653_probe(struct i2c_client *client,
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 @@ static int adp1653_probe(struct i2c_client *client,
free_and_quit:
v4l2_ctrl_handler_free(&flash->ctrls);
kfree(flash);
return ret;
}
......@@ -455,7 +454,7 @@ static int adp1653_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(&flash->subdev);
v4l2_ctrl_handler_free(&flash->ctrls);
media_entity_cleanup(&flash->subdev.entity);
kfree(flash);
return 0;
}
......
......@@ -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 @@ static int adv7170_s_fmt(struct v4l2_subdev *sd,
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_video_ops adv7170_video_ops = {
};
static const struct v4l2_subdev_ops adv7170_ops = {
.core = &adv7170_core_ops,
.video = &adv7170_video_ops,
};
......@@ -359,7 +346,7 @@ static int adv7170_probe(struct i2c_client *client,
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 @@ static int adv7170_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
kfree(to_adv7170(sd));
return 0;
}
......
......@@ -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 @@ static int adv7175_s_fmt(struct v4l2_subdev *sd,
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 int adv7175_s_power(struct v4l2_subdev *sd, int on)
/* ----------------------------------------------------------------------- */
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 @@ static int adv7175_probe(struct i2c_client *client,
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 @@ static int adv7175_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
kfree(to_adv7175(sd));
return 0;
}
......
/*
* 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 @@ static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
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 @@ static void adv7180_exit_controls(struct adv7180_state *state)
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 @@ static int adv7180_probe(struct i2c_client *client,
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 @@ static int adv7180_probe(struct i2c_client *client,
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 @@ static int adv7180_remove(struct i2c_client *client)
mutex_destroy(&state->mutex);
v4l2_device_unregister_subdev(sd);
kfree(to_state(sd));
return 0;
}
......@@ -616,9 +650,10 @@ static const struct i2c_device_id adv7180_id[] = {
{},
};
#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 @@ static int adv7180_suspend(struct i2c_client *client, pm_message_t state)
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 @@ static int adv7180_resume(struct i2c_client *client)
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 @@ static struct i2c_driver adv7180_driver = {
.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,
};
......
......@@ -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 @@ static int adv7183_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
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 @@ static int adv7183_s_stream(struct v4l2_subdev *sd, int enable)
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, &reg->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_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
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, &reg->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 @@ static const struct v4l2_subdev_core_ops adv7183_core_ops = {
.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 @@ static int adv7183_probe(struct i2c_client *client,
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 @@ static int adv7183_probe(struct i2c_client *client,
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 @@ static int adv7183_probe(struct i2c_client *client,
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 @@ static int adv7183_probe(struct i2c_client *client,
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;
}
......
......@@ -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 @@ static int adv7343_s_ctrl(struct v4l2_ctrl *ctrl)
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,
......
......@@ -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 @@ static int adv7393_s_ctrl(struct v4l2_ctrl *ctrl)
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 @@ static int adv7393_probe(struct i2c_client *client,
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 @@ static int adv7393_probe(struct i2c_client *client,
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 @@ static int adv7393_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return 0;
}
......
......@@ -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 void adv7604_inv_register(struct v4l2_subdev *sd)
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, &reg->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_g_register(struct v4l2_subdev *sd,
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, &reg->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 @@ static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl)
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 @@ static const struct v4l2_subdev_core_ops adv7604_core_ops = {
.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 @@ static int adv7604_probe(struct i2c_client *client,
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 @@ static int adv7604_probe(struct i2c_client *client,
/* 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 @@ static int adv7604_probe(struct i2c_client *client,
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 @@ static int adv7604_probe(struct i2c_client *client,
adv7604_unregister_clients(state);
err_hdl:
v4l2_ctrl_handler_free(hdl);
err_state:
kfree(state);
return err;
}
......@@ -2111,7 +2085,6 @@ static int adv7604_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
adv7604_unregister_clients(to_state(sd));
v4l2_ctrl_handler_free(sd->ctrl_handler);
kfree(to_state(sd));
return 0;
}
......
......@@ -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 ak881x {
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 @@ static struct ak881x *to_ak881x(const struct i2c_client *client)
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 @@ static int ak881x_s_register(struct v4l2_subdev *sd,
{
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 int ak881x_s_stream(struct v4l2_subdev *sd, int enable)
}
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 @@ static int ak881x_probe(struct i2c_client *client,
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 @@ static int ak881x_probe(struct i2c_client *client,
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 @@ static int ak881x_remove(struct i2c_client *client)
struct ak881x *ak881x = to_ak881x(client);
v4l2_device_unregister_subdev(&ak881x->subdev);
kfree(ak881x);
return 0;
}
......
......@@ -813,7 +813,7 @@ static int as3645a_probe(struct i2c_client *client,
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 @@ static int as3645a_probe(struct i2c_client *client,
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 @@ static int as3645a_remove(struct i2c_client *client)
v4l2_ctrl_handler_free(&flash->ctrls);
media_entity_cleanup(&flash->subdev.entity);
mutex_destroy(&flash->power_lock);
kfree(flash);
return 0;
}
......
......@@ -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 @@ struct bt819 {
unsigned char reg[32];
v4l2_std_id norm;
int ident;
int input;
int enable;
};
......@@ -217,15 +215,17 @@ static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
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 @@ static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
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_ctrl_ops bt819_ctrl_ops = {
};
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 @@ static int bt819_probe(struct i2c_client *client,
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 @@ static int bt819_probe(struct i2c_client *client,
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 @@ static int bt819_probe(struct i2c_client *client,
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 @@ static int bt819_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&decoder->hdl);
kfree(decoder);
return 0;
}
......
......@@ -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 @@ static int bt856_s_routing(struct v4l2_subdev *sd,
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 @@ static int bt856_probe(struct i2c_client *client,
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 @@ static int bt856_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
kfree(to_bt856(sd));
return 0;
}
......
......@@ -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 @@ static int bt866_s_routing(struct v4l2_subdev *sd,
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 @@ static int bt866_probe(struct i2c_client *client,
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 @@ static int bt866_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
kfree(to_bt866(sd));
return 0;
}
......
......@@ -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 @@ static int cs5345_s_ctrl(struct v4l2_ctrl *ctrl)
#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, &reg->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_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *r
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, &reg->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_ctrl_ops cs5345_ctrl_ops = {
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 @@ static int cs5345_probe(struct i2c_client *client,
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 @@ static int cs5345_probe(struct i2c_client *client,
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return err;
}
/* set volume/mute */
......@@ -227,7 +205,6 @@ static int cs5345_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return 0;
}
......
......@@ -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 @@ static int cs53l32a_s_ctrl(struct v4l2_ctrl *ctrl)
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_ctrl_ops cs53l32a_ctrl_ops = {
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 @@ static int cs53l32a_probe(struct i2c_client *client,
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 @@ static int cs53l32a_probe(struct i2c_client *client,
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return err;
}
......@@ -228,7 +217,6 @@ static int cs53l32a_remove(struct i2c_client *client)
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return 0;
}
......
......@@ -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 @@ static void cx23885_initialize(struct i2c_client *client)
/* 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 @@ static void cx23885_initialize(struct i2c_client *client)
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 @@ static void cx23885_initialize(struct i2c_client *client)
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 @@ static void cx23885_initialize(struct i2c_client *client)
/* 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 @@ static void cx23885_initialize(struct i2c_client *client)
* 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 @@ static void cx23885_initialize(struct i2c_client *client)
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 @@ static void cx23885_initialize(struct i2c_client *client)
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 @@ static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
if (!v4l2_chip_match_i2c_client(client, &reg->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 @@ static int cx25840_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regi
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
if (!v4l2_chip_match_i2c_client(client, &reg->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 @@ static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
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_ctrl_ops cx25840_ctrl_ops = {
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 @@ static u32 get_cx2388x_ident(struct i2c_client *client)
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 @@ static int cx25840_probe(struct i2c_client *client,
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 @@ static int cx25840_probe(struct i2c_client *client,
/* 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 @@ static int cx25840_probe(struct i2c_client *client,
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 @@ static int cx25840_probe(struct i2c_client *client,
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 @@ static int cx25840_probe(struct i2c_client *client,
: (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 @@ static int cx25840_probe(struct i2c_client *client,
int err = state->hdl.error;
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return err;
}
if (!is_cx2583x(state))
......@@ -5317,7 +5298,6 @@ static int cx25840_remove(struct i2c_client *client)
cx25840_ir_remove(sd);
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return 0;
}
......
......@@ -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 @@ struct cx25840_state {
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 struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
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;
}
/* ----------------------------------------------------------------------- */
......
......@@ -1230,16 +1230,14 @@ int cx25840_ir_probe(struct v4l2_subdev *sd)
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 @@ int cx25840_ir_remove(struct v4l2_subdev *sd)
cx25840_ir_tx_shutdown(sd);
kfifo_free(&ir_state->rx_kfifo);
kfree(ir_state);
state->ir_state = NULL;
return 0;
}
......@@ -295,7 +295,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
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 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
* internally
*/
rc = rc_allocate_device();
if (!rc) {
err = -ENOMEM;
goto err_out_free;
}
if (!rc)
return -ENOMEM;
}
ir->rc = rc;
......@@ -454,7 +452,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
err_out_free:
/* Only frees rc if it were allocated internally */
rc_free_device(rc);
kfree(ir);
return err;
}
......@@ -470,7 +467,6 @@ static int ir_remove(struct i2c_client *client)
rc_unregister_device(ir->rc);
/* free memory */
kfree(ir);
return 0;
}
......
......@@ -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 adjust {
struct ks0127 {
struct v4l2_subdev sd;
v4l2_std_id norm;
int ident;
u8 regs[256];
};
......@@ -371,12 +369,9 @@ static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v)
****************************************************************************/
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 @@ static void ks0127_init(struct v4l2_subdev *sd)
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 @@ static void ks0127_init(struct v4l2_subdev *sd)
break;
case 9:
ks->ident = V4L2_IDENT_KS0127B;
v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
break;
......@@ -616,17 +609,24 @@ static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd
{
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 @@ static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
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 @@ static int ks0127_probe(struct i2c_client *client, const struct i2c_device_id *i
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 @@ static int ks0127_remove(struct i2c_client *client)
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;
}
......
......@@ -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_s_routing(struct v4l2_subdev *sd,
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, &reg->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_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *r
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, &reg->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 @@ static int m52790_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regis
}
#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 int m52790_log_status(struct v4l2_subdev *sd)
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 @@ static int m52790_probe(struct i2c_client *client,
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 @@ static int m52790_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
kfree(to_state(sd));
return 0;
}
......
......@@ -930,6 +930,7 @@ static int m5mols_probe(struct i2c_client *client,
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 @@ static int m5mols_probe(struct i2c_client *client,
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 @@ static int m5mols_probe(struct i2c_client *client,
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 @@ static int m5mols_probe(struct i2c_client *client,
ret = m5mols_sensor_power(info, true);
if (ret)
goto out_irq;
goto error;
ret = m5mols_fw_start(sd);
if (!ret)
......@@ -1005,32 +1009,19 @@ static int m5mols_probe(struct i2c_client *client,
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;
}
......
/*
* 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");
......@@ -570,15 +570,6 @@ static int msp_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
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_ctrl_ops msp_ctrl_ops = {
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 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
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 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
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 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
kfree(state);
return err;
}
......@@ -889,7 +877,6 @@ static int msp_remove(struct i2c_client *client)
msp_reset(client);
v4l2_ctrl_handler_free(&state->hdl);
kfree(state);
return 0;
}
......
......@@ -554,10 +554,8 @@ static int mt9m032_g_register(struct v4l2_subdev *sd,
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 @@ static int mt9m032_s_register(struct v4l2_subdev *sd,
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 @@ static int mt9m032_probe(struct i2c_client *client,
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 @@ static int mt9m032_probe(struct i2c_client *client,
v4l2_ctrl_handler_free(&sensor->ctrls);
error_sensor:
mutex_destroy(&sensor->lock);
kfree(sensor);
return ret;
}
......@@ -873,7 +867,6 @@ static int mt9m032_remove(struct i2c_client *client)
v4l2_ctrl_handler_free(&sensor->ctrls);
media_entity_cleanup(&subdev->entity);
mutex_destroy(&sensor->lock);
kfree(sensor);
return 0;
}
......
......@@ -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 @@ struct mt9p031 {
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 inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
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 int mt9p031_power_on(struct mt9p031 *mt9p031)
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 @@ static int mt9p031_registered(struct v4l2_subdev *subdev)
/* 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 @@ static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = {
* 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 @@ static int mt9p031_probe(struct i2c_client *client,
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 @@ static int mt9p031_probe(struct i2c_client *client,
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 @@ static const struct i2c_device_id mt9p031_id[] = {
};
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,
......
......@@ -740,7 +740,7 @@ static int mt9t001_probe(struct i2c_client *client,
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 @@ static int mt9t001_probe(struct i2c_client *client,
if (ret < 0) {
v4l2_ctrl_handler_free(&mt9t001->ctrls);
media_entity_cleanup(&mt9t001->subdev.entity);
kfree(mt9t001);
}
return ret;
......@@ -815,7 +814,6 @@ static int mt9t001_remove(struct i2c_client *client)
v4l2_ctrl_handler_free(&mt9t001->ctrls);
v4l2_device_unregister_subdev(subdev);
media_entity_cleanup(&subdev->entity);
kfree(mt9t001);
return 0;
}
......
......@@ -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_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt
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, &reg->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_g_register(struct v4l2_subdev *sd,
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, &reg->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 struct v4l2_ctrl_ops mt9v011_ctrl_ops = {
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 @@ static int mt9v011_probe(struct i2c_client *c,
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 @@ static int mt9v011_probe(struct i2c_client *c,
(version != MT9V011_REV_B_VERSION)) {
v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
version);
kfree(core);
return -EINVAL;
}
......@@ -562,7 +533,6 @@ static int mt9v011_probe(struct i2c_client *c,
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 @@ static int mt9v011_remove(struct i2c_client *c)
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(&core->ctrls);
kfree(to_mt9v011(sd));
return 0;
}
......
......@@ -744,7 +744,7 @@ static int mt9v032_probe(struct i2c_client *client,
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 @@ static int mt9v032_probe(struct i2c_client *client,
mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
if (ret < 0)
kfree(mt9v032);
v4l2_ctrl_handler_free(&mt9v032->ctrls);
return ret;
}
......@@ -841,9 +842,10 @@ static int mt9v032_remove(struct i2c_client *client)
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;
}
......
......@@ -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 @@ static int noon010_probe(struct i2c_client *client,
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 @@ static int noon010_probe(struct i2c_client *client,
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 @@ static int noon010_remove(struct i2c_client *client)
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;
}
......
......@@ -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 @@ static int ov7640_probe(struct i2c_client *client,
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 @@ static int ov7640_probe(struct i2c_client *client,
if (write_regs(client, initial_registers) < 0) {
v4l_err(client, "error initializing OV7640\n");
kfree(sd);
return -ENODEV;
}
......@@ -84,7 +82,7 @@ static int ov7640_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
kfree(sd);
return 0;
}
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册