]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'v4l-dvb/master'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 11 Feb 2016 00:32:43 +0000 (11:32 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 11 Feb 2016 00:32:43 +0000 (11:32 +1100)
188 files changed:
Documentation/DocBook/device-drivers.tmpl
Documentation/DocBook/media/v4l/media-ioc-g-topology.xml
Documentation/DocBook/media/v4l/media-types.xml
Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml [deleted file]
Documentation/DocBook/media/v4l/pixfmt.xml
Documentation/DocBook/media/v4l/vidioc-query-dv-timings.xml
Documentation/DocBook/media/v4l/vidioc-querystd.xml
Documentation/devicetree/bindings/media/i2c/mt9v032.txt
Documentation/devicetree/bindings/media/i2c/tvp5150.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/rcar_vin.txt
Documentation/devicetree/bindings/media/renesas,jpu.txt
Documentation/devicetree/bindings/media/ti-cal.txt [new file with mode: 0644]
Documentation/dvb/README.dvb-usb
MAINTAINERS
drivers/media/common/b2c2/flexcop-fe-tuner.c
drivers/media/common/b2c2/flexcop.c
drivers/media/common/cypress_firmware.c
drivers/media/common/cypress_firmware.h
drivers/media/dvb-core/dvb-usb-ids.h
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-core/dvbdev.c
drivers/media/dvb-frontends/af9013.c
drivers/media/dvb-frontends/af9033.c
drivers/media/dvb-frontends/bcm3510.c
drivers/media/dvb-frontends/bcm3510.h
drivers/media/dvb-frontends/bcm3510_priv.h
drivers/media/dvb-frontends/cxd2820r_core.c
drivers/media/dvb-frontends/dib0070.c
drivers/media/dvb-frontends/dib0090.c
drivers/media/dvb-frontends/dib3000.h
drivers/media/dvb-frontends/dib3000mb.c
drivers/media/dvb-frontends/dib3000mb_priv.h
drivers/media/dvb-frontends/dib3000mc.c
drivers/media/dvb-frontends/dib3000mc.h
drivers/media/dvb-frontends/dib7000m.c
drivers/media/dvb-frontends/dib7000p.c
drivers/media/dvb-frontends/dib8000.c
drivers/media/dvb-frontends/dib9000.c
drivers/media/dvb-frontends/dibx000_common.c
drivers/media/dvb-frontends/rtl2830.c
drivers/media/dvb-frontends/si2165.c
drivers/media/dvb-frontends/stv0299.c
drivers/media/dvb-frontends/stv6110x.c
drivers/media/dvb-frontends/stv6110x.h
drivers/media/dvb-frontends/stv6110x_priv.h
drivers/media/dvb-frontends/ts2020.c
drivers/media/i2c/adv7604.c
drivers/media/i2c/msp3400-driver.c
drivers/media/i2c/msp3400-driver.h
drivers/media/i2c/mt9v011.c
drivers/media/i2c/mt9v032.c
drivers/media/i2c/ov2659.c
drivers/media/i2c/s5c73m3/s5c73m3-core.c
drivers/media/i2c/s5c73m3/s5c73m3-spi.c
drivers/media/i2c/s5k5baf.c
drivers/media/i2c/saa7115.c
drivers/media/i2c/soc_camera/mt9m001.c
drivers/media/i2c/soc_camera/mt9t031.c
drivers/media/i2c/soc_camera/mt9v022.c
drivers/media/i2c/tc358743.c
drivers/media/i2c/tvp514x.c
drivers/media/i2c/tvp5150.c
drivers/media/i2c/tvp7002.c
drivers/media/i2c/vpx3220.c
drivers/media/media-device.c
drivers/media/media-devnode.c
drivers/media/media-entity.c
drivers/media/pci/b2c2/flexcop-pci.c
drivers/media/pci/bt8xx/bttv-driver.c
drivers/media/pci/bt8xx/dvb-bt8xx.c
drivers/media/pci/ddbridge/ddbridge-core.c
drivers/media/pci/netup_unidvb/netup_unidvb_core.c
drivers/media/pci/ngene/ngene-cards.c
drivers/media/pci/saa7134/saa7134-empress.c
drivers/media/pci/saa7134/saa7134-go7007.c
drivers/media/pci/saa7134/saa7134-video.c
drivers/media/pci/ttpci/av7110.c
drivers/media/pci/ttpci/budget.c
drivers/media/platform/Kconfig
drivers/media/platform/Makefile
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/davinci/dm644x_ccdc.c
drivers/media/platform/exynos-gsc/gsc-m2m.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/media/platform/exynos4-is/mipi-csis.c
drivers/media/platform/omap3isp/isp.c
drivers/media/platform/omap3isp/ispccdc.c
drivers/media/platform/omap3isp/isppreview.c
drivers/media/platform/omap3isp/ispvideo.c
drivers/media/platform/omap3isp/omap3isp.h
drivers/media/platform/rcar_jpu.c
drivers/media/platform/soc_camera/rcar_vin.c
drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
drivers/media/platform/ti-vpe/Makefile
drivers/media/platform/ti-vpe/cal.c [new file with mode: 0644]
drivers/media/platform/ti-vpe/cal_regs.h [new file with mode: 0644]
drivers/media/platform/vim2m.c
drivers/media/platform/vivid/vivid-tpg.h
drivers/media/radio/radio-si476x.c
drivers/media/radio/wl128x/fmdrv_common.c
drivers/media/rc/nuvoton-cir.c
drivers/media/rc/nuvoton-cir.h
drivers/media/rc/rc-core-priv.h
drivers/media/rc/rc-ir-raw.c
drivers/media/tuners/m88rs6000t.c
drivers/media/tuners/r820t.c
drivers/media/tuners/si2157.c
drivers/media/tuners/tuner-xc2028.c
drivers/media/usb/as102/as102_drv.h
drivers/media/usb/as102/as102_usb_drv.c
drivers/media/usb/au0828/au0828-core.c
drivers/media/usb/au0828/au0828-dvb.c
drivers/media/usb/b2c2/flexcop-usb.c
drivers/media/usb/cx231xx/cx231xx-417.c
drivers/media/usb/cx231xx/cx231xx-audio.c
drivers/media/usb/cx231xx/cx231xx-cards.c
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/media/usb/dvb-usb-v2/af9035.h
drivers/media/usb/dvb-usb-v2/dvb_usb.h
drivers/media/usb/dvb-usb-v2/dvb_usb_common.h
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
drivers/media/usb/dvb-usb-v2/dvbsky.c
drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
drivers/media/usb/dvb-usb-v2/mxl111sf.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/usb_urb.c
drivers/media/usb/dvb-usb/a800.c
drivers/media/usb/dvb-usb/cxusb.c
drivers/media/usb/dvb-usb/dib0700_core.c
drivers/media/usb/dvb-usb/dib0700_devices.c
drivers/media/usb/dvb-usb/dibusb-common.c
drivers/media/usb/dvb-usb/dibusb-mb.c
drivers/media/usb/dvb-usb/dibusb-mc.c
drivers/media/usb/dvb-usb/dibusb.h
drivers/media/usb/dvb-usb/digitv.c
drivers/media/usb/dvb-usb/dtt200u-fe.c
drivers/media/usb/dvb-usb/dtt200u.c
drivers/media/usb/dvb-usb/dtt200u.h
drivers/media/usb/dvb-usb/dvb-usb-common.h
drivers/media/usb/dvb-usb/dvb-usb-dvb.c
drivers/media/usb/dvb-usb/dvb-usb-firmware.c
drivers/media/usb/dvb-usb/dvb-usb-i2c.c
drivers/media/usb/dvb-usb/dvb-usb-init.c
drivers/media/usb/dvb-usb/dvb-usb-remote.c
drivers/media/usb/dvb-usb/dvb-usb-urb.c
drivers/media/usb/dvb-usb/dvb-usb.h
drivers/media/usb/dvb-usb/dw2102.c
drivers/media/usb/dvb-usb/nova-t-usb2.c
drivers/media/usb/dvb-usb/technisat-usb2.c
drivers/media/usb/dvb-usb/ttusb2.c
drivers/media/usb/dvb-usb/umt-010.c
drivers/media/usb/dvb-usb/usb-urb.c
drivers/media/usb/dvb-usb/vp702x-fe.c
drivers/media/usb/dvb-usb/vp702x.c
drivers/media/usb/dvb-usb/vp7045-fe.c
drivers/media/usb/dvb-usb/vp7045.c
drivers/media/usb/dvb-usb/vp7045.h
drivers/media/usb/em28xx/em28xx-camera.c
drivers/media/usb/em28xx/em28xx-cards.c
drivers/media/usb/em28xx/em28xx-dvb.c
drivers/media/usb/em28xx/em28xx-video.c
drivers/media/usb/em28xx/em28xx.h
drivers/media/usb/go7007/go7007-priv.h
drivers/media/usb/go7007/go7007-usb.c
drivers/media/usb/hdpvr/hdpvr-core.c
drivers/media/usb/hdpvr/hdpvr-video.c
drivers/media/usb/msi2500/msi2500.c
drivers/media/usb/pwc/pwc-if.c
drivers/media/usb/stk1160/stk1160-video.c
drivers/media/usb/usbtv/usbtv-video.c
drivers/media/usb/usbtv/usbtv.h
drivers/media/usb/usbvision/usbvision-video.c
drivers/media/v4l2-core/Kconfig
drivers/media/v4l2-core/tuner-core.c
drivers/media/v4l2-core/v4l2-compat-ioctl32.c
drivers/media/v4l2-core/v4l2-dv-timings.c
drivers/media/v4l2-core/v4l2-of.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h
drivers/staging/media/lirc/lirc_parallel.c
include/media/tuner.h
include/media/v4l2-mc.h [new file with mode: 0644]
include/uapi/linux/media.h
include/uapi/linux/v4l2-common.h

index cdd8b24db68d3efc7f9a8d85130c8b851b2f963b..cc303a2f641cb59e7d8ab3c78c4f38751474d43d 100644 (file)
@@ -229,6 +229,7 @@ X!Isound/sound_firmware.c
 !Iinclude/media/v4l2-dv-timings.h
 !Iinclude/media/v4l2-event.h
 !Iinclude/media/v4l2-flash-led-class.h
+!Iinclude/media/v4l2-mc.h
 !Iinclude/media/v4l2-mediabus.h
 !Iinclude/media/v4l2-mem2mem.h
 !Iinclude/media/v4l2-of.h
index 63152ab9efbad0b10c59105effc55c49cc02d488..e0d49fa329f095bdc35ff643e4cac206232f2e03 100644 (file)
@@ -48,9 +48,6 @@
 
   <refsect1>
     <title>Description</title>
-
-    <para><emphasis role="bold">NOTE:</emphasis> This new ioctl is programmed to be added on Kernel 4.6. Its definition/arguments may change until its final version.</para>
-
     <para>The typical usage of this ioctl is to call it twice.
     On the first call, the structure defined at &media-v2-topology; should
     be zeroed. At return, if no errors happen, this ioctl will return the
index 1af3842509105ea45fd815ad953781d901b03bfe..751c3d0271036544dae44457fdab0f8767830ef7 100644 (file)
          </row>
          <row>
            <entry><constant>MEDIA_ENT_F_TUNER</constant></entry>
-           <entry>Digital TV, analog TV, radio and/or software radio tuner.</entry>
+           <entry>Digital TV, analog TV, radio and/or software radio tuner,
+                  with consists on a PLL tuning stage that converts radio
+                  frequency (RF) signal into an Intermediate Frequency (IF).
+                  Modern tuners have internally IF-PLL decoders for audio
+                  and video, but older models have those stages implemented
+                  on separate entities.
+           </entry>
+         </row>
+         <row>
+           <entry><constant>MEDIA_ENT_F_IF_VID_DECODER</constant></entry>
+           <entry>IF-PLL video decoder. It receives the IF from a PLL
+                  and decodes the analog TV video signal. This is commonly
+                  found on some very old analog tuners, like Philips MK3
+                  designs. They all contain a tda9887 (or some software
+                  compatible similar chip, like tda9885). Those devices
+                  use a different I2C address than the tuner PLL.
+           </entry>
+         </row>
+         <row>
+           <entry><constant>MEDIA_ENT_F_IF_AUD_DECODER</constant></entry>
+           <entry>IF-PLL sound decoder. It receives the IF from a PLL
+                  and decodes the analog TV audio signal. This is commonly
+                  found on some very old analog hardware, like Micronas
+                  msp3400, Philips tda9840, tda985x, etc. Those devices
+                  use a different I2C address than the tuner PLL and
+                  should be controlled together with the IF-PLL video
+                  decoder.
+           </entry>
          </row>
        </tbody>
       </tgroup>
index e781cc61786c52b93f3f2973110f6040c56dac0e..7d13fe96657d6fef3ab8fa51bf54ec60a7f697fa 100644 (file)
@@ -1,35 +1,43 @@
-    <refentry id="V4L2-PIX-FMT-YUV420M">
+    <refentry>
       <refmeta>
-       <refentrytitle>V4L2_PIX_FMT_YUV420M ('YM12')</refentrytitle>
+       <refentrytitle>V4L2_PIX_FMT_YUV420M ('YM12'), V4L2_PIX_FMT_YVU420M ('YM21')</refentrytitle>
        &manvol;
       </refmeta>
       <refnamediv>
-       <refname> <constant>V4L2_PIX_FMT_YUV420M</constant></refname>
-       <refpurpose>Variation of <constant>V4L2_PIX_FMT_YUV420</constant>
-         with planes non contiguous in memory. </refpurpose>
+       <refname id="V4L2-PIX-FMT-YUV420M"><constant>V4L2_PIX_FMT_YUV420M</constant></refname>
+       <refname id="V4L2-PIX-FMT-YVU420M"><constant>V4L2_PIX_FMT_YVU420M</constant></refname>
+       <refpurpose>Variation of <constant>V4L2_PIX_FMT_YUV420</constant> and
+         <constant>V4L2_PIX_FMT_YVU420</constant> with planes non contiguous
+         in memory.</refpurpose>
       </refnamediv>
 
       <refsect1>
        <title>Description</title>
 
        <para>This is a multi-planar format, as opposed to a packed format.
-The three components are separated into three sub- images or planes.
+The three components are separated into three sub-images or planes.</para>
 
-The Y plane is first. The Y plane has one byte per pixel. The Cb data
+       <para>The Y plane is first. The Y plane has one byte per pixel.
+For <constant>V4L2_PIX_FMT_YUV420M</constant> the Cb data
 constitutes the second plane which is half the width and half
 the height of the Y plane (and of the image). Each Cb belongs to four
 pixels, a two-by-two square of the image. For example,
 Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
 Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
 Y'<subscript>11</subscript>. The Cr data, just like the Cb plane, is
-in the third plane. </para>
+in the third plane.</para>
+
+       <para><constant>V4L2_PIX_FMT_YVU420M</constant> is the same except
+the Cr data is stored in the second plane and the Cb data in the third plane.
+</para>
 
        <para>If the Y plane has pad bytes after each row, then the Cb
 and Cr planes have half as many pad bytes after their rows. In other
 words, two Cx rows (including padding) is exactly as long as one Y row
 (including padding).</para>
 
-       <para><constant>V4L2_PIX_FMT_YUV420M</constant> is intended to be
+       <para><constant>V4L2_PIX_FMT_YUV420M</constant> and
+<constant>V4L2_PIX_FMT_YVU420M</constant> are intended to be
 used only in drivers and applications that support the multi-planar API,
 described in <xref linkend="planar-apis"/>. </para>
 
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yvu420m.xml
deleted file mode 100644 (file)
index 2330667..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-    <refentry id="V4L2-PIX-FMT-YVU420M">
-      <refmeta>
-       <refentrytitle>V4L2_PIX_FMT_YVU420M ('YM21')</refentrytitle>
-       &manvol;
-      </refmeta>
-      <refnamediv>
-       <refname> <constant>V4L2_PIX_FMT_YVU420M</constant></refname>
-       <refpurpose>Variation of <constant>V4L2_PIX_FMT_YVU420</constant>
-         with planes non contiguous in memory. </refpurpose>
-      </refnamediv>
-
-      <refsect1>
-       <title>Description</title>
-
-       <para>This is a multi-planar format, as opposed to a packed format.
-The three components are separated into three sub-images or planes.
-
-The Y plane is first. The Y plane has one byte per pixel. The Cr data
-constitutes the second plane which is half the width and half
-the height of the Y plane (and of the image). Each Cr belongs to four
-pixels, a two-by-two square of the image. For example,
-Cr<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
-Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
-Y'<subscript>11</subscript>. The Cb data, just like the Cr plane, constitutes
-the third plane. </para>
-
-       <para>If the Y plane has pad bytes after each row, then the Cr
-and Cb planes have half as many pad bytes after their rows. In other
-words, two Cx rows (including padding) is exactly as long as one Y row
-(including padding).</para>
-
-       <para><constant>V4L2_PIX_FMT_YVU420M</constant> is intended to be
-used only in drivers and applications that support the multi-planar API,
-described in <xref linkend="planar-apis"/>. </para>
-
-       <example>
-         <title><constant>V4L2_PIX_FMT_YVU420M</constant> 4 &times; 4
-pixel image</title>
-
-         <formalpara>
-           <title>Byte Order.</title>
-           <para>Each cell is one byte.
-               <informaltable frame="none">
-               <tgroup cols="5" align="center">
-                 <colspec align="left" colwidth="2*" />
-                 <tbody valign="top">
-                   <row>
-                     <entry>start0&nbsp;+&nbsp;0:</entry>
-                     <entry>Y'<subscript>00</subscript></entry>
-                     <entry>Y'<subscript>01</subscript></entry>
-                     <entry>Y'<subscript>02</subscript></entry>
-                     <entry>Y'<subscript>03</subscript></entry>
-                   </row>
-                   <row>
-                     <entry>start0&nbsp;+&nbsp;4:</entry>
-                     <entry>Y'<subscript>10</subscript></entry>
-                     <entry>Y'<subscript>11</subscript></entry>
-                     <entry>Y'<subscript>12</subscript></entry>
-                     <entry>Y'<subscript>13</subscript></entry>
-                   </row>
-                   <row>
-                     <entry>start0&nbsp;+&nbsp;8:</entry>
-                     <entry>Y'<subscript>20</subscript></entry>
-                     <entry>Y'<subscript>21</subscript></entry>
-                     <entry>Y'<subscript>22</subscript></entry>
-                     <entry>Y'<subscript>23</subscript></entry>
-                   </row>
-                   <row>
-                     <entry>start0&nbsp;+&nbsp;12:</entry>
-                     <entry>Y'<subscript>30</subscript></entry>
-                     <entry>Y'<subscript>31</subscript></entry>
-                     <entry>Y'<subscript>32</subscript></entry>
-                     <entry>Y'<subscript>33</subscript></entry>
-                   </row>
-                   <row><entry></entry></row>
-                   <row>
-                     <entry>start1&nbsp;+&nbsp;0:</entry>
-                     <entry>Cr<subscript>00</subscript></entry>
-                     <entry>Cr<subscript>01</subscript></entry>
-                   </row>
-                   <row>
-                     <entry>start1&nbsp;+&nbsp;2:</entry>
-                     <entry>Cr<subscript>10</subscript></entry>
-                     <entry>Cr<subscript>11</subscript></entry>
-                   </row>
-                   <row><entry></entry></row>
-                   <row>
-                     <entry>start2&nbsp;+&nbsp;0:</entry>
-                     <entry>Cb<subscript>00</subscript></entry>
-                     <entry>Cb<subscript>01</subscript></entry>
-                   </row>
-                   <row>
-                     <entry>start2&nbsp;+&nbsp;2:</entry>
-                     <entry>Cb<subscript>10</subscript></entry>
-                     <entry>Cb<subscript>11</subscript></entry>
-                   </row>
-                 </tbody>
-               </tgroup>
-               </informaltable>
-             </para>
-         </formalpara>
-
-         <formalpara>
-           <title>Color Sample Location.</title>
-           <para>
-               <informaltable frame="none">
-               <tgroup cols="7" align="center">
-                 <tbody valign="top">
-                   <row>
-                     <entry></entry>
-                     <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
-                     <entry>2</entry><entry></entry><entry>3</entry>
-                   </row>
-                   <row>
-                     <entry>0</entry>
-                     <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
-                     <entry>Y</entry><entry></entry><entry>Y</entry>
-                   </row>
-                   <row>
-                     <entry></entry>
-                     <entry></entry><entry>C</entry><entry></entry><entry></entry>
-                     <entry></entry><entry>C</entry><entry></entry>
-                   </row>
-                   <row>
-                     <entry>1</entry>
-                     <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
-                     <entry>Y</entry><entry></entry><entry>Y</entry>
-                   </row>
-                   <row>
-                     <entry></entry>
-                   </row>
-                   <row>
-                     <entry>2</entry>
-                     <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
-                     <entry>Y</entry><entry></entry><entry>Y</entry>
-                   </row>
-                   <row>
-                     <entry></entry>
-                     <entry></entry><entry>C</entry><entry></entry><entry></entry>
-                     <entry></entry><entry>C</entry><entry></entry>
-                   </row>
-                   <row>
-                     <entry>3</entry>
-                     <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
-                     <entry>Y</entry><entry></entry><entry>Y</entry>
-                   </row>
-                 </tbody>
-               </tgroup>
-               </informaltable>
-             </para>
-         </formalpara>
-       </example>
-      </refsect1>
-    </refentry>
index d871245d29735a0084ea422539a0dc23f106ca10..9e77ff353febe87d1e8ba66b6159c78e656f716a 100644 (file)
@@ -1628,7 +1628,6 @@ information.</para>
     &sub-y41p;
     &sub-yuv420;
     &sub-yuv420m;
-    &sub-yvu420m;
     &sub-yuv410;
     &sub-yuv422p;
     &sub-yuv411p;
index e9c70a8f34762b878ee67aa51a57d568ce5d6791..0c93677d16b449b931f5b9cb7591bd184be39fa2 100644 (file)
@@ -60,9 +60,19 @@ input</refpurpose>
 automatically, similar to sensing the video standard. To do so, applications
 call <constant>VIDIOC_QUERY_DV_TIMINGS</constant> with a pointer to a
 &v4l2-dv-timings;. Once the hardware detects the timings, it will fill in the
-timings structure.
+timings structure.</para>
 
-If the timings could not be detected because there was no signal, then
+<para>Please note that drivers shall <emphasis>not</emphasis> switch timings automatically
+if new timings are detected. Instead, drivers should send the
+<constant>V4L2_EVENT_SOURCE_CHANGE</constant> event (if they support this) and expect
+that userspace will take action by calling <constant>VIDIOC_QUERY_DV_TIMINGS</constant>.
+The reason is that new timings usually mean different buffer sizes as well, and you
+cannot change buffer sizes on the fly. In general, applications that receive the
+Source Change event will have to call <constant>VIDIOC_QUERY_DV_TIMINGS</constant>,
+and if the detected timings are valid they will have to stop streaming, set the new
+timings, allocate new buffers and start streaming again.</para>
+
+<para>If the timings could not be detected because there was no signal, then
 <errorcode>ENOLINK</errorcode> is returned. If a signal was detected, but
 it was unstable and the receiver could not lock to the signal, then
 <errorcode>ENOLCK</errorcode> is returned. If the receiver could lock to the signal,
index 222348542182bfb06b5019bbac2ea023d06bab02..3ceae35fab0317e22fe891ce8c895346f527d223 100644 (file)
@@ -59,6 +59,16 @@ 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>
 
+<para>Please note that drivers shall <emphasis>not</emphasis> switch the video standard
+automatically if a new video standard is detected. Instead, drivers should send the
+<constant>V4L2_EVENT_SOURCE_CHANGE</constant> event (if they support this) and expect
+that userspace will take action by calling <constant>VIDIOC_QUERYSTD</constant>.
+The reason is that a new video standard can mean different buffer sizes as well, and you
+cannot change buffer sizes on the fly. In general, applications that receive the
+Source Change event will have to call <constant>VIDIOC_QUERYSTD</constant>,
+and if the detected video standard is valid they will have to stop streaming, set the new
+standard, allocate new buffers and start streaming again.</para>
+
   </refsect1>
 
   <refsect1>
index 202565313e825fe897e03a05849fa54765efe2fe..100f0ae432691c36ff54609c86a8cc984b9a5b7d 100644 (file)
@@ -20,6 +20,8 @@ Optional Properties:
 
 - link-frequencies: List of allowed link frequencies in Hz. Each frequency is
        expressed as a 64-bit big-endian integer.
+- reset-gpios: GPIO handle which is connected to the reset pin of the chip.
+- standby-gpios: GPIO handle which is connected to the standby pin of the chip.
 
 For further reading on port node refer to
 Documentation/devicetree/bindings/media/video-interfaces.txt.
diff --git a/Documentation/devicetree/bindings/media/i2c/tvp5150.txt b/Documentation/devicetree/bindings/media/i2c/tvp5150.txt
new file mode 100644 (file)
index 0000000..8c0fc1a
--- /dev/null
@@ -0,0 +1,45 @@
+* Texas Instruments TVP5150 and TVP5151 video decoders
+
+The TVP5150 and TVP5151 are video decoders that convert baseband NTSC and PAL
+(and also SECAM in the TVP5151 case) video signals to either 8-bit 4:2:2 YUV
+with discrete syncs or 8-bit ITU-R BT.656 with embedded syncs output formats.
+
+Required Properties:
+- compatible: value must be "ti,tvp5150"
+- reg: I2C slave address
+
+Optional Properties:
+- pdn-gpios: phandle for the GPIO connected to the PDN pin, if any.
+- reset-gpios: phandle for the GPIO connected to the RESETB pin, if any.
+
+The device node must contain one 'port' child node for its digital output
+video port, in accordance with the video interface bindings defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Required Endpoint Properties for parallel synchronization:
+
+- hsync-active: active state of the HSYNC signal. Must be <1> (HIGH).
+- vsync-active: active state of the VSYNC signal. Must be <1> (HIGH).
+- field-even-active: field signal level during the even field data
+  transmission. Must be <0>.
+
+If none of hsync-active, vsync-active and field-even-active is specified,
+the endpoint is assumed to use embedded BT.656 synchronization.
+
+Example:
+
+&i2c2 {
+       ...
+       tvp5150@5c {
+               compatible = "ti,tvp5150";
+               reg = <0x5c>;
+               pdn-gpios = <&gpio4 30 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>;
+
+               port {
+                       tvp5150_1: endpoint {
+                               remote-endpoint = <&ccdc_ep>;
+                       };
+               };
+       };
+};
index 9dafe6b06cd286a053a5db66cbbf8a5288faba2a..619193ccf7ff831d876c151f9689d8074c20070d 100644 (file)
@@ -6,6 +6,7 @@ family of devices. The current blocks are always slaves and suppot one input
 channel which can be either RGB, YUYV or BT656.
 
  - compatible: Must be one of the following
+   - "renesas,vin-r8a7795" for the R8A7795 device
    - "renesas,vin-r8a7794" for the R8A7794 device
    - "renesas,vin-r8a7793" for the R8A7793 device
    - "renesas,vin-r8a7791" for the R8A7791 device
index 0cb94201bf921a191c617c4c84a4a4637fc9c8d0..d3436e5190f9196a64f42fd0872a218a893cc229 100644 (file)
@@ -5,11 +5,12 @@ and decoding function conforming to the JPEG baseline process, so that the JPU
 can encode image data and decode JPEG data quickly.
 
 Required properties:
-  - compatible: should containg one of the following:
-                       - "renesas,jpu-r8a7790" for R-Car H2
-                       - "renesas,jpu-r8a7791" for R-Car M2-W
-                       - "renesas,jpu-r8a7792" for R-Car V2H
-                       - "renesas,jpu-r8a7793" for R-Car M2-N
+- compatible: "renesas,jpu-<soctype>", "renesas,rcar-gen2-jpu" as fallback.
+       Examples with soctypes are:
+         - "renesas,jpu-r8a7790" for R-Car H2
+         - "renesas,jpu-r8a7791" for R-Car M2-W
+         - "renesas,jpu-r8a7792" for R-Car V2H
+         - "renesas,jpu-r8a7793" for R-Car M2-N
 
   - reg: Base address and length of the registers block for the JPU.
   - interrupts: JPU interrupt specifier.
@@ -17,7 +18,7 @@ Required properties:
 
 Example: R8A7790 (R-Car H2) JPU node
        jpeg-codec@fe980000 {
-               compatible = "renesas,jpu-r8a7790";
+               compatible = "renesas,jpu-r8a7790", "renesas,rcar-gen2-jpu";
                reg = <0 0xfe980000 0 0x10300>;
                interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp1_clks R8A7790_CLK_JPU>;
diff --git a/Documentation/devicetree/bindings/media/ti-cal.txt b/Documentation/devicetree/bindings/media/ti-cal.txt
new file mode 100644 (file)
index 0000000..ae9b52f
--- /dev/null
@@ -0,0 +1,72 @@
+Texas Instruments DRA72x CAMERA ADAPTATION LAYER (CAL)
+------------------------------------------------------
+
+The Camera Adaptation Layer (CAL) is a key component for image capture
+applications. The capture module provides the system interface and the
+processing capability to connect CSI2 image-sensor modules to the
+DRA72x device.
+
+Required properties:
+- compatible: must be "ti,dra72-cal"
+- reg: CAL Top level, Receiver Core #0, Receiver Core #1 and Camera RX
+       control address space
+- reg-names: cal_top, cal_rx_core0, cal_rx_core1, and camerrx_control
+            registers
+- interrupts: should contain IRQ line for the CAL;
+
+CAL supports 2 camera port nodes on MIPI bus. Each CSI2 camera port nodes
+should contain a 'port' child node with child 'endpoint' node. Please
+refer to the bindings defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+       cal: cal@4845b000 {
+               compatible = "ti,dra72-cal";
+               ti,hwmods = "cal";
+               reg = <0x4845B000 0x400>,
+                     <0x4845B800 0x40>,
+                     <0x4845B900 0x40>,
+                     <0x4A002e94 0x4>;
+               reg-names = "cal_top",
+                           "cal_rx_core0",
+                           "cal_rx_core1",
+                           "camerrx_control";
+               interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       csi2_0: port@0 {
+                               reg = <0>;
+                               endpoint {
+                                       slave-mode;
+                                       remote-endpoint = <&ar0330_1>;
+                               };
+                       };
+                       csi2_1: port@1 {
+                               reg = <1>;
+                       };
+               };
+       };
+
+       i2c5: i2c@4807c000 {
+               ar0330@10 {
+                       compatible = "ti,ar0330";
+                       reg = <0x10>;
+
+                       port {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               ar0330_1: endpoint {
+                                       reg = <0>;
+                                       clock-lanes = <1>;
+                                       data-lanes = <0 2 3 4>;
+                                       remote-endpoint = <&csi2_0>;
+                               };
+                       };
+               };
+       };
index 669dc6ce43305e17f29ea95066bec2a80b59b70d..6f4b12f7b8444cc121ece7f6de89ebb217e64461 100644 (file)
@@ -190,7 +190,7 @@ and watch another one.
 Patches, comments and suggestions are very very welcome.
 
 3. Acknowledgements
-   Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for
+   Amaury Demol (Amaury.Demol@parrot.com) and Francois Kanounnikoff from DiBcom for
     providing specs, code and help, on which the dvb-dibusb, dib3000mb and
     dib3000mc are based.
 
index 208539fa2b65dc51490b6fdaf3b822f3a44a3515..df28b91f4311e29dd7e260b42ef4dab40af0e0a6 100644 (file)
@@ -10869,6 +10869,14 @@ L:     linux-omap@vger.kernel.org
 S:     Maintained
 F:     drivers/thermal/ti-soc-thermal/
 
+TI VPE/CAL DRIVERS
+M:     Benoit Parrot <bparrot@ti.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org/
+Q:     http://patchwork.linuxtv.org/project/linux-media/list/
+S:     Maintained
+F:     drivers/media/platform/ti-vpe/
+
 TI CDCE706 CLOCK DRIVER
 M:     Max Filippov <jcmvbkbc@gmail.com>
 S:     Maintained
index 9c59f4306883a6de666052c613896b850313b8d0..f5956402fc69dfcd88c9870abe5ea76e3d6e6d65 100644 (file)
@@ -38,7 +38,7 @@ static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
 #endif
 
 /* lnb control */
-#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)
+#if (FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)) && FE_SUPPORTED(PLL)
 static int flexcop_set_voltage(struct dvb_frontend *fe,
                               enum fe_sec_voltage voltage)
 {
@@ -68,7 +68,7 @@ static int flexcop_set_voltage(struct dvb_frontend *fe,
 #endif
 
 #if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
-static int flexcop_sleep(struct dvb_frontend* fe)
+static int __maybe_unused flexcop_sleep(struct dvb_frontend* fe)
 {
        struct flexcop_device *fc = fe->dvb->priv;
        if (fc->fe_sleep)
index 412c5daf2b48c4208f2fb0bd60ed50fb2f4acbef..0f5114d406f822004dca7f2b6e148ca49110d710 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
  * flexcop.c - main module part
- * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@posteo.de>
  * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
  *
  * Acknowledgements:
@@ -34,7 +34,7 @@
 #include "flexcop.h"
 
 #define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip"
-#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@posteo.de"
 
 #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
 #define DEBSTATUS ""
index 577e82058fdc9e268bf1268651a6402f7f7de9ca..50e3f76d4847412e1280e14c1fe0b44847c8fd57 100644 (file)
@@ -1,6 +1,6 @@
 /*  cypress_firmware.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for downloading the firmware to Cypress FX 1
index e493cbc7a5289ecae3c8c80fedd52b358e1ffd90..1e4f2735620529a5bc3531947c15e003679b95df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for downloading the firmware to Cypress FX 1
index 1c1c298d2289b9bba1ab8fdd1629c660dedfba92..dbdbb84294c5f1b5a225fe493a603d18bdbcab13 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-ids.h is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de) see
  * dvb-usb-init.c for copyright information.
  *
  * a header file containing define's for the USB device supported by the
 #define USB_PID_DIBCOM_STK807XP                                0x1f90
 #define USB_PID_DIBCOM_STK807XPVR                      0x1f98
 #define USB_PID_DIBCOM_STK8096GP                        0x1fa0
+#define USB_PID_DIBCOM_STK8096PVR                       0x1faa
 #define USB_PID_DIBCOM_NIM8096MD                        0x1fa8
 #define USB_PID_DIBCOM_TFE8096P                                0x1f9C
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD                        0x2131
 #define USB_PID_TECHNOTREND_CONNECT_CT3650             0x300d
 #define USB_PID_TECHNOTREND_CONNECT_S2_4600             0x3011
 #define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI                0x3012
+#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2      0x3015
 #define USB_PID_TECHNOTREND_TVSTICK_CT2_4400           0x3014
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY       0x005a
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2     0x0081
 #define USB_PID_TERRATEC_CINERGY_T_EXPRESS             0x0062
 #define USB_PID_TERRATEC_CINERGY_T_XXS                 0x0078
 #define USB_PID_TERRATEC_CINERGY_T_XXS_2               0x00ab
+#define USB_PID_TERRATEC_CINERGY_S2_R1                 0x00a8
+#define USB_PID_TERRATEC_CINERGY_S2_R2                 0x00b0
+#define USB_PID_TERRATEC_CINERGY_S2_R3                 0x0102
+#define USB_PID_TERRATEC_CINERGY_S2_R4                 0x0105
 #define USB_PID_TERRATEC_H7                            0x10b4
 #define USB_PID_TERRATEC_H7_2                          0x10a3
 #define USB_PID_TERRATEC_H7_3                          0x10a5
index 40080645341e727a6380feac3f991fb022b86bf4..b1255b7c0b0edb7c34dd65c3983a1f02ededb949 100644 (file)
@@ -899,10 +899,10 @@ void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec)
        s32 delta;
 
        *waketime = ktime_add_us(*waketime, add_usec);
-       delta = ktime_us_delta(ktime_get_real(), *waketime);
+       delta = ktime_us_delta(ktime_get_boottime(), *waketime);
        if (delta > 2500) {
                msleep((delta - 1500) / 1000);
-               delta = ktime_us_delta(ktime_get_real(), *waketime);
+               delta = ktime_us_delta(ktime_get_boottime(), *waketime);
        }
        if (delta > 0)
                udelay(delta);
@@ -1162,18 +1162,24 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
        _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0),
 };
 
-static void dtv_property_dump(struct dvb_frontend *fe, struct dtv_property *tvp)
+static void dtv_property_dump(struct dvb_frontend *fe,
+                             bool is_set,
+                             struct dtv_property *tvp)
 {
        int i;
 
        if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
-               dev_warn(fe->dvb->device, "%s: tvp.cmd = 0x%08x undefined\n",
-                               __func__, tvp->cmd);
+               dev_warn(fe->dvb->device, "%s: %s tvp.cmd = 0x%08x undefined\n",
+                               __func__,
+                               is_set ? "SET" : "GET",
+                               tvp->cmd);
                return;
        }
 
-       dev_dbg(fe->dvb->device, "%s: tvp.cmd    = 0x%08x (%s)\n", __func__,
-                       tvp->cmd, dtv_cmds[tvp->cmd].name);
+       dev_dbg(fe->dvb->device, "%s: %s tvp.cmd    = 0x%08x (%s)\n", __func__,
+               is_set ? "SET" : "GET",
+               tvp->cmd,
+               dtv_cmds[tvp->cmd].name);
 
        if (dtv_cmds[tvp->cmd].buffer) {
                dev_dbg(fe->dvb->device, "%s: tvp.u.buffer.len = 0x%02x\n",
@@ -1589,7 +1595,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
                        return r;
        }
 
-       dtv_property_dump(fe, tvp);
+       dtv_property_dump(fe, false, tvp);
 
        return 0;
 }
@@ -1830,6 +1836,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
                        return r;
        }
 
+       dtv_property_dump(fe, true, tvp);
+
        switch(tvp->cmd) {
        case DTV_CLEAR:
                /*
@@ -2451,7 +2459,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
                        u8 last = 1;
                        if (dvb_frontend_debug)
                                printk("%s switch command: 0x%04lx\n", __func__, swcmd);
-                       nexttime = ktime_get_real();
+                       nexttime = ktime_get_boottime();
                        if (dvb_frontend_debug)
                                tv[0] = nexttime;
                        /* before sending a command, initialize by sending
@@ -2462,7 +2470,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
 
                        for (i = 0; i < 9; i++) {
                                if (dvb_frontend_debug)
-                                       tv[i+1] = ktime_get_real();
+                                       tv[i+1] = ktime_get_boottime();
                                if ((swcmd & 0x01) != last) {
                                        /* set voltage to (last ? 13V : 18V) */
                                        fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
index 560450a0b32a5b2399196aa2a9a8d0ff161534e9..1b9732ee0a4fbd4720289d336148941e4e0de550 100644 (file)
@@ -58,7 +58,7 @@ static const char * const dnames[] = {
 #define DVB_MAX_IDS            MAX_DVB_MINORS
 #else
 #define DVB_MAX_IDS            4
-#define nums2minor(num,type,id)        ((num << 6) | (id << 4) | type)
+#define nums2minor(num, type, id)      ((num << 6) | (id << 4) | type)
 #define MAX_DVB_MINORS         (DVB_MAX_ADAPTERS*64)
 #endif
 
@@ -85,7 +85,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
                file->private_data = dvbdev;
                replace_fops(file, new_fops);
                if (file->f_op->open)
-                       err = file->f_op->open(inode,file);
+                       err = file->f_op->open(inode, file);
                up_read(&minor_rwsem);
                mutex_unlock(&dvbdev_mutex);
                return err;
@@ -352,7 +352,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
        ret = media_device_register_entity(dvbdev->adapter->mdev,
                                           dvbdev->entity);
        if (ret)
-               return (ret);
+               return ret;
 
        printk(KERN_DEBUG "%s: media entity '%s' registered.\n",
                __func__, dvbdev->entity->name);
@@ -620,8 +620,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
                        return -ENOMEM;
                adap->conn = conn;
 
-               adap->conn_pads = kcalloc(1, sizeof(*adap->conn_pads),
-                                           GFP_KERNEL);
+               adap->conn_pads = kzalloc(sizeof(*adap->conn_pads), GFP_KERNEL);
                if (!adap->conn_pads)
                        return -ENOMEM;
 
@@ -661,7 +660,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
        if (ntuner && ndemod) {
                ret = media_create_pad_links(mdev,
                                             MEDIA_ENT_F_TUNER,
-                                            tuner, TUNER_PAD_IF_OUTPUT,
+                                            tuner, TUNER_PAD_OUTPUT,
                                             MEDIA_ENT_F_DTV_DEMOD,
                                             demod, 0, MEDIA_LNK_FL_ENABLED,
                                             false);
@@ -868,7 +867,7 @@ int dvb_usercopy(struct file *file,
                        parg = sbuf;
                } else {
                        /* too big to allocate from stack */
-                       mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
+                       mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
                        if (NULL == mbuf)
                                return -ENOMEM;
                        parg = mbuf;
index e23197da84af51bc244772d2dc2e7b01caf8eae9..41ab5defb7989b058bb42dfa90ecd972ded4381d 100644 (file)
@@ -1344,6 +1344,10 @@ err:
 static void af9013_release(struct dvb_frontend *fe)
 {
        struct af9013_state *state = fe->demodulator_priv;
+
+       /* stop statistics polling */
+       cancel_delayed_work_sync(&state->statistics_work);
+
        kfree(state);
 }
 
index bc35206a08215b83a6cf49719cfd1db9363af98c..8b328d1ca8d365f6cac693a443a80adee4e9041e 100644 (file)
@@ -1372,6 +1372,9 @@ static int af9033_remove(struct i2c_client *client)
 
        dev_dbg(&dev->client->dev, "\n");
 
+       /* stop statistics polling */
+       cancel_delayed_work_sync(&dev->stat_work);
+
        dev->fe.ops.release = NULL;
        dev->fe.demodulator_priv = NULL;
        kfree(dev);
index d30275f27644bd963d16329f117d73fc3364c15d..bb698839e477e23a07a04dbc15082cdd341d04f0 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001-5, B2C2 inc.
  *
- *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@posteo.de>
  *
  *  This driver is "hard-coded" to be used with the 1st generation of
  *  Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
@@ -865,5 +865,5 @@ static struct dvb_frontend_ops bcm3510_ops = {
 };
 
 MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_LICENSE("GPL");
index ff66492fb9408f5324c749d64638df67929d1077..961c2eb87c684a595ede26ac332a6889c8323309 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001-5, B2C2 inc.
  *
- *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@posteo.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3bb1bc2a04f006a43d849ad2dad914ffde425852..67f24686c31b9dd3306bc51c5271d9af25a47e11 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001-5, B2C2 inc.
  *
- *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@posteo.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 24a457d9d803372dd25ced70284bdab381c0d2f5..ba4cb7557aa577ce762ef455e26d30176ad004b8 100644 (file)
@@ -606,8 +606,7 @@ static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 static int cxd2820r_gpio_direction_output(struct gpio_chip *chip, unsigned nr,
                int val)
 {
-       struct cxd2820r_priv *priv =
-                       container_of(chip, struct cxd2820r_priv, gpio_chip);
+       struct cxd2820r_priv *priv = gpiochip_get_data(chip);
        u8 gpio[GPIO_COUNT];
 
        dev_dbg(&priv->i2c->dev, "%s: nr=%d val=%d\n", __func__, nr, val);
@@ -620,8 +619,7 @@ static int cxd2820r_gpio_direction_output(struct gpio_chip *chip, unsigned nr,
 
 static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
 {
-       struct cxd2820r_priv *priv =
-                       container_of(chip, struct cxd2820r_priv, gpio_chip);
+       struct cxd2820r_priv *priv = gpiochip_get_data(chip);
        u8 gpio[GPIO_COUNT];
 
        dev_dbg(&priv->i2c->dev, "%s: nr=%d val=%d\n", __func__, nr, val);
@@ -636,8 +634,7 @@ static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
 
 static int cxd2820r_gpio_get(struct gpio_chip *chip, unsigned nr)
 {
-       struct cxd2820r_priv *priv =
-                       container_of(chip, struct cxd2820r_priv, gpio_chip);
+       struct cxd2820r_priv *priv = gpiochip_get_data(chip);
 
        dev_dbg(&priv->i2c->dev, "%s: nr=%d\n", __func__, nr);
 
@@ -731,7 +728,7 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
                priv->gpio_chip.base = -1; /* dynamic allocation */
                priv->gpio_chip.ngpio = GPIO_COUNT;
                priv->gpio_chip.can_sleep = 1;
-               ret = gpiochip_add(&priv->gpio_chip);
+               ret = gpiochip_add_data(&priv->gpio_chip, priv);
                if (ret)
                        goto error;
 
index 0b8fb5dd18898a46c93348caabd4818ec4dbe37b..ee7d66997ccde63508b9f4ac1a626cd9c1f0f286 100644 (file)
@@ -774,6 +774,6 @@ free_mem:
 }
 EXPORT_SYMBOL(dib0070_attach);
 
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner");
 MODULE_LICENSE("GPL");
index 47cb72243b9da6bfc9c62271592633f2ecadc3db..976ee034a4307052a344c6c70592826a8b535641 100644 (file)
@@ -2669,7 +2669,7 @@ free_mem:
 }
 EXPORT_SYMBOL(dib0090_fw_register);
 
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
+MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
 MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
 MODULE_LICENSE("GPL");
index 6ae9899b5b450bec39a56601134accd686dbd990..d5dfafb4ef13b665a5439c9a68ce72eb69452486 100644 (file)
@@ -2,11 +2,11 @@
  * public header file of the frontend drivers for mobile DVB-T demodulators
  * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * based on GPL code from DibCom, which has
  *
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ * Copyright (C) 2004 Amaury Demol for DiBcom
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
@@ -14,7 +14,7 @@
  *
  * Acknowledgements
  *
- *  Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
+ *  Amaury Demol from DiBcom for providing specs and driver
  *  sources, on which this driver (and the dvb-dibusb) are based.
  *
  * see Documentation/dvb/README.dvb-usb for more information
index 7a61172d0d453b9aa38282dbb6cd97d239387080..3ca300939f790bb1c3ebaceca298932a19f1ac3c 100644 (file)
@@ -2,11 +2,11 @@
  * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
  * DiBcom (http://www.dibcom.fr/)
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * based on GPL code from DibCom, which has
  *
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ * Copyright (C) 2004 Amaury Demol for DiBcom
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
@@ -14,7 +14,7 @@
  *
  * Acknowledgements
  *
- *  Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
+ *  Amaury Demol from DiBcom for providing specs and driver
  *  sources, on which this driver (and the dvb-dibusb) are based.
  *
  * see Documentation/dvb/README.dvb-usb for more information
@@ -36,7 +36,7 @@
 /* Version information */
 #define DRIVER_VERSION "0.1"
 #define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
-#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
+#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@posteo.de"
 
 static int debug;
 module_param(debug, int, 0644);
index 9dc235aa44b71a712ba7c57918f9c786dd237e15..0459d5c84314e7cca51532d2e088ddd28b6cc130 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * dib3000mb_priv.h
  *
- * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
index 583d6b7fabedad77116565a8f948c0e10ec28318..ac90ed3af37e40a6a184dd7698a6f756140adddb 100644 (file)
@@ -2,7 +2,7 @@
  * Driver for DiBcom DiB3000MC/P-demodulator.
  *
  * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * This code is partially based on the previous dib3000mc.c .
  *
@@ -939,6 +939,6 @@ static struct dvb_frontend_ops dib3000mc_ops = {
        .read_ucblocks        = dib3000mc_read_unc_blocks,
 };
 
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
 MODULE_LICENSE("GPL");
index 74816f79361180c0191c4cdd69239121371543f5..b37e69e6a58c7ca63e05167780de8e9cadd86738 100644 (file)
@@ -2,7 +2,7 @@
  * Driver for DiBcom DiB3000MC/P-demodulator.
  *
  * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * This code is partially based on the previous dib3000mc.c .
  *
index 35eb71fe3c2b4977d5db8bf68e5f7b8039cb60da..8b21cccf3c3a04184629af11a30cb0d9c3d91d9b 100644 (file)
@@ -1465,6 +1465,6 @@ static struct dvb_frontend_ops dib7000m_ops = {
        .read_ucblocks        = dib7000m_read_unc_blocks,
 };
 
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
 MODULE_LICENSE("GPL");
index 33be5d6b9e10589275529a83525914ad6a33a470..65ab79ed5e3ecb3e3a00c31adbb6b7ca5e8e03b6 100644 (file)
@@ -2834,7 +2834,7 @@ static struct dvb_frontend_ops dib7000p_ops = {
        .read_ucblocks = dib7000p_read_unc_blocks,
 };
 
-MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Olivier Grenie <olivie.grenie@parrot.com>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
 MODULE_LICENSE("GPL");
index 94c26270fff0e98375161ddad5e9c0ae5fc8d2bd..349d2f1f62ce0341e2612d519b7d7ee3f043ed21 100644 (file)
@@ -4516,6 +4516,6 @@ void *dib8000_attach(struct dib8000_ops *ops)
 }
 EXPORT_SYMBOL(dib8000_attach);
 
-MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@parrot.com, Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
 MODULE_LICENSE("GPL");
index 8f92aca0b073555a40fa422b864ddb89646e0232..91888a2f53018bc2755a31d2a128560486226ce7 100644 (file)
@@ -2589,7 +2589,7 @@ static struct dvb_frontend_ops dib9000_ops = {
        .read_ucblocks = dib9000_read_unc_blocks,
 };
 
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
-MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
+MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
 MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");
 MODULE_LICENSE("GPL");
index 43be7238311ec513726e8ecaa13d0864c2b622dd..723358d7ca84debd209750f58a1423b1dd3861f9 100644 (file)
@@ -510,6 +510,6 @@ u32 systime(void)
 }
 EXPORT_SYMBOL(systime);
 
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
 MODULE_LICENSE("GPL");
index b792f305cf15f05fc1289a4bdd0566269bfd15e0..74b771218033d76dee58d151dca1addd54404b13 100644 (file)
@@ -900,6 +900,9 @@ static int rtl2830_remove(struct i2c_client *client)
 
        dev_dbg(&client->dev, "\n");
 
+       /* stop statistics polling */
+       cancel_delayed_work_sync(&dev->stat_work);
+
        i2c_del_mux_adapter(dev->adapter);
        regmap_exit(dev->regmap);
        kfree(dev);
index 2b93241d4bc102618c722107477b08482c7d86bb..8bf716a8ea58c2d5161ab66e08cae9ec1f1f3545 100644 (file)
@@ -225,22 +225,18 @@ static int si2165_writereg32(struct si2165_state *state, const u16 reg, u32 val)
 static int si2165_writereg_mask8(struct si2165_state *state, const u16 reg,
                                 u8 val, u8 mask)
 {
-       int ret;
-       u8 tmp;
-
        if (mask != 0xff) {
-               ret = si2165_readreg8(state, reg, &tmp);
+               u8 tmp;
+               int ret = si2165_readreg8(state, reg, &tmp);
+
                if (ret < 0)
-                       goto err;
+                       return ret;
 
                val &= mask;
                tmp &= ~mask;
                val |= tmp;
        }
-
-       ret = si2165_writereg8(state, reg, val);
-err:
-       return ret;
+       return si2165_writereg8(state, reg, val);
 }
 
 #define REG16(reg, val) { (reg), (val) & 0xff }, { (reg)+1, (val)>>8 & 0xff }
@@ -825,19 +821,19 @@ static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
        struct si2165_state *state = fe->demodulator_priv;
        u32 dvb_rate = 0;
        u16 bw10k;
+       u32 bw_hz = p->bandwidth_hz;
 
        dprintk("%s: called\n", __func__);
 
        if (!state->has_dvbt)
                return -EINVAL;
 
-       if (p->bandwidth_hz > 0) {
-               dvb_rate = p->bandwidth_hz * 8 / 7;
-               bw10k = p->bandwidth_hz / 10000;
-       } else {
-               dvb_rate = 8 * 8 / 7;
-               bw10k = 800;
-       }
+       /* no bandwidth auto-detection */
+       if (bw_hz == 0)
+               return -EINVAL;
+
+       dvb_rate = bw_hz * 8 / 7;
+       bw10k = bw_hz / 10000;
 
        ret = si2165_adjust_pll_divl(state, 12);
        if (ret < 0)
index a8177807fb6568f6d4a261c3509242ac8152b7b3..c43f36d323409b768c5dfbe2ff0fab22e03995af 100644 (file)
@@ -422,7 +422,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
        if (debug_legacy_dish_switch)
                printk ("%s switch command: 0x%04lx\n",__func__, cmd);
 
-       nexttime = ktime_get_real();
+       nexttime = ktime_get_boottime();
        if (debug_legacy_dish_switch)
                tv[0] = nexttime;
        stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
@@ -431,7 +431,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
 
        for (i=0; i<9; i++) {
                if (debug_legacy_dish_switch)
-                       tv[i+1] = ktime_get_real();
+                       tv[i+1] = ktime_get_boottime();
                if((cmd & 0x01) != last) {
                        /* set voltage to (last ? 13V : 18V) */
                        stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
index e66154e5c1d7710e0ddcc8c6183f707be0e388ea..a62c01e454f518399270443f0311106a39ef426b 100644 (file)
@@ -355,7 +355,7 @@ static struct dvb_tuner_ops stv6110x_ops = {
        .release                = stv6110x_release
 };
 
-static struct stv6110x_devctl stv6110x_ctl = {
+static const struct stv6110x_devctl stv6110x_ctl = {
        .tuner_init             = stv6110x_init,
        .tuner_sleep            = stv6110x_sleep,
        .tuner_set_mode         = stv6110x_set_mode,
@@ -369,7 +369,7 @@ static struct stv6110x_devctl stv6110x_ctl = {
        .tuner_get_status       = stv6110x_get_status,
 };
 
-struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
                                        const struct stv6110x_config *config,
                                        struct i2c_adapter *i2c)
 {
index 9f7eb251aec32cb0a6d7bf821000a95690674332..696b6e5b9e7be1969fc51d1fb482ad52f52b02e7 100644 (file)
@@ -55,12 +55,12 @@ struct stv6110x_devctl {
 
 #if IS_REACHABLE(CONFIG_DVB_STV6110x)
 
-extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+extern const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
                                               const struct stv6110x_config *config,
                                               struct i2c_adapter *i2c);
 
 #else
-static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
+static inline const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
                                                      const struct stv6110x_config *config,
                                                      struct i2c_adapter *i2c)
 {
index 0ec936a660a765801a60791f095981e27943946d..a993aba27b7ef33e8c7a48dc849950f737504b28 100644 (file)
@@ -70,7 +70,7 @@ struct stv6110x_state {
        const struct stv6110x_config    *config;
        u8                              regs[8];
 
-       struct stv6110x_devctl          *devctl;
+       const struct stv6110x_devctl    *devctl;
 };
 
 #endif /* __STV6110x_PRIV_H */
index 7979e5d6498b52a2c01f4db05a44079eeb5c3bb5..14b410ffe612c2d76381ab0177d82970384913e8 100644 (file)
@@ -712,6 +712,10 @@ static int ts2020_remove(struct i2c_client *client)
 
        dev_dbg(&client->dev, "\n");
 
+       /* stop statistics polling */
+       if (!dev->dont_poll)
+               cancel_delayed_work_sync(&dev->stat_work);
+
        regmap_exit(dev->regmap);
        kfree(dev);
        return 0;
index f8dd7505b5294ff167352a1d3ce8823605916db7..801a9b09d5e51e913089d4d29b8f19345730440e 100644 (file)
@@ -1884,6 +1884,26 @@ static int adv76xx_get_format(struct v4l2_subdev *sd,
        return 0;
 }
 
+static int adv76xx_get_selection(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_pad_config *cfg,
+                                struct v4l2_subdev_selection *sel)
+{
+       struct adv76xx_state *state = to_state(sd);
+
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+       /* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported */
+       if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS)
+               return -EINVAL;
+
+       sel->r.left     = 0;
+       sel->r.top      = 0;
+       sel->r.width    = state->timings.bt.width;
+       sel->r.height   = state->timings.bt.height;
+
+       return 0;
+}
+
 static int adv76xx_set_format(struct v4l2_subdev *sd,
                              struct v4l2_subdev_pad_config *cfg,
                              struct v4l2_subdev_format *format)
@@ -2404,6 +2424,7 @@ static const struct v4l2_subdev_video_ops adv76xx_video_ops = {
 
 static const struct v4l2_subdev_pad_ops adv76xx_pad_ops = {
        .enum_mbus_code = adv76xx_enum_mbus_code,
+       .get_selection = adv76xx_get_selection,
        .get_fmt = adv76xx_get_format,
        .set_fmt = adv76xx_set_format,
        .get_edid = adv76xx_get_edid,
@@ -2799,6 +2820,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
        struct device_node *endpoint;
        struct device_node *np;
        unsigned int flags;
+       int ret;
        u32 v;
 
        np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
@@ -2808,7 +2830,11 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
        if (!endpoint)
                return -EINVAL;
 
-       v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+       ret = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+       if (ret) {
+               of_node_put(endpoint);
+               return ret;
+       }
 
        if (!of_property_read_u32(endpoint, "default-input", &v))
                state->pdata.default_input = v;
index a84561d0d4a809c761c5ed51d58af93aa7737dd7..e016626ebf89b25de49a282582676bcd710b10c2 100644 (file)
@@ -688,6 +688,9 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
        int msp_revision;
        int msp_product, msp_prod_hi, msp_prod_lo;
        int msp_rom;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       int ret;
+#endif
 
        if (!id)
                strlcpy(client->name, "msp3400", sizeof(client->name));
@@ -704,6 +707,17 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
        sd = &state->sd;
        v4l2_i2c_subdev_init(sd, client, &msp_ops);
 
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       state->pads[IF_AUD_DEC_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+       state->pads[IF_AUD_DEC_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
+
+       sd->entity.function = MEDIA_ENT_F_IF_AUD_DECODER;
+
+       ret = media_entity_pads_init(&sd->entity, 2, state->pads);
+       if (ret < 0)
+               return ret;
+#endif
+
        state->v4l2_std = V4L2_STD_NTSC;
        state->detected_std = V4L2_STD_ALL;
        state->audmode = V4L2_TUNER_MODE_STEREO;
index 6cae21366ed5e6b4ab7003dee04ba6504be05652..a8702aca187a97176eac9c4b2795e1b9c2969872 100644 (file)
@@ -7,6 +7,7 @@
 #include <media/drv-intf/msp3400.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-mc.h>
 
 /* ---------------------------------------------------------------------- */
 
@@ -102,6 +103,10 @@ struct msp_state {
        wait_queue_head_t    wq;
        unsigned int         restart:1;
        unsigned int         watch_stereo:1;
+
+#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
+       struct media_pad pads[IF_AUD_DEC_PAD_NUM_PADS];
+#endif
 };
 
 static inline struct msp_state *to_state(struct v4l2_subdev *sd)
index b9fea11d6b0b0e08ff2c4440f976a97a077aaa99..9ed1b26b6549822a46338f6ce2b826147f3903c4 100644 (file)
@@ -50,6 +50,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
 
 struct mt9v011 {
        struct v4l2_subdev sd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct media_pad pad;
+#endif
        struct v4l2_ctrl_handler ctrls;
        unsigned width, height;
        unsigned xtal;
@@ -493,6 +496,9 @@ static int mt9v011_probe(struct i2c_client *c,
        u16 version;
        struct mt9v011 *core;
        struct v4l2_subdev *sd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+       int ret;
+#endif
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(c->adapter,
@@ -506,6 +512,15 @@ static int mt9v011_probe(struct i2c_client *c,
        sd = &core->sd;
        v4l2_i2c_subdev_init(sd, c, &mt9v011_ops);
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+       core->pad.flags = MEDIA_PAD_FL_SOURCE;
+       sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+       ret = media_entity_pads_init(&sd->entity, 1, &core->pad);
+       if (ret < 0)
+               return ret;
+#endif
+
        /* Check if the sensor is really a MT9V011 */
        version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
        if ((version != MT9V011_VERSION) &&
index 2e1d116a64e7b43eb1f6e886f842d9ef296664c9..501b37039449730411ad1673da7f4458d15ce373 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
 #include <linux/mutex.h>
@@ -251,6 +252,8 @@ struct mt9v032 {
 
        struct regmap *regmap;
        struct clk *clk;
+       struct gpio_desc *reset_gpio;
+       struct gpio_desc *standby_gpio;
 
        struct mt9v032_platform_data *pdata;
        const struct mt9v032_model_info *model;
@@ -312,16 +315,31 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
        struct regmap *map = mt9v032->regmap;
        int ret;
 
+       if (mt9v032->reset_gpio)
+               gpiod_set_value_cansleep(mt9v032->reset_gpio, 1);
+
        ret = clk_set_rate(mt9v032->clk, mt9v032->sysclk);
        if (ret < 0)
                return ret;
 
+       /* System clock has to be enabled before releasing the reset */
        ret = clk_prepare_enable(mt9v032->clk);
        if (ret)
                return ret;
 
        udelay(1);
 
+       if (mt9v032->reset_gpio) {
+               gpiod_set_value_cansleep(mt9v032->reset_gpio, 0);
+
+               /* After releasing reset we need to wait 10 clock cycles
+                * before accessing the sensor over I2C. As the minimum SYSCLK
+                * frequency is 13MHz, waiting 1µs will be enough in the worst
+                * case.
+                */
+               udelay(1);
+       }
+
        /* Reset the chip and stop data read out */
        ret = regmap_write(map, MT9V032_RESET, 1);
        if (ret < 0)
@@ -954,6 +972,16 @@ static int mt9v032_probe(struct i2c_client *client,
        if (IS_ERR(mt9v032->clk))
                return PTR_ERR(mt9v032->clk);
 
+       mt9v032->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+                                                     GPIOD_OUT_HIGH);
+       if (IS_ERR(mt9v032->reset_gpio))
+               return PTR_ERR(mt9v032->reset_gpio);
+
+       mt9v032->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby",
+                                                       GPIOD_OUT_LOW);
+       if (IS_ERR(mt9v032->standby_gpio))
+               return PTR_ERR(mt9v032->standby_gpio);
+
        mutex_init(&mt9v032->power_lock);
        mt9v032->pdata = pdata;
        mt9v032->model = (const void *)did->driver_data;
index 02b9a3440557b49e9ad7dd366d201ebcd6e962ed..1f999e9c0118e358ac111c17084c21799a677db0 100644 (file)
@@ -1321,10 +1321,6 @@ static int ov2659_detect(struct v4l2_subdev *sd)
        }
        usleep_range(1000, 2000);
 
-       ret = ov2659_init(sd, 0);
-       if (ret < 0)
-               return ret;
-
        /* Check sensor revision */
        ret = ov2659_read(client, REG_SC_CHIP_ID_H, &pid);
        if (!ret)
@@ -1338,8 +1334,10 @@ static int ov2659_detect(struct v4l2_subdev *sd)
                        dev_err(&client->dev,
                                "Sensor detection failed (%04X, %d)\n",
                                id, ret);
-               else
+               else {
                        dev_info(&client->dev, "Found OV%04X sensor\n", id);
+                       ret = ov2659_init(sd, 0);
+               }
        }
 
        return ret;
index 57b3d27993a40ffadf7d42a5b791e71f3f74eb76..08af58fb8e7d0089a410b8ceb1e4c2466ba9f9da 100644 (file)
@@ -1639,8 +1639,10 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
                return 0;
        }
 
-       v4l2_of_parse_endpoint(node_ep, &ep);
+       ret = v4l2_of_parse_endpoint(node_ep, &ep);
        of_node_put(node_ep);
+       if (ret)
+               return ret;
 
        if (ep.bus_type != V4L2_MBUS_CSI2) {
                dev_err(dev, "unsupported bus type\n");
index 7d65b36434b1f3ccfccf25a7ff2071821080ff4b..72ef9f936e6ceb13ad7b94e5c998ffa9543700e8 100644 (file)
@@ -37,7 +37,6 @@ enum spi_direction {
        SPI_DIR_RX,
        SPI_DIR_TX
 };
-MODULE_DEVICE_TABLE(of, s5c73m3_spi_ids);
 
 static int spi_xmit(struct spi_device *spi_dev, void *addr, const int len,
                                                        enum spi_direction dir)
index fc3a5a8e6c9c7ebafb5b8a3ba97e1fa7cbe564fd..db82ed05792ef7d21c99879c7cd38e9a754af0fe 100644 (file)
@@ -1868,8 +1868,11 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
                return -EINVAL;
        }
 
-       v4l2_of_parse_endpoint(node_ep, &ep);
+       ret = v4l2_of_parse_endpoint(node_ep, &ep);
        of_node_put(node_ep);
+       if (ret)
+               return ret;
+
        state->bus_type = ep.bus_type;
 
        switch (state->bus_type) {
index 24d2b76dbe97e7a24d762b2bc58a6ba2bc2c6051..d2a1ce2bc7f5ce41eec4c1c6d5069280c358df5d 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-mc.h>
 #include <media/i2c/saa7115.h>
 #include <asm/div64.h>
 
@@ -74,6 +75,9 @@ enum saa711x_model {
 
 struct saa711x_state {
        struct v4l2_subdev sd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct media_pad pads[DEMOD_NUM_PADS];
+#endif
        struct v4l2_ctrl_handler hdl;
 
        struct {
@@ -1809,6 +1813,9 @@ static int saa711x_probe(struct i2c_client *client,
        struct saa7115_platform_data *pdata;
        int ident;
        char name[CHIP_VER_SIZE + 1];
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       int ret;
+#endif
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -1832,6 +1839,18 @@ static int saa711x_probe(struct i2c_client *client,
        sd = &state->sd;
        v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
 
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+       state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
+
+       sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
+
+       ret = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, state->pads);
+       if (ret < 0)
+               return ret;
+#endif
+
        v4l_info(client, "%s found @ 0x%x (%s)\n", name,
                 client->addr << 1, client->adapter->name);
        hdl = &state->hdl;
index 2e14e52ba2e056a071d0f1e4e02538569e446af5..69becc358659cf25dc6a4ccf7ddf0d2dbbe9573d 100644 (file)
@@ -632,7 +632,7 @@ static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
        .s_mbus_config  = mt9m001_s_mbus_config,
 };
 
-static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
+static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
        .g_skip_top_lines       = mt9m001_g_skip_top_lines,
 };
 
index 3b6eeed2e2b96d9457b0c0a09eeef88d1697c8ef..5c8e3ffe3b27bff0b69c51d218cd68e7f3001d0e 100644 (file)
@@ -728,7 +728,7 @@ static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
        .s_mbus_config  = mt9t031_s_mbus_config,
 };
 
-static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
+static const struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
        .g_skip_top_lines       = mt9t031_g_skip_top_lines,
 };
 
index c2ba1fb3694dfe78a874186d50b042c60bdde7dd..2721e583bfa0b239c3f36b7cb8d3efa6affc53a4 100644 (file)
@@ -860,7 +860,7 @@ static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
        .s_mbus_config  = mt9v022_s_mbus_config,
 };
 
-static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
+static const struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
        .g_skip_top_lines       = mt9v022_g_skip_top_lines,
 };
 
index 3397eb99c67b0269beecf3cc47c0076758d53885..da7469bc6e56fa8ede646e5aa7846f5a931e044f 100644 (file)
@@ -59,8 +59,7 @@ MODULE_LICENSE("GPL");
 #define EDID_NUM_BLOCKS_MAX 8
 #define EDID_BLOCK_SIZE 128
 
-/* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE  (EDID_NUM_BLOCKS_MAX * EDID_BLOCK_SIZE + 2)
+#define I2C_MAX_XFER_SIZE  (EDID_BLOCK_SIZE + 2)
 
 static const struct v4l2_dv_timings_cap tc358743_timings_cap = {
        .type = V4L2_DV_BT_656_1120,
@@ -97,9 +96,6 @@ struct tc358743_state {
        /* edid  */
        u8 edid_blocks_written;
 
-       /* used by i2c_wr() */
-       u8 wr_data[MAX_XFER_SIZE];
-
        struct v4l2_dv_timings timings;
        u32 mbus_fmt_code;
 
@@ -149,13 +145,15 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
 {
        struct tc358743_state *state = to_state(sd);
        struct i2c_client *client = state->i2c_client;
-       u8 *data = state->wr_data;
        int err, i;
        struct i2c_msg msg;
+       u8 data[I2C_MAX_XFER_SIZE];
 
-       if ((2 + n) > sizeof(state->wr_data))
+       if ((2 + n) > I2C_MAX_XFER_SIZE) {
+               n = I2C_MAX_XFER_SIZE - 2;
                v4l2_warn(sd, "i2c wr reg=%04x: len=%d is too big!\n",
                          reg, 2 + n);
+       }
 
        msg.addr = client->addr;
        msg.buf = data;
@@ -859,15 +857,16 @@ static void tc358743_format_change(struct v4l2_subdev *sd)
        if (tc358743_get_detected_timings(sd, &timings)) {
                enable_stream(sd, false);
 
-               v4l2_dbg(1, debug, sd, "%s: Format changed. No signal\n",
+               v4l2_dbg(1, debug, sd, "%s: No signal\n",
                                __func__);
        } else {
                if (!v4l2_match_dv_timings(&state->timings, &timings, 0, false))
                        enable_stream(sd, false);
 
-               v4l2_print_dv_timings(sd->name,
-                               "tc358743_format_change: Format changed. New format: ",
-                               &timings, false);
+               if (debug)
+                       v4l2_print_dv_timings(sd->name,
+                                       "tc358743_format_change: New format: ",
+                                       &timings, false);
        }
 
        if (sd->devnode)
@@ -1581,6 +1580,7 @@ static int tc358743_s_edid(struct v4l2_subdev *sd,
 {
        struct tc358743_state *state = to_state(sd);
        u16 edid_len = edid->blocks * EDID_BLOCK_SIZE;
+       int i;
 
        v4l2_dbg(2, debug, sd, "%s, pad %d, start block %d, blocks %d\n",
                 __func__, edid->pad, edid->start_block, edid->blocks);
@@ -1606,7 +1606,8 @@ static int tc358743_s_edid(struct v4l2_subdev *sd,
                return 0;
        }
 
-       i2c_wr(sd, EDID_RAM, edid->edid, edid_len);
+       for (i = 0; i < edid_len; i += EDID_BLOCK_SIZE)
+               i2c_wr(sd, EDID_RAM + i, edid->edid + i, EDID_BLOCK_SIZE);
 
        state->edid_blocks_written = edid->blocks;
 
index 7fa5f1e4fe3798155011263f9e4bdd0ad6b2955c..7cdd94842938e6d923fc9ed209f98556e242a9bc 100644 (file)
@@ -1001,7 +1001,7 @@ static struct tvp514x_decoder tvp514x_dev = {
 static struct tvp514x_platform_data *
 tvp514x_get_pdata(struct i2c_client *client)
 {
-       struct tvp514x_platform_data *pdata;
+       struct tvp514x_platform_data *pdata = NULL;
        struct v4l2_of_endpoint bus_cfg;
        struct device_node *endpoint;
        unsigned int flags;
@@ -1013,11 +1013,13 @@ tvp514x_get_pdata(struct i2c_client *client)
        if (!endpoint)
                return NULL;
 
+       if (v4l2_of_parse_endpoint(endpoint, &bus_cfg))
+               goto done;
+
        pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                goto done;
 
-       v4l2_of_parse_endpoint(endpoint, &bus_cfg);
        flags = bus_cfg.bus.parallel.flags;
 
        if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
index 6c3769d44b75ccf6cc113dece96d2ab2e6244b2b..19b52736b24e97236abf849bc1d1650410594d90 100644 (file)
@@ -9,11 +9,14 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
 #include <media/i2c/tvp5150.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-of.h>
+#include <media/v4l2-mc.h>
 
 #include "tvp5150_reg.h"
 
@@ -35,6 +38,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
 
 struct tvp5150 {
        struct v4l2_subdev sd;
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct media_pad pads[DEMOD_NUM_PADS];
+#endif
        struct v4l2_ctrl_handler hdl;
        struct v4l2_rect rect;
 
@@ -42,6 +48,8 @@ struct tvp5150 {
        u32 input;
        u32 output;
        int enable;
+
+       enum v4l2_mbus_type mbus_type;
 };
 
 static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
@@ -772,6 +780,10 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
        v4l2_ctrl_handler_setup(&decoder->hdl);
 
        tvp5150_set_std(sd, decoder->norm);
+
+       if (decoder->mbus_type == V4L2_MBUS_PARALLEL)
+               tvp5150_write(sd, TVP5150_DATA_RATE_SEL, 0x40);
+
        return 0;
 };
 
@@ -818,17 +830,6 @@ static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
        }
 }
 
-static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd,
-               struct v4l2_subdev_pad_config *cfg,
-               struct v4l2_subdev_mbus_code_enum *code)
-{
-       if (code->pad || code->index)
-               return -EINVAL;
-
-       code->code = MEDIA_BUS_FMT_UYVY8_2X8;
-       return 0;
-}
-
 static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
                struct v4l2_subdev_pad_config *cfg,
                struct v4l2_subdev_format *format)
@@ -844,10 +845,10 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
        tvp5150_reset(sd, 0);
 
        f->width = decoder->rect.width;
-       f->height = decoder->rect.height;
+       f->height = decoder->rect.height / 2;
 
        f->code = MEDIA_BUS_FMT_UYVY8_2X8;
-       f->field = V4L2_FIELD_SEQ_TB;
+       f->field = V4L2_FIELD_ALTERNATE;
        f->colorspace = V4L2_COLORSPACE_SMPTE170M;
 
        v4l2_dbg(1, debug, sd, "width = %d, height = %d\n", f->width,
@@ -948,10 +949,76 @@ static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
        return 0;
 }
 
+static int tvp5150_g_mbus_config(struct v4l2_subdev *sd,
+                                struct v4l2_mbus_config *cfg)
+{
+       struct tvp5150 *decoder = to_tvp5150(sd);
+
+       cfg->type = decoder->mbus_type;
+       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING
+                  | V4L2_MBUS_FIELD_EVEN_LOW | V4L2_MBUS_DATA_ACTIVE_HIGH;
+
+       return 0;
+}
+
+/****************************************************************************
+                       V4L2 subdev pad ops
+ ****************************************************************************/
+static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd,
+               struct v4l2_subdev_pad_config *cfg,
+               struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->pad || code->index)
+               return -EINVAL;
+
+       code->code = MEDIA_BUS_FMT_UYVY8_2X8;
+       return 0;
+}
+
+static int tvp5150_enum_frame_size(struct v4l2_subdev *sd,
+                                  struct v4l2_subdev_pad_config *cfg,
+                                  struct v4l2_subdev_frame_size_enum *fse)
+{
+       struct tvp5150 *decoder = to_tvp5150(sd);
+
+       if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_UYVY8_2X8)
+               return -EINVAL;
+
+       fse->code = MEDIA_BUS_FMT_UYVY8_2X8;
+       fse->min_width = decoder->rect.width;
+       fse->max_width = decoder->rect.width;
+       fse->min_height = decoder->rect.height / 2;
+       fse->max_height = decoder->rect.height / 2;
+
+       return 0;
+}
+
 /****************************************************************************
                        I2C Command
  ****************************************************************************/
 
+static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       struct tvp5150 *decoder = to_tvp5150(sd);
+       /* Output format: 8-bit ITU-R BT.656 with embedded syncs */
+       int val = 0x09;
+
+       /* Output format: 8-bit 4:2:2 YUV with discrete sync */
+       if (decoder->mbus_type == V4L2_MBUS_PARALLEL)
+               val = 0x0d;
+
+       /* Initializes TVP5150 to its default values */
+       /* # set PCLK (27MHz) */
+       tvp5150_write(sd, TVP5150_CONF_SHARED_PIN, 0x00);
+
+       if (enable)
+               tvp5150_write(sd, TVP5150_MISC_CTL, val);
+       else
+               tvp5150_write(sd, TVP5150_MISC_CTL, 0x00);
+
+       return 0;
+}
+
 static int tvp5150_s_routing(struct v4l2_subdev *sd,
                             u32 input, u32 output, u32 config)
 {
@@ -1073,10 +1140,12 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
 
 static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
        .s_std = tvp5150_s_std,
+       .s_stream = tvp5150_s_stream,
        .s_routing = tvp5150_s_routing,
        .s_crop = tvp5150_s_crop,
        .g_crop = tvp5150_g_crop,
        .cropcap = tvp5150_cropcap,
+       .g_mbus_config = tvp5150_g_mbus_config,
 };
 
 static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
@@ -1088,6 +1157,7 @@ static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
 
 static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = {
        .enum_mbus_code = tvp5150_enum_mbus_code,
+       .enum_frame_size = tvp5150_enum_frame_size,
        .set_fmt = tvp5150_fill_fmt,
        .get_fmt = tvp5150_fill_fmt,
 };
@@ -1105,63 +1175,167 @@ static const struct v4l2_subdev_ops tvp5150_ops = {
                        I2C Client & Driver
  ****************************************************************************/
 
+static int tvp5150_detect_version(struct tvp5150 *core)
+{
+       struct v4l2_subdev *sd = &core->sd;
+       struct i2c_client *c = v4l2_get_subdevdata(sd);
+       unsigned int i;
+       u16 dev_id;
+       u16 rom_ver;
+       u8 regs[4];
+       int res;
+
+       /*
+        * Read consequent registers - TVP5150_MSB_DEV_ID, TVP5150_LSB_DEV_ID,
+        * TVP5150_ROM_MAJOR_VER, TVP5150_ROM_MINOR_VER
+        */
+       for (i = 0; i < 4; i++) {
+               res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
+               if (res < 0)
+                       return res;
+               regs[i] = res;
+       }
+
+       dev_id = (regs[0] << 8) | regs[1];
+       rom_ver = (regs[2] << 8) | regs[3];
+
+       v4l2_info(sd, "tvp%04x (%u.%u) chip found @ 0x%02x (%s)\n",
+                 dev_id, regs[2], regs[3], c->addr << 1, c->adapter->name);
+
+       if (dev_id == 0x5150 && rom_ver == 0x0321) { /* TVP51510A */
+               v4l2_info(sd, "tvp5150a detected.\n");
+       } else if (dev_id == 0x5150 && rom_ver == 0x0400) { /* TVP5150AM1 */
+               v4l2_info(sd, "tvp5150am1 detected.\n");
+
+               /* ITU-T BT.656.4 timing */
+               tvp5150_write(sd, TVP5150_REV_SELECT, 0);
+       } else if (dev_id == 0x5151 && rom_ver == 0x0100) { /* TVP5151 */
+               v4l2_info(sd, "tvp5151 detected.\n");
+       } else {
+               v4l2_info(sd, "*** unknown tvp%04x chip detected.\n", dev_id);
+       }
+
+       return 0;
+}
+
+static int tvp5150_init(struct i2c_client *c)
+{
+       struct gpio_desc *pdn_gpio;
+       struct gpio_desc *reset_gpio;
+
+       pdn_gpio = devm_gpiod_get_optional(&c->dev, "pdn", GPIOD_OUT_HIGH);
+       if (IS_ERR(pdn_gpio))
+               return PTR_ERR(pdn_gpio);
+
+       if (pdn_gpio) {
+               gpiod_set_value_cansleep(pdn_gpio, 0);
+               /* Delay time between power supplies active and reset */
+               msleep(20);
+       }
+
+       reset_gpio = devm_gpiod_get_optional(&c->dev, "reset", GPIOD_OUT_HIGH);
+       if (IS_ERR(reset_gpio))
+               return PTR_ERR(reset_gpio);
+
+       if (reset_gpio) {
+               /* RESETB pulse duration */
+               ndelay(500);
+               gpiod_set_value_cansleep(reset_gpio, 0);
+               /* Delay time between end of reset to I2C active */
+               usleep_range(200, 250);
+       }
+
+       return 0;
+}
+
+static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
+{
+       struct v4l2_of_endpoint bus_cfg;
+       struct device_node *ep;
+       unsigned int flags;
+       int ret = 0;
+
+       ep = of_graph_get_next_endpoint(np, NULL);
+       if (!ep)
+               return -EINVAL;
+
+       ret = v4l2_of_parse_endpoint(ep, &bus_cfg);
+       if (ret)
+               goto err;
+
+       flags = bus_cfg.bus.parallel.flags;
+
+       if (bus_cfg.bus_type == V4L2_MBUS_PARALLEL &&
+           !(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH &&
+             flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH &&
+             flags & V4L2_MBUS_FIELD_EVEN_LOW))
+               return -EINVAL;
+
+       decoder->mbus_type = bus_cfg.bus_type;
+
+err:
+       of_node_put(ep);
+       return ret;
+}
+
 static int tvp5150_probe(struct i2c_client *c,
                         const struct i2c_device_id *id)
 {
        struct tvp5150 *core;
        struct v4l2_subdev *sd;
-       int tvp5150_id[4];
-       int i, res;
+       struct device_node *np = c->dev.of_node;
+       int res;
 
        /* Check if the adapter supports the needed features */
        if (!i2c_check_functionality(c->adapter,
             I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
                return -EIO;
 
+       res = tvp5150_init(c);
+       if (res)
+               return res;
+
        core = devm_kzalloc(&c->dev, sizeof(*core), GFP_KERNEL);
        if (!core)
                return -ENOMEM;
+
        sd = &core->sd;
-       v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
 
-       /* 
-        * Read consequent registers - TVP5150_MSB_DEV_ID, TVP5150_LSB_DEV_ID,
-        * TVP5150_ROM_MAJOR_VER, TVP5150_ROM_MINOR_VER 
-        */
-       for (i = 0; i < 4; i++) {
-               res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
-               if (res < 0)
+       if (IS_ENABLED(CONFIG_OF) && np) {
+               res = tvp5150_parse_dt(core, np);
+               if (res) {
+                       v4l2_err(sd, "DT parsing error: %d\n", res);
                        return res;
-               tvp5150_id[i] = res;
+               }
+       } else {
+               /* Default to BT.656 embedded sync */
+               core->mbus_type = V4L2_MBUS_BT656;
        }
 
-       v4l_info(c, "chip found @ 0x%02x (%s)\n",
-                c->addr << 1, c->adapter->name);
+       v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
+       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
-       if (tvp5150_id[2] == 4 && tvp5150_id[3] == 0) { /* Is TVP5150AM1 */
-               v4l2_info(sd, "tvp%02x%02xam1 detected.\n",
-                         tvp5150_id[0], tvp5150_id[1]);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+       core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+       core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
 
-               /* ITU-T BT.656.4 timing */
-               tvp5150_write(sd, TVP5150_REV_SELECT, 0);
-       } else {
-               /* Is TVP5150A */
-               if (tvp5150_id[2] == 3 || tvp5150_id[3] == 0x21) {
-                       v4l2_info(sd, "tvp%02x%02xa detected.\n",
-                                 tvp5150_id[0], tvp5150_id[1]);
-               } else {
-                       v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
-                                 tvp5150_id[0], tvp5150_id[1]);
-                       v4l2_info(sd, "*** Rom ver is %d.%d\n",
-                                 tvp5150_id[2], tvp5150_id[3]);
-               }
-       }
+       sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
+
+       res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
+       if (res < 0)
+               return res;
+#endif
+
+       res = tvp5150_detect_version(core);
+       if (res < 0)
+               return res;
 
        core->norm = V4L2_STD_ALL;      /* Default is autodetect */
        core->input = TVP5150_COMPOSITE1;
        core->enable = 1;
 
-       v4l2_ctrl_handler_init(&core->hdl, 4);
+       v4l2_ctrl_handler_init(&core->hdl, 5);
        v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
                        V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
        v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
@@ -1170,6 +1344,9 @@ static int tvp5150_probe(struct i2c_client *c,
                        V4L2_CID_SATURATION, 0, 255, 1, 128);
        v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
                        V4L2_CID_HUE, -128, 127, 1, 0);
+       v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
+                       V4L2_CID_PIXEL_RATE, 27000000,
+                       27000000, 1, 27000000);
        sd->ctrl_handler = &core->hdl;
        if (core->hdl.error) {
                res = core->hdl.error;
@@ -1221,8 +1398,17 @@ static const struct i2c_device_id tvp5150_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, tvp5150_id);
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id tvp5150_of_match[] = {
+       { .compatible = "ti,tvp5150", },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, tvp5150_of_match);
+#endif
+
 static struct i2c_driver tvp5150_driver = {
        .driver = {
+               .of_match_table = of_match_ptr(tvp5150_of_match),
                .name   = "tvp5150",
        },
        .probe          = tvp5150_probe,
index 83c79fa5f61de1b7155cb42ff69672f87036b5ba..4df640c3aa40fde3eecf4206233e1aa04745f12d 100644 (file)
@@ -894,7 +894,7 @@ static struct tvp7002_config *
 tvp7002_get_pdata(struct i2c_client *client)
 {
        struct v4l2_of_endpoint bus_cfg;
-       struct tvp7002_config *pdata;
+       struct tvp7002_config *pdata = NULL;
        struct device_node *endpoint;
        unsigned int flags;
 
@@ -905,11 +905,13 @@ tvp7002_get_pdata(struct i2c_client *client)
        if (!endpoint)
                return NULL;
 
+       if (v4l2_of_parse_endpoint(endpoint, &bus_cfg))
+               goto done;
+
        pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                goto done;
 
-       v4l2_of_parse_endpoint(endpoint, &bus_cfg);
        flags = bus_cfg.bus.parallel.flags;
 
        if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
index 4b564f17f618e38664d9cdffc8992fe6cf61a737..90b693f4e2ab84b4da6b68bf79f5b24fab65149d 100644 (file)
@@ -124,7 +124,7 @@ static int vpx3220_fp_write(struct v4l2_subdev *sd, u8 fpaddr, u16 data)
        return 0;
 }
 
-static u16 vpx3220_fp_read(struct v4l2_subdev *sd, u16 fpaddr)
+static int vpx3220_fp_read(struct v4l2_subdev *sd, u16 fpaddr)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        s16 data;
index 7dae0ac0f3aec12c5d44875111d3a69818e43c92..4d1c13de494bfb9f7a4957311225211250480b5d 100644 (file)
@@ -234,7 +234,6 @@ static long media_device_setup_link(struct media_device *mdev,
        return ret;
 }
 
-#if 0 /* Let's postpone it to Kernel 4.6 */
 static long __media_device_get_topology(struct media_device *mdev,
                                      struct media_v2_topology *topo)
 {
@@ -390,7 +389,6 @@ static long media_device_get_topology(struct media_device *mdev,
 
        return 0;
 }
-#endif
 
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
                               unsigned long arg)
@@ -424,14 +422,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
                mutex_unlock(&dev->graph_mutex);
                break;
 
-#if 0 /* Let's postpone it to Kernel 4.6 */
        case MEDIA_IOC_G_TOPOLOGY:
                mutex_lock(&dev->graph_mutex);
                ret = media_device_get_topology(dev,
                                (struct media_v2_topology __user *)arg);
                mutex_unlock(&dev->graph_mutex);
                break;
-#endif
+
        default:
                ret = -ENOIOCTLCMD;
        }
@@ -480,9 +477,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
        case MEDIA_IOC_DEVICE_INFO:
        case MEDIA_IOC_ENUM_ENTITIES:
        case MEDIA_IOC_SETUP_LINK:
-#if 0 /* Let's postpone it to Kernel 4.6 */
        case MEDIA_IOC_G_TOPOLOGY:
-#endif
                return media_device_ioctl(filp, cmd, arg);
 
        case MEDIA_IOC_ENUM_LINKS32:
index cea35bf2001170d7ca0471e1d51e5fe9eae8211e..29409f440f1caef38f82694b382d3b66a3895ffb 100644 (file)
@@ -181,6 +181,7 @@ static int media_open(struct inode *inode, struct file *filp)
                ret = mdev->fops->open(filp);
                if (ret) {
                        put_device(&mdev->dev);
+                       filp->private_data = NULL;
                        return ret;
                }
        }
index e89d85a7d31b56286a6d8c9d492b5565dc6a4d43..f2e43603d6d24f6a3c27105369187a73d61d8175 100644 (file)
@@ -452,9 +452,12 @@ error:
        media_entity_graph_walk_start(graph, entity_err);
 
        while ((entity_err = media_entity_graph_walk_next(graph))) {
-               entity_err->stream_count--;
-               if (entity_err->stream_count == 0)
-                       entity_err->pipe = NULL;
+               /* don't let the stream_count go negative */
+               if (entity->stream_count > 0) {
+                       entity_err->stream_count--;
+                       if (entity_err->stream_count == 0)
+                               entity_err->pipe = NULL;
+               }
 
                /*
                 * We haven't increased stream_count further than this
@@ -486,9 +489,12 @@ void media_entity_pipeline_stop(struct media_entity *entity)
        media_entity_graph_walk_start(graph, entity);
 
        while ((entity = media_entity_graph_walk_next(graph))) {
-               entity->stream_count--;
-               if (entity->stream_count == 0)
-                       entity->pipe = NULL;
+               /* don't let the stream_count go negative */
+               if (entity->stream_count > 0) {
+                       entity->stream_count--;
+                       if (entity->stream_count == 0)
+                               entity->pipe = NULL;
+               }
        }
 
        if (!--pipe->streaming_count)
index 8b5e0b3a92a0c4a408af8bc50217279065b78803..4cac1fc233f28fd0a99e58f923a216482b63d90a 100644 (file)
@@ -39,7 +39,7 @@ MODULE_PARM_DESC(debug,
 
 #define DRIVER_VERSION "0.1"
 #define DRIVER_NAME "flexcop-pci"
-#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@posteo.de>"
 
 struct flexcop_pci {
        struct pci_dev *pdev;
index 9400e996087b6a5eb5076cd7e0ab399f2bed0e9e..2c412377507bc16f13468f524b566618f5d7f76d 100644 (file)
@@ -186,7 +186,7 @@ MODULE_VERSION(BTTV_VERSION);
 static ssize_t show_card(struct device *cd,
                         struct device_attribute *attr, char *buf)
 {
-       struct video_device *vfd = container_of(cd, struct video_device, dev);
+       struct video_device *vfd = to_video_device(cd);
        struct bttv *btv = video_get_drvdata(vfd);
        return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
 }
@@ -1726,22 +1726,15 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id id)
        struct bttv_fh *fh  = priv;
        struct bttv *btv = fh->btv;
        unsigned int i;
-       int err = 0;
 
        for (i = 0; i < BTTV_TVNORMS; i++)
                if (id & bttv_tvnorms[i].v4l2_id)
                        break;
-       if (i == BTTV_TVNORMS) {
-               err = -EINVAL;
-               goto err;
-       }
-
+       if (i == BTTV_TVNORMS)
+               return -EINVAL;
        btv->std = id;
        set_tvnorm(btv, i);
-
-err:
-
-       return err;
+       return 0;
 }
 
 static int bttv_g_std(struct file *file, void *priv, v4l2_std_id *id)
@@ -1770,12 +1763,9 @@ static int bttv_enum_input(struct file *file, void *priv,
 {
        struct bttv_fh *fh = priv;
        struct bttv *btv = fh->btv;
-       int rc = 0;
 
-       if (i->index >= bttv_tvcards[btv->c.type].video_inputs) {
-               rc = -EINVAL;
-               goto err;
-       }
+       if (i->index >= bttv_tvcards[btv->c.type].video_inputs)
+               return -EINVAL;
 
        i->type     = V4L2_INPUT_TYPE_CAMERA;
        i->audioset = 0;
@@ -1799,10 +1789,7 @@ static int bttv_enum_input(struct file *file, void *priv,
        }
 
        i->std = BTTV_NORMS;
-
-err:
-
-       return rc;
+       return 0;
 }
 
 static int bttv_g_input(struct file *file, void *priv, unsigned int *i)
index d407244fd1bce3339b3fdbc13ea3e4801114f19a..e69d338ab9be0e0f51b85b05e2e4071c5982c802 100644 (file)
@@ -318,7 +318,7 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s
        return request_firmware(fw, name, &bt->bt->dev->dev);
 }
 
-static struct sp887x_config microtune_mt7202dtf_config = {
+static const struct sp887x_config microtune_mt7202dtf_config = {
        .demod_address = 0x70,
        .request_firmware = microtune_mt7202dtf_request_firmware,
 };
@@ -458,7 +458,7 @@ static void or51211_sleep(struct dvb_frontend * fe)
        bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
 }
 
-static struct or51211_config or51211_config = {
+static const struct or51211_config or51211_config = {
        .demod_address = 0x15,
        .request_firmware = or51211_request_firmware,
        .setmode = or51211_setmode,
index 9d5b314142f1b49daabb78985f6d13a2f982405a..6e995ef8c37e80872be886d5aa8a7027915ad992 100644 (file)
@@ -690,7 +690,7 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type)
        struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900;
        struct stv6110x_config *tunerconf = (input->nr & 1) ?
                &stv6110b : &stv6110a;
-       struct stv6110x_devctl *ctl;
+       const struct stv6110x_devctl *ctl;
 
        ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c);
        if (!ctl) {
index 525ebfefeee829c644a74d279d888a7fc60e9ca3..c94cecd2aa4068c5d7a4922800745e52b5a8dd98 100644 (file)
@@ -771,10 +771,9 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
 
        /* allocate device context */
        ndev = kzalloc(sizeof(*ndev), GFP_KERNEL);
-
        if (!ndev)
                goto dev_alloc_err;
-       memset(ndev, 0, sizeof(*ndev));
+
        ndev->old_fw = old_firmware;
        ndev->wq = create_singlethread_workqueue(NETUP_UNIDVB_NAME);
        if (!ndev->wq) {
index 039bed3cc919d2f5624e1635327e126abdfca064..4e783a68bf4aef998cf2c26353510a367dba338d 100644 (file)
@@ -57,7 +57,7 @@ static int tuner_attach_stv6110(struct ngene_channel *chan)
                chan->dev->card_info->fe_config[chan->number];
        struct stv6110x_config *tunerconf = (struct stv6110x_config *)
                chan->dev->card_info->tuner_config[chan->number];
-       struct stv6110x_devctl *ctl;
+       const struct stv6110x_devctl *ctl;
 
        /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
        if (chan->number < 2)
index 56b932c97196d68cc76dcdfd007dcf7b937bd40f..ca417a454d6787aecc77a0a338137dce78d7acb0 100644 (file)
@@ -189,6 +189,7 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
        .vidioc_querybuf                = vb2_ioctl_querybuf,
        .vidioc_qbuf                    = vb2_ioctl_qbuf,
        .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
+       .vidioc_expbuf                  = vb2_ioctl_expbuf,
        .vidioc_streamon                = vb2_ioctl_streamon,
        .vidioc_streamoff               = vb2_ioctl_streamoff,
        .vidioc_g_frequency             = saa7134_g_frequency,
@@ -286,7 +287,7 @@ static int empress_init(struct saa7134_dev *dev)
         * transfers that do not start at the beginning of a page. A USERPTR
         * can start anywhere in a page, so USERPTR support is a no-go.
         */
-       q->io_modes = VB2_MMAP | VB2_READ;
+       q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
        q->drv_priv = &dev->ts_q;
        q->ops = &saa7134_empress_qops;
        q->gfp_flags = GFP_DMA32;
index 8a2abb34186b3dfa08b3ac6a22af298b757bc132..2799538e2d7e043ac70a4985daee314a9392f18b 100644 (file)
@@ -378,7 +378,7 @@ static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
        return 0;
 }
 
-static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
+static const struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
        .interface_reset        = saa7134_go7007_interface_reset,
        .write_interrupt        = saa7134_go7007_write_interrupt,
        .read_interrupt         = saa7134_go7007_read_interrupt,
index a63c1366a64efad4ad837a5ae927a3417b39d580..7a42d3ae3ac933287884480beeb9d7623ce1abbc 100644 (file)
@@ -1906,6 +1906,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
        .vidioc_querybuf                = vb2_ioctl_querybuf,
        .vidioc_qbuf                    = vb2_ioctl_qbuf,
        .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
+       .vidioc_expbuf                  = vb2_ioctl_expbuf,
        .vidioc_s_std                   = saa7134_s_std,
        .vidioc_g_std                   = saa7134_g_std,
        .vidioc_querystd                = saa7134_querystd,
@@ -2089,7 +2090,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
         * USERPTR support is a no-go unless the application knows about these
         * limitations and has special support for this.
         */
-       q->io_modes = VB2_MMAP | VB2_READ;
+       q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
        if (saa7134_userptr)
                q->io_modes |= VB2_USERPTR;
        q->drv_priv = &dev->video_q;
index a69dc6a0752bb94fc8352c133571b31f37599f99..18d229fa65cfb3839e61a60cd8f4dfebd8fc55eb 100644 (file)
@@ -1739,7 +1739,7 @@ static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct fir
 #endif
 }
 
-static struct sp8870_config alps_tdlb7_config = {
+static const struct sp8870_config alps_tdlb7_config = {
 
        .demod_address = 0x71,
        .request_firmware = alps_tdlb7_request_firmware,
index de54310a26603b23a152b174b3d04c2ce7cd58df..9f48100227f150f216c9ecfaf8c704d73ae6f3b8 100644 (file)
@@ -644,7 +644,7 @@ static void frontend_init(struct budget *budget)
                }
 
        case 0x101c: { /* TT S2-1600 */
-                       struct stv6110x_devctl *ctl;
+                       const struct stv6110x_devctl *ctl;
                        saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
                        msleep(50);
                        saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
@@ -697,7 +697,7 @@ static void frontend_init(struct budget *budget)
                break;
 
        case 0x1020: { /* Omicom S2 */
-                       struct stv6110x_devctl *ctl;
+                       const struct stv6110x_devctl *ctl;
                        saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO);
                        msleep(50);
                        saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI);
index 8b89ebe16d94ace645d7401ece918b83cf92add6..fd4fcd5a7184ce08f31d1ea11b8ea730496121ae 100644 (file)
@@ -120,6 +120,18 @@ source "drivers/media/platform/s5p-tv/Kconfig"
 source "drivers/media/platform/am437x/Kconfig"
 source "drivers/media/platform/xilinx/Kconfig"
 
+config VIDEO_TI_CAL
+       tristate "TI CAL (Camera Adaptation Layer) driver"
+       depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       depends on SOC_DRA7XX || COMPILE_TEST
+       select VIDEOBUF2_DMA_CONTIG
+       default n
+       ---help---
+         Support for the TI CAL (Camera Adaptation Layer) block
+         found on DRA72X SoC.
+         In TI Technical Reference Manual this module is referred as
+         Camera Interface Subsystem (CAMSS).
+
 endif # V4L_PLATFORM_DRIVERS
 
 menuconfig V4L_MEM2MEM_DRIVERS
index efa0295af87bfe089acb526329b1601e95756c89..028a7233096baff93845935b4be126a65dadd32b 100644 (file)
@@ -18,6 +18,8 @@ obj-$(CONFIG_VIDEO_VIM2M)             += vim2m.o
 
 obj-$(CONFIG_VIDEO_TI_VPE)             += ti-vpe/
 
+obj-$(CONFIG_VIDEO_TI_CAL)             += ti-vpe/
+
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP)                += mx2_emmaprp.o
 obj-$(CONFIG_VIDEO_CODA)               += coda/
 
index 7d28899f89ce16c00cd9f00f424a948fa57e2ae8..6efe9d0029611251ba0621210dbeee41606abb08 100644 (file)
@@ -1342,7 +1342,7 @@ static void coda_finish_encode(struct coda_ctx *ctx)
 
        /* Calculate bytesused field */
        if (dst_buf->sequence == 0) {
-               vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
+               vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr +
                                        ctx->vpu_header_size[0] +
                                        ctx->vpu_header_size[1] +
                                        ctx->vpu_header_size[2]);
index ffbefdff6b5ef460d4a7c1abce024ed9841d8b4c..6fba32bec97455b8a98ddd255252b88e178ed0ea 100644 (file)
@@ -261,7 +261,7 @@ static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
         */
        if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) {
                if (fpc_physaddr != NULL) {
-                       free_pages((unsigned long)fpc_physaddr,
+                       free_pages((unsigned long)fpc_virtaddr,
                                   get_order
                                   (config_params->fault_pxl.fp_num *
                                   FP_NUM_BYTES));
index 93782f15b8252092ba31a81b8c135de581f8dc4a..a600e32e25430a8ddc82e090f373a87d4e335b57 100644 (file)
@@ -700,7 +700,7 @@ static unsigned int gsc_m2m_poll(struct file *file,
 {
        struct gsc_ctx *ctx = fh_to_ctx(file->private_data);
        struct gsc_dev *gsc = ctx->gsc_dev;
-       int ret;
+       unsigned int ret;
 
        if (mutex_lock_interruptible(&gsc->lock))
                return -ERESTARTSYS;
index e79ddbb1e14fc0bd8c1b56504183a927edcdec83..feb521f28e14857b8344d7320769c87183cd17ac 100644 (file)
@@ -389,13 +389,19 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
        struct fimc_source_info *pd = &fmd->sensor[index].pdata;
        struct device_node *rem, *ep, *np;
        struct v4l2_of_endpoint endpoint;
+       int ret;
 
        /* Assume here a port node can have only one endpoint node. */
        ep = of_get_next_child(port, NULL);
        if (!ep)
                return 0;
 
-       v4l2_of_parse_endpoint(ep, &endpoint);
+       ret = v4l2_of_parse_endpoint(ep, &endpoint);
+       if (ret) {
+               of_node_put(ep);
+               return ret;
+       }
+
        if (WARN_ON(endpoint.base.port == 0) || index >= FIMC_MAX_SENSORS)
                return -EINVAL;
 
@@ -486,8 +492,10 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
                        continue;
 
                ret = fimc_md_parse_port_node(fmd, port, index);
-               if (ret < 0)
+               if (ret < 0) {
+                       of_node_put(node);
                        goto rpm_put;
+               }
                index++;
        }
 
@@ -498,8 +506,10 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
 
        for_each_child_of_node(ports, node) {
                ret = fimc_md_parse_port_node(fmd, node, index);
-               if (ret < 0)
+               if (ret < 0) {
+                       of_node_put(node);
                        break;
+               }
                index++;
        }
 rpm_put:
@@ -707,8 +717,10 @@ static int fimc_md_register_platform_entities(struct fimc_md *fmd,
                        ret = fimc_md_register_platform_entity(fmd, pdev,
                                                        plat_entity);
                put_device(&pdev->dev);
-               if (ret < 0)
+               if (ret < 0) {
+                       of_node_put(node);
                        break;
+               }
        }
 
        return ret;
index ac5e50e595be83cd7ac973a6eab1d5866fca1d1b..bd5c46c3d4b7bedc362c29cb473c8206f84026b3 100644 (file)
@@ -736,6 +736,7 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
 {
        struct device_node *node = pdev->dev.of_node;
        struct v4l2_of_endpoint endpoint;
+       int ret;
 
        if (of_property_read_u32(node, "clock-frequency",
                                 &state->clk_frequency))
@@ -751,7 +752,9 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
                return -EINVAL;
        }
        /* Get port node and validate MIPI-CSI channel id. */
-       v4l2_of_parse_endpoint(node, &endpoint);
+       ret = v4l2_of_parse_endpoint(node, &endpoint);
+       if (ret)
+               goto err;
 
        state->index = endpoint.base.port - FIMC_INPUT_MIPI_CSI2_0;
        if (state->index >= CSIS_MAX_ENTITIES)
@@ -764,9 +767,10 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
                                        "samsung,csis-wclk");
 
        state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
-       of_node_put(node);
 
-       return 0;
+err:
+       of_node_put(node);
+       return ret;
 }
 
 static int s5pcsis_pm_resume(struct device *dev, bool runtime);
index 0bcfa553c1aa254b63789980d50a1dc5a0149d5f..f9e5245f26acca69a0113b05d950d2611bb6a3d0 100644 (file)
@@ -449,7 +449,7 @@ void omap3isp_configure_bridge(struct isp_device *isp,
        case CCDC_INPUT_PARALLEL:
                ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
                ispctrl_val |= parcfg->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
-               shift += parcfg->data_lane_shift * 2;
+               shift += parcfg->data_lane_shift;
                break;
 
        case CCDC_INPUT_CSI2A:
@@ -2235,8 +2235,11 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
        struct isp_bus_cfg *buscfg = &isd->bus;
        struct v4l2_of_endpoint vep;
        unsigned int i;
+       int ret;
 
-       v4l2_of_parse_endpoint(node, &vep);
+       ret = v4l2_of_parse_endpoint(node, &vep);
+       if (ret)
+               return ret;
 
        dev_dbg(dev, "parsing endpoint %s, interface %u\n", node->full_name,
                vep.base.port);
@@ -2528,12 +2531,13 @@ static int isp_probe(struct platform_device *pdev)
        }
 
        /* Interrupt */
-       isp->irq_num = platform_get_irq(pdev, 0);
-       if (isp->irq_num <= 0) {
+       ret = platform_get_irq(pdev, 0);
+       if (ret <= 0) {
                dev_err(isp->dev, "No IRQ resource\n");
                ret = -ENODEV;
                goto error_iommu;
        }
+       isp->irq_num = ret;
 
        if (devm_request_irq(isp->dev, isp->irq_num, isp_isr, IRQF_SHARED,
                             "OMAP3 ISP", isp)) {
@@ -2599,6 +2603,7 @@ static const struct of_device_id omap3isp_of_table[] = {
        { .compatible = "ti,omap3-isp" },
        { },
 };
+MODULE_DEVICE_TABLE(of, omap3isp_of_table);
 
 static struct platform_driver omap3isp_driver = {
        .probe = isp_probe,
index bb3974c98e37ebdfc1306534fd9d0555b67273de..882310eb45ccfa51e309769058a21433aa485655 100644 (file)
@@ -2421,7 +2421,7 @@ static int ccdc_link_validate(struct v4l2_subdev *sd,
                        &((struct isp_bus_cfg *)
                          media_entity_to_v4l2_subdev(link->source->entity)
                          ->host_priv)->bus.parallel;
-               parallel_shift = parcfg->data_lane_shift * 2;
+               parallel_shift = parcfg->data_lane_shift;
        } else {
                parallel_shift = 0;
        }
index 84a96670e2e71483442a584d2bcd124f4f0c6da4..ac30a0f837801ae57d3227429e4492a23306a0a9 100644 (file)
@@ -1480,13 +1480,6 @@ static void preview_isr_buffer(struct isp_prev_device *prev)
        struct isp_buffer *buffer;
        int restart = 0;
 
-       if (prev->input == PREVIEW_INPUT_MEMORY) {
-               buffer = omap3isp_video_buffer_next(&prev->video_in);
-               if (buffer != NULL)
-                       preview_set_inaddr(prev, buffer->dma);
-               pipe->state |= ISP_PIPELINE_IDLE_INPUT;
-       }
-
        if (prev->output & PREVIEW_OUTPUT_MEMORY) {
                buffer = omap3isp_video_buffer_next(&prev->video_out);
                if (buffer != NULL) {
@@ -1496,6 +1489,13 @@ static void preview_isr_buffer(struct isp_prev_device *prev)
                pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
        }
 
+       if (prev->input == PREVIEW_INPUT_MEMORY) {
+               buffer = omap3isp_video_buffer_next(&prev->video_in);
+               if (buffer != NULL)
+                       preview_set_inaddr(prev, buffer->dma);
+               pipe->state |= ISP_PIPELINE_IDLE_INPUT;
+       }
+
        switch (prev->state) {
        case ISP_PIPELINE_STREAM_SINGLESHOT:
                if (isp_pipeline_ready(pipe))
index 994dfc0813f6b7556fb43b05b8536b29f4c6f8b1..2aff755ff77c37741d540181ce25e32dc8bf0ba1 100644 (file)
@@ -434,10 +434,68 @@ static void isp_video_buffer_queue(struct vb2_buffer *buf)
        }
 }
 
+/*
+ * omap3isp_video_return_buffers - Return all queued buffers to videobuf2
+ * @video: ISP video object
+ * @state: new state for the returned buffers
+ *
+ * Return all buffers queued on the video node to videobuf2 in the given state.
+ * The buffer state should be VB2_BUF_STATE_QUEUED if called due to an error
+ * when starting the stream, or VB2_BUF_STATE_ERROR otherwise.
+ *
+ * The function must be called with the video irqlock held.
+ */
+static void omap3isp_video_return_buffers(struct isp_video *video,
+                                         enum vb2_buffer_state state)
+{
+       while (!list_empty(&video->dmaqueue)) {
+               struct isp_buffer *buf;
+
+               buf = list_first_entry(&video->dmaqueue,
+                                      struct isp_buffer, irqlist);
+               list_del(&buf->irqlist);
+               vb2_buffer_done(&buf->vb.vb2_buf, state);
+       }
+}
+
+static int isp_video_start_streaming(struct vb2_queue *queue,
+                                    unsigned int count)
+{
+       struct isp_video_fh *vfh = vb2_get_drv_priv(queue);
+       struct isp_video *video = vfh->video;
+       struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
+       unsigned long flags;
+       int ret;
+
+       /* In sensor-to-memory mode, the stream can be started synchronously
+        * to the stream on command. In memory-to-memory mode, it will be
+        * started when buffers are queued on both the input and output.
+        */
+       if (pipe->input)
+               return 0;
+
+       ret = omap3isp_pipeline_set_stream(pipe,
+                                          ISP_PIPELINE_STREAM_CONTINUOUS);
+       if (ret < 0) {
+               spin_lock_irqsave(&video->irqlock, flags);
+               omap3isp_video_return_buffers(video, VB2_BUF_STATE_QUEUED);
+               spin_unlock_irqrestore(&video->irqlock, flags);
+               return ret;
+       }
+
+       spin_lock_irqsave(&video->irqlock, flags);
+       if (list_empty(&video->dmaqueue))
+               video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
+       spin_unlock_irqrestore(&video->irqlock, flags);
+
+       return 0;
+}
+
 static const struct vb2_ops isp_video_queue_ops = {
        .queue_setup = isp_video_queue_setup,
        .buf_prepare = isp_video_buffer_prepare,
        .buf_queue = isp_video_buffer_queue,
+       .start_streaming = isp_video_start_streaming,
 };
 
 /*
@@ -459,7 +517,7 @@ static const struct vb2_ops isp_video_queue_ops = {
 struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
 {
        struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
-       enum isp_pipeline_state state;
+       enum vb2_buffer_state vb_state;
        struct isp_buffer *buf;
        unsigned long flags;
 
@@ -495,17 +553,19 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
 
        /* Report pipeline errors to userspace on the capture device side. */
        if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
-               state = VB2_BUF_STATE_ERROR;
+               vb_state = VB2_BUF_STATE_ERROR;
                pipe->error = false;
        } else {
-               state = VB2_BUF_STATE_DONE;
+               vb_state = VB2_BUF_STATE_DONE;
        }
 
-       vb2_buffer_done(&buf->vb.vb2_buf, state);
+       vb2_buffer_done(&buf->vb.vb2_buf, vb_state);
 
        spin_lock_irqsave(&video->irqlock, flags);
 
        if (list_empty(&video->dmaqueue)) {
+               enum isp_pipeline_state state;
+
                spin_unlock_irqrestore(&video->irqlock, flags);
 
                if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -541,26 +601,16 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
  * omap3isp_video_cancel_stream - Cancel stream on a video node
  * @video: ISP video object
  *
- * Cancelling a stream mark all buffers on the video node as erroneous and makes
- * sure no new buffer can be queued.
+ * Cancelling a stream returns all buffers queued on the video node to videobuf2
+ * in the erroneous state and makes sure no new buffer can be queued.
  */
 void omap3isp_video_cancel_stream(struct isp_video *video)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&video->irqlock, flags);
-
-       while (!list_empty(&video->dmaqueue)) {
-               struct isp_buffer *buf;
-
-               buf = list_first_entry(&video->dmaqueue,
-                                      struct isp_buffer, irqlist);
-               list_del(&buf->irqlist);
-               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-       }
-
+       omap3isp_video_return_buffers(video, VB2_BUF_STATE_ERROR);
        video->error = true;
-
        spin_unlock_irqrestore(&video->irqlock, flags);
 }
 
@@ -1087,29 +1137,10 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
        if (ret < 0)
                goto err_check_format;
 
-       /* In sensor-to-memory mode, the stream can be started synchronously
-        * to the stream on command. In memory-to-memory mode, it will be
-        * started when buffers are queued on both the input and output.
-        */
-       if (pipe->input == NULL) {
-               ret = omap3isp_pipeline_set_stream(pipe,
-                                             ISP_PIPELINE_STREAM_CONTINUOUS);
-               if (ret < 0)
-                       goto err_set_stream;
-               spin_lock_irqsave(&video->irqlock, flags);
-               if (list_empty(&video->dmaqueue))
-                       video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
-               spin_unlock_irqrestore(&video->irqlock, flags);
-       }
-
        mutex_unlock(&video->stream_lock);
 
        return 0;
 
-err_set_stream:
-       mutex_lock(&video->queue_lock);
-       vb2_streamoff(&vfh->queue, type);
-       mutex_unlock(&video->queue_lock);
 err_check_format:
        media_entity_pipeline_stop(&video->video.entity);
 err_pipeline_start:
index 190e259a6a2df87553dd2e7c3b655b0f7ebca08e..443e8f7673e2fe02164ba907ca5744a12bf44785 100644 (file)
@@ -33,9 +33,9 @@ enum isp_interface_type {
  * struct isp_parallel_cfg - Parallel interface configuration
  * @data_lane_shift: Data lane shifter
  *             0 - CAMEXT[13:0] -> CAM[13:0]
- *             1 - CAMEXT[13:2] -> CAM[11:0]
- *             2 - CAMEXT[13:4] -> CAM[9:0]
- *             3 - CAMEXT[13:6] -> CAM[7:0]
+ *             2 - CAMEXT[13:2] -> CAM[11:0]
+ *             4 - CAMEXT[13:4] -> CAM[9:0]
+ *             6 - CAMEXT[13:6] -> CAM[7:0]
  * @clk_pol: Pixel clock polarity
  *             0 - Sample on rising edge, 1 - Sample on falling edge
  * @hs_pol: Horizontal synchronization polarity
@@ -48,7 +48,7 @@ enum isp_interface_type {
  *             0 - Normal, 1 - One's complement
  */
 struct isp_parallel_cfg {
-       unsigned int data_lane_shift:2;
+       unsigned int data_lane_shift:3;
        unsigned int clk_pol:1;
        unsigned int hs_pol:1;
        unsigned int vs_pol:1;
index 485f5259acb082d4e71484c12ad730c0142dc77c..552789a69c8645bd94af18f71cee62192fa3d80c 100644 (file)
@@ -1613,6 +1613,7 @@ static const struct of_device_id jpu_dt_ids[] = {
        { .compatible = "renesas,jpu-r8a7791" }, /* M2-W */
        { .compatible = "renesas,jpu-r8a7792" }, /* V2H */
        { .compatible = "renesas,jpu-r8a7793" }, /* M2-N */
+       { .compatible = "renesas,rcar-gen2-jpu" },
        { },
 };
 MODULE_DEVICE_TABLE(of, jpu_dt_ids);
index b7fd695b9ed5187d2f8d2c356269ebe6fc1d26d4..dc75a80794fb92658f0ab375d924eeeed74b3467 100644 (file)
 #define RCAR_VIN_BT656                 (1 << 3)
 
 enum chip_id {
+       RCAR_GEN3,
        RCAR_GEN2,
        RCAR_H1,
        RCAR_M1,
@@ -1818,6 +1819,7 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
 
 #ifdef CONFIG_OF
 static const struct of_device_id rcar_vin_of_table[] = {
+       { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_GEN3 },
        { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
        { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
        { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
index 90c87f2b4ec075bbe96ee15201494f3dcc757753..b9f369c0fb9473190bfc7d4f41c63b503a1b1785 100644 (file)
@@ -213,8 +213,7 @@ static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
                        unsigned int *count, unsigned int *num_planes,
                        unsigned int sizes[], void *alloc_ctxs[])
 {
-       struct soc_camera_device *icd = container_of(vq,
-                       struct soc_camera_device, vb2_vidq);
+       struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
 
@@ -361,8 +360,7 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
 static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
 {
        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct soc_camera_device *icd = container_of(vb->vb2_queue,
-                       struct soc_camera_device, vb2_vidq);
+       struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
        struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vbuf);
@@ -413,8 +411,7 @@ error:
 static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
 {
        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct soc_camera_device *icd = container_of(vb->vb2_queue,
-                       struct soc_camera_device, vb2_vidq);
+       struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vbuf);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -444,8 +441,7 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
 static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
 {
        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-       struct soc_camera_device *icd = container_of(vb->vb2_queue,
-                       struct soc_camera_device, vb2_vidq);
+       struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
 
@@ -460,7 +456,7 @@ static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
 
 static void sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
 {
-       struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq);
+       struct soc_camera_device *icd = soc_camera_from_vb2q(q);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
        struct list_head *buf_head, *tmp;
index 69d7fe4471c2ce887c57f15551df6fbd1f385b63..2c0015b1264d3254451a7c56f9c9b1a69b760ad9 100644 (file)
@@ -118,7 +118,7 @@ int c8sectpfe_frontend_attach(struct dvb_frontend **fe,
                struct channel_info *tsin, int chan_num)
 {
        struct tda18212_config *tda18212;
-       struct stv6110x_devctl *fe2;
+       const struct stv6110x_devctl *fe2;
        struct i2c_client *client;
        struct i2c_board_info tda18212_info = {
                .type = "tda18212",
index be680f839e77c9f3d7ab0e7366762093a35e88fe..e236059a60ad3ccf9b16c1861b5297abd549c266 100644 (file)
@@ -3,3 +3,7 @@ obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
 ti-vpe-y := vpe.o sc.o csc.o vpdma.o
 
 ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
+
+obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o
+
+ti-cal-y := cal.o
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
new file mode 100644 (file)
index 0000000..69ec79b
--- /dev/null
@@ -0,0 +1,1970 @@
+/*
+ * TI CAL camera interface driver
+ *
+ * Copyright (c) 2015 Texas Instruments Inc.
+ * Benoit Parrot, <bparrot@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioctl.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+
+#include <media/v4l2-of.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-common.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include "cal_regs.h"
+
+#define CAL_MODULE_NAME "cal"
+
+#define MAX_WIDTH 1920
+#define MAX_HEIGHT 1200
+
+#define CAL_VERSION "0.1.0"
+
+MODULE_DESCRIPTION("TI CAL driver");
+MODULE_AUTHOR("Benoit Parrot, <bparrot@ti.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(CAL_VERSION);
+
+static unsigned video_nr = -1;
+module_param(video_nr, uint, 0644);
+MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
+
+static unsigned debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+/* timeperframe: min/max and default */
+static const struct v4l2_fract
+       tpf_default = {.numerator = 1001,       .denominator = 30000};
+
+#define cal_dbg(level, caldev, fmt, arg...)    \
+               v4l2_dbg(level, debug, &caldev->v4l2_dev, fmt, ##arg)
+#define cal_info(caldev, fmt, arg...)  \
+               v4l2_info(&caldev->v4l2_dev, fmt, ##arg)
+#define cal_err(caldev, fmt, arg...)   \
+               v4l2_err(&caldev->v4l2_dev, fmt, ##arg)
+
+#define ctx_dbg(level, ctx, fmt, arg...)       \
+               v4l2_dbg(level, debug, &ctx->v4l2_dev, fmt, ##arg)
+#define ctx_info(ctx, fmt, arg...)     \
+               v4l2_info(&ctx->v4l2_dev, fmt, ##arg)
+#define ctx_err(ctx, fmt, arg...)      \
+               v4l2_err(&ctx->v4l2_dev, fmt, ##arg)
+
+#define CAL_NUM_INPUT 1
+#define CAL_NUM_CONTEXT 2
+
+#define bytes_per_line(pixel, bpp) (ALIGN(pixel * bpp, 16))
+
+#define reg_read(dev, offset) ioread32(dev->base + offset)
+#define reg_write(dev, offset, val) iowrite32(val, dev->base + offset)
+
+#define reg_read_field(dev, offset, mask) get_field(reg_read(dev, offset), \
+                                                   mask)
+#define reg_write_field(dev, offset, field, mask) { \
+       u32 val = reg_read(dev, offset); \
+       set_field(&val, field, mask); \
+       reg_write(dev, offset, val); }
+
+/* ------------------------------------------------------------------
+ *     Basic structures
+ * ------------------------------------------------------------------
+ */
+
+struct cal_fmt {
+       u32     fourcc;
+       u32     code;
+       u8      depth;
+};
+
+static struct cal_fmt cal_formats[] = {
+       {
+               .fourcc         = V4L2_PIX_FMT_YUYV,
+               .code           = MEDIA_BUS_FMT_YUYV8_2X8,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_UYVY,
+               .code           = MEDIA_BUS_FMT_UYVY8_2X8,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_YVYU,
+               .code           = MEDIA_BUS_FMT_YVYU8_2X8,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_VYUY,
+               .code           = MEDIA_BUS_FMT_VYUY8_2X8,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+               .code           = MEDIA_BUS_FMT_RGB565_2X8_LE,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
+               .code           = MEDIA_BUS_FMT_RGB565_2X8_BE,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
+               .code           = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
+               .code           = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_RGB24, /* rgb */
+               .code           = MEDIA_BUS_FMT_RGB888_2X12_LE,
+               .depth          = 24,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_BGR24, /* bgr */
+               .code           = MEDIA_BUS_FMT_RGB888_2X12_BE,
+               .depth          = 24,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_RGB32, /* argb */
+               .code           = MEDIA_BUS_FMT_ARGB8888_1X32,
+               .depth          = 32,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SBGGR8,
+               .code           = MEDIA_BUS_FMT_SBGGR8_1X8,
+               .depth          = 8,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SGBRG8,
+               .code           = MEDIA_BUS_FMT_SGBRG8_1X8,
+               .depth          = 8,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SGRBG8,
+               .code           = MEDIA_BUS_FMT_SGRBG8_1X8,
+               .depth          = 8,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SRGGB8,
+               .code           = MEDIA_BUS_FMT_SRGGB8_1X8,
+               .depth          = 8,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SBGGR10,
+               .code           = MEDIA_BUS_FMT_SBGGR10_1X10,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SGBRG10,
+               .code           = MEDIA_BUS_FMT_SGBRG10_1X10,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SGRBG10,
+               .code           = MEDIA_BUS_FMT_SGRBG10_1X10,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SRGGB10,
+               .code           = MEDIA_BUS_FMT_SRGGB10_1X10,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SBGGR12,
+               .code           = MEDIA_BUS_FMT_SBGGR12_1X12,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SGBRG12,
+               .code           = MEDIA_BUS_FMT_SGBRG12_1X12,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SGRBG12,
+               .code           = MEDIA_BUS_FMT_SGRBG12_1X12,
+               .depth          = 16,
+       }, {
+               .fourcc         = V4L2_PIX_FMT_SRGGB12,
+               .code           = MEDIA_BUS_FMT_SRGGB12_1X12,
+               .depth          = 16,
+       },
+};
+
+/*  Print Four-character-code (FOURCC) */
+static char *fourcc_to_str(u32 fmt)
+{
+       static char code[5];
+
+       code[0] = (unsigned char)(fmt & 0xff);
+       code[1] = (unsigned char)((fmt >> 8) & 0xff);
+       code[2] = (unsigned char)((fmt >> 16) & 0xff);
+       code[3] = (unsigned char)((fmt >> 24) & 0xff);
+       code[4] = '\0';
+
+       return code;
+}
+
+/* buffer for one video frame */
+struct cal_buffer {
+       /* common v4l buffer stuff -- must be first */
+       struct vb2_v4l2_buffer  vb;
+       struct list_head        list;
+       const struct cal_fmt    *fmt;
+};
+
+struct cal_dmaqueue {
+       struct list_head        active;
+
+       /* Counters to control fps rate */
+       int                     frame;
+       int                     ini_jiffies;
+};
+
+struct cm_data {
+       void __iomem            *base;
+       struct resource         *res;
+
+       unsigned int            camerrx_control;
+
+       struct platform_device *pdev;
+};
+
+struct cc_data {
+       void __iomem            *base;
+       struct resource         *res;
+
+       struct platform_device *pdev;
+};
+
+/*
+ * there is one cal_dev structure in the driver, it is shared by
+ * all instances.
+ */
+struct cal_dev {
+       int                     irq;
+       void __iomem            *base;
+       struct resource         *res;
+       struct platform_device  *pdev;
+       struct v4l2_device      v4l2_dev;
+
+       /* Control Module handle */
+       struct cm_data          *cm;
+       /* Camera Core Module handle */
+       struct cc_data          *cc[CAL_NUM_CSI2_PORTS];
+
+       struct cal_ctx          *ctx[CAL_NUM_CONTEXT];
+};
+
+/*
+ * There is one cal_ctx structure for each camera core context.
+ */
+struct cal_ctx {
+       struct v4l2_device      v4l2_dev;
+       struct v4l2_ctrl_handler ctrl_handler;
+       struct video_device     vdev;
+       struct v4l2_async_notifier notifier;
+       struct v4l2_subdev      *sensor;
+       struct v4l2_of_endpoint endpoint;
+
+       struct v4l2_async_subdev asd;
+       struct v4l2_async_subdev *asd_list[1];
+
+       struct v4l2_fh          fh;
+       struct cal_dev          *dev;
+       struct cc_data          *cc;
+
+       /* v4l2_ioctl mutex */
+       struct mutex            mutex;
+       /* v4l2 buffers lock */
+       spinlock_t              slock;
+
+       /* Several counters */
+       unsigned long           jiffies;
+
+       struct vb2_alloc_ctx    *alloc_ctx;
+       struct cal_dmaqueue     vidq;
+
+       /* Input Number */
+       int                     input;
+
+       /* video capture */
+       const struct cal_fmt    *fmt;
+       /* Used to store current pixel format */
+       struct v4l2_format              v_fmt;
+       /* Used to store current mbus frame format */
+       struct v4l2_mbus_framefmt       m_fmt;
+
+       /* Current subdev enumerated format */
+       struct cal_fmt          *active_fmt[ARRAY_SIZE(cal_formats)];
+       int                     num_active_fmt;
+
+       struct v4l2_fract       timeperframe;
+       unsigned int            sequence;
+       unsigned int            external_rate;
+       struct vb2_queue        vb_vidq;
+       unsigned int            seq_count;
+       unsigned int            csi2_port;
+       unsigned int            virtual_channel;
+
+       /* Pointer pointing to current v4l2_buffer */
+       struct cal_buffer       *cur_frm;
+       /* Pointer pointing to next v4l2_buffer */
+       struct cal_buffer       *next_frm;
+};
+
+static const struct cal_fmt *find_format_by_pix(struct cal_ctx *ctx,
+                                               u32 pixelformat)
+{
+       const struct cal_fmt *fmt;
+       unsigned int k;
+
+       for (k = 0; k < ctx->num_active_fmt; k++) {
+               fmt = ctx->active_fmt[k];
+               if (fmt->fourcc == pixelformat)
+                       return fmt;
+       }
+
+       return NULL;
+}
+
+static const struct cal_fmt *find_format_by_code(struct cal_ctx *ctx,
+                                                u32 code)
+{
+       const struct cal_fmt *fmt;
+       unsigned int k;
+
+       for (k = 0; k < ctx->num_active_fmt; k++) {
+               fmt = ctx->active_fmt[k];
+               if (fmt->code == code)
+                       return fmt;
+       }
+
+       return NULL;
+}
+
+static inline struct cal_ctx *notifier_to_ctx(struct v4l2_async_notifier *n)
+{
+       return container_of(n, struct cal_ctx, notifier);
+}
+
+static inline int get_field(u32 value, u32 mask)
+{
+       return (value & mask) >> __ffs(mask);
+}
+
+static inline void set_field(u32 *valp, u32 field, u32 mask)
+{
+       u32 val = *valp;
+
+       val &= ~mask;
+       val |= (field << __ffs(mask)) & mask;
+       *valp = val;
+}
+
+/*
+ * Control Module block access
+ */
+static struct cm_data *cm_create(struct cal_dev *dev)
+{
+       struct platform_device *pdev = dev->pdev;
+       struct cm_data *cm;
+
+       cm = devm_kzalloc(&pdev->dev, sizeof(*cm), GFP_KERNEL);
+       if (!cm)
+               return ERR_PTR(-ENOMEM);
+
+       cm->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                               "camerrx_control");
+       cm->base = devm_ioremap_resource(&pdev->dev, cm->res);
+       if (IS_ERR(cm->base)) {
+               cal_err(dev, "failed to ioremap\n");
+               return cm->base;
+       }
+
+       cal_dbg(1, dev, "ioresource %s at %pa - %pa\n",
+               cm->res->name, &cm->res->start, &cm->res->end);
+
+       return cm;
+}
+
+static void camerarx_phy_enable(struct cal_ctx *ctx)
+{
+       u32 val;
+
+       if (!ctx->dev->cm->base) {
+               ctx_err(ctx, "cm not mapped\n");
+               return;
+       }
+
+       val = reg_read(ctx->dev->cm, CM_CTRL_CORE_CAMERRX_CONTROL);
+       if (ctx->csi2_port == 1) {
+               set_field(&val, 1, CM_CAMERRX_CTRL_CSI0_CTRLCLKEN_MASK);
+               set_field(&val, 0, CM_CAMERRX_CTRL_CSI0_CAMMODE_MASK);
+               /* enable all lanes by default */
+               set_field(&val, 0xf, CM_CAMERRX_CTRL_CSI0_LANEENABLE_MASK);
+               set_field(&val, 1, CM_CAMERRX_CTRL_CSI0_MODE_MASK);
+       } else if (ctx->csi2_port == 2) {
+               set_field(&val, 1, CM_CAMERRX_CTRL_CSI1_CTRLCLKEN_MASK);
+               set_field(&val, 0, CM_CAMERRX_CTRL_CSI1_CAMMODE_MASK);
+               /* enable all lanes by default */
+               set_field(&val, 0x3, CM_CAMERRX_CTRL_CSI1_LANEENABLE_MASK);
+               set_field(&val, 1, CM_CAMERRX_CTRL_CSI1_MODE_MASK);
+       }
+       reg_write(ctx->dev->cm, CM_CTRL_CORE_CAMERRX_CONTROL, val);
+}
+
+static void camerarx_phy_disable(struct cal_ctx *ctx)
+{
+       u32 val;
+
+       if (!ctx->dev->cm->base) {
+               ctx_err(ctx, "cm not mapped\n");
+               return;
+       }
+
+       val = reg_read(ctx->dev->cm, CM_CTRL_CORE_CAMERRX_CONTROL);
+       if (ctx->csi2_port == 1)
+               set_field(&val, 0x0, CM_CAMERRX_CTRL_CSI0_CTRLCLKEN_MASK);
+       else if (ctx->csi2_port == 2)
+               set_field(&val, 0x0, CM_CAMERRX_CTRL_CSI1_CTRLCLKEN_MASK);
+       reg_write(ctx->dev->cm, CM_CTRL_CORE_CAMERRX_CONTROL, val);
+}
+
+/*
+ * Camera Instance access block
+ */
+static struct cc_data *cc_create(struct cal_dev *dev, unsigned int core)
+{
+       struct platform_device *pdev = dev->pdev;
+       struct cc_data *cc;
+
+       cc = devm_kzalloc(&pdev->dev, sizeof(*cc), GFP_KERNEL);
+       if (!cc)
+               return ERR_PTR(-ENOMEM);
+
+       cc->res = platform_get_resource_byname(pdev,
+                                              IORESOURCE_MEM,
+                                              (core == 0) ?
+                                               "cal_rx_core0" :
+                                               "cal_rx_core1");
+       cc->base = devm_ioremap_resource(&pdev->dev, cc->res);
+       if (IS_ERR(cc->base)) {
+               cal_err(dev, "failed to ioremap\n");
+               return cc->base;
+       }
+
+       cal_dbg(1, dev, "ioresource %s at %pa - %pa\n",
+               cc->res->name, &cc->res->start, &cc->res->end);
+
+       return cc;
+}
+
+/*
+ * Get Revision and HW info
+ */
+static void cal_get_hwinfo(struct cal_dev *dev)
+{
+       u32 revision = 0;
+       u32 hwinfo = 0;
+
+       revision = reg_read(dev, CAL_HL_REVISION);
+       cal_dbg(3, dev, "CAL_HL_REVISION = 0x%08x (expecting 0x40000200)\n",
+               revision);
+
+       hwinfo = reg_read(dev, CAL_HL_HWINFO);
+       cal_dbg(3, dev, "CAL_HL_HWINFO = 0x%08x (expecting 0xA3C90469)\n",
+               hwinfo);
+}
+
+static inline int cal_runtime_get(struct cal_dev *dev)
+{
+       int r;
+
+       r = pm_runtime_get_sync(&dev->pdev->dev);
+
+       return r;
+}
+
+static inline void cal_runtime_put(struct cal_dev *dev)
+{
+       pm_runtime_put_sync(&dev->pdev->dev);
+}
+
+static void cal_quickdump_regs(struct cal_dev *dev)
+{
+       cal_info(dev, "CAL Registers @ 0x%pa:\n", &dev->res->start);
+       print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
+                      dev->base, resource_size(dev->res), false);
+
+       if (dev->ctx[0]) {
+               cal_info(dev, "CSI2 Core 0 Registers @ %pa:\n",
+                        &dev->ctx[0]->cc->res->start);
+               print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
+                              dev->ctx[0]->cc->base,
+                              resource_size(dev->ctx[0]->cc->res),
+                              false);
+       }
+
+       if (dev->ctx[1]) {
+               cal_info(dev, "CSI2 Core 1 Registers @ %pa:\n",
+                        &dev->ctx[1]->cc->res->start);
+               print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
+                              dev->ctx[1]->cc->base,
+                              resource_size(dev->ctx[1]->cc->res),
+                              false);
+       }
+
+       cal_info(dev, "CAMERRX_Control Registers @ %pa:\n",
+                &dev->cm->res->start);
+       print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
+                      dev->cm->base,
+                      resource_size(dev->cm->res), false);
+}
+
+/*
+ * Enable the expected IRQ sources
+ */
+static void enable_irqs(struct cal_ctx *ctx)
+{
+       /* Enable IRQ_WDMA_END 0/1 */
+       reg_write_field(ctx->dev,
+                       CAL_HL_IRQENABLE_SET(2),
+                       CAL_HL_IRQ_ENABLE,
+                       CAL_HL_IRQ_MASK(ctx->csi2_port));
+       /* Enable IRQ_WDMA_START 0/1 */
+       reg_write_field(ctx->dev,
+                       CAL_HL_IRQENABLE_SET(3),
+                       CAL_HL_IRQ_ENABLE,
+                       CAL_HL_IRQ_MASK(ctx->csi2_port));
+       /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
+       reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0xFF000000);
+}
+
+static void disable_irqs(struct cal_ctx *ctx)
+{
+       /* Disable IRQ_WDMA_END 0/1 */
+       reg_write_field(ctx->dev,
+                       CAL_HL_IRQENABLE_CLR(2),
+                       CAL_HL_IRQ_CLEAR,
+                       CAL_HL_IRQ_MASK(ctx->csi2_port));
+       /* Disable IRQ_WDMA_START 0/1 */
+       reg_write_field(ctx->dev,
+                       CAL_HL_IRQENABLE_CLR(3),
+                       CAL_HL_IRQ_CLEAR,
+                       CAL_HL_IRQ_MASK(ctx->csi2_port));
+       /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */
+       reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0);
+}
+
+static void csi2_init(struct cal_ctx *ctx)
+{
+       int i;
+       u32 val;
+
+       val = reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port));
+       set_field(&val, CAL_GEN_ENABLE,
+                 CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK);
+       set_field(&val, CAL_GEN_ENABLE,
+                 CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK);
+       set_field(&val, CAL_GEN_DISABLE,
+                 CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK);
+       set_field(&val, 407, CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK);
+       reg_write(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port), val);
+       ctx_dbg(3, ctx, "CAL_CSI2_TIMING(%d) = 0x%08x\n", ctx->csi2_port,
+               reg_read(ctx->dev, CAL_CSI2_TIMING(ctx->csi2_port)));
+
+       val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
+       set_field(&val, CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL,
+                 CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
+       set_field(&val, CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON,
+                 CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK);
+       reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port), val);
+       for (i = 0; i < 10; i++) {
+               if (reg_read_field(ctx->dev,
+                                  CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port),
+                                  CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK) ==
+                   CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_ON)
+                       break;
+               usleep_range(1000, 1100);
+       }
+       ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x\n", ctx->csi2_port,
+               reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port)));
+
+       val = reg_read(ctx->dev, CAL_CTRL);
+       set_field(&val, CAL_CTRL_BURSTSIZE_BURST128, CAL_CTRL_BURSTSIZE_MASK);
+       set_field(&val, 0xF, CAL_CTRL_TAGCNT_MASK);
+       set_field(&val, CAL_CTRL_POSTED_WRITES_NONPOSTED,
+                 CAL_CTRL_POSTED_WRITES_MASK);
+       set_field(&val, 0xFF, CAL_CTRL_MFLAGL_MASK);
+       set_field(&val, 0xFF, CAL_CTRL_MFLAGH_MASK);
+       reg_write(ctx->dev, CAL_CTRL, val);
+       ctx_dbg(3, ctx, "CAL_CTRL = 0x%08x\n", reg_read(ctx->dev, CAL_CTRL));
+}
+
+static void csi2_lane_config(struct cal_ctx *ctx)
+{
+       u32 val = reg_read(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port));
+       u32 lane_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK;
+       u32 polarity_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK;
+       struct v4l2_of_bus_mipi_csi2 *mipi_csi2 = &ctx->endpoint.bus.mipi_csi2;
+       int lane;
+
+       set_field(&val, mipi_csi2->clock_lane + 1, lane_mask);
+       set_field(&val, mipi_csi2->lane_polarities[0], polarity_mask);
+       for (lane = 0; lane < mipi_csi2->num_data_lanes; lane++) {
+               /*
+                * Every lane are one nibble apart starting with the
+                * clock followed by the data lanes so shift masks by 4.
+                */
+               lane_mask <<= 4;
+               polarity_mask <<= 4;
+               set_field(&val, mipi_csi2->data_lanes[lane] + 1, lane_mask);
+               set_field(&val, mipi_csi2->lane_polarities[lane + 1],
+                         polarity_mask);
+       }
+
+       reg_write(ctx->dev, CAL_CSI2_COMPLEXIO_CFG(ctx->csi2_port), val);
+       ctx_dbg(3, ctx, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x\n",
+               ctx->csi2_port, val);
+}
+
+static void csi2_ppi_enable(struct cal_ctx *ctx)
+{
+       reg_write_field(ctx->dev, CAL_CSI2_PPI_CTRL(ctx->csi2_port),
+                       CAL_GEN_ENABLE, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
+}
+
+static void csi2_ppi_disable(struct cal_ctx *ctx)
+{
+       reg_write_field(ctx->dev, CAL_CSI2_PPI_CTRL(ctx->csi2_port),
+                       CAL_GEN_DISABLE, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
+}
+
+static void csi2_ctx_config(struct cal_ctx *ctx)
+{
+       u32 val;
+
+       val = reg_read(ctx->dev, CAL_CSI2_CTX0(ctx->csi2_port));
+       set_field(&val, ctx->csi2_port, CAL_CSI2_CTX_CPORT_MASK);
+       /*
+        * DT type: MIPI CSI-2 Specs
+        *   0x1: All - DT filter is disabled
+        *  0x24: RGB888 1 pixel  = 3 bytes
+        *  0x2B: RAW10  4 pixels = 5 bytes
+        *  0x2A: RAW8   1 pixel  = 1 byte
+        *  0x1E: YUV422 2 pixels = 4 bytes
+        */
+       set_field(&val, 0x1, CAL_CSI2_CTX_DT_MASK);
+       /* Virtual Channel from the CSI2 sensor usually 0! */
+       set_field(&val, ctx->virtual_channel, CAL_CSI2_CTX_VC_MASK);
+       /* NUM_LINES_PER_FRAME => 0 means auto detect */
+       set_field(&val, 0, CAL_CSI2_CTX_LINES_MASK);
+       set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK);
+       set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE,
+                 CAL_CSI2_CTX_PACK_MODE_MASK);
+       reg_write(ctx->dev, CAL_CSI2_CTX0(ctx->csi2_port), val);
+       ctx_dbg(3, ctx, "CAL_CSI2_CTX0(%d) = 0x%08x\n", ctx->csi2_port,
+               reg_read(ctx->dev, CAL_CSI2_CTX0(ctx->csi2_port)));
+}
+
+static void pix_proc_config(struct cal_ctx *ctx)
+{
+       u32 val;
+
+       val = reg_read(ctx->dev, CAL_PIX_PROC(ctx->csi2_port));
+       set_field(&val, CAL_PIX_PROC_EXTRACT_B8, CAL_PIX_PROC_EXTRACT_MASK);
+       set_field(&val, CAL_PIX_PROC_DPCMD_BYPASS, CAL_PIX_PROC_DPCMD_MASK);
+       set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK);
+       set_field(&val, CAL_PIX_PROC_PACK_B8, CAL_PIX_PROC_PACK_MASK);
+       set_field(&val, ctx->csi2_port, CAL_PIX_PROC_CPORT_MASK);
+       set_field(&val, CAL_GEN_ENABLE, CAL_PIX_PROC_EN_MASK);
+       reg_write(ctx->dev, CAL_PIX_PROC(ctx->csi2_port), val);
+       ctx_dbg(3, ctx, "CAL_PIX_PROC(%d) = 0x%08x\n", ctx->csi2_port,
+               reg_read(ctx->dev, CAL_PIX_PROC(ctx->csi2_port)));
+}
+
+static void cal_wr_dma_config(struct cal_ctx *ctx,
+                             unsigned int width)
+{
+       u32 val;
+
+       val = reg_read(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port));
+       set_field(&val, ctx->csi2_port, CAL_WR_DMA_CTRL_CPORT_MASK);
+       set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT,
+                 CAL_WR_DMA_CTRL_DTAG_MASK);
+       set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST,
+                 CAL_WR_DMA_CTRL_MODE_MASK);
+       set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR,
+                 CAL_WR_DMA_CTRL_PATTERN_MASK);
+       set_field(&val, CAL_GEN_ENABLE, CAL_WR_DMA_CTRL_STALL_RD_MASK);
+       reg_write(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port), val);
+       ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->csi2_port,
+               reg_read(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port)));
+
+       /*
+        * width/16 not sure but giving it a whirl.
+        * zero does not work right
+        */
+       reg_write_field(ctx->dev,
+                       CAL_WR_DMA_OFST(ctx->csi2_port),
+                       (width / 16),
+                       CAL_WR_DMA_OFST_MASK);
+       ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->csi2_port,
+               reg_read(ctx->dev, CAL_WR_DMA_OFST(ctx->csi2_port)));
+
+       val = reg_read(ctx->dev, CAL_WR_DMA_XSIZE(ctx->csi2_port));
+       /* 64 bit word means no skipping */
+       set_field(&val, 0, CAL_WR_DMA_XSIZE_XSKIP_MASK);
+       /*
+        * (width*8)/64 this should be size of an entire line
+        * in 64bit word but 0 means all data until the end
+        * is detected automagically
+        */
+       set_field(&val, (width / 8), CAL_WR_DMA_XSIZE_MASK);
+       reg_write(ctx->dev, CAL_WR_DMA_XSIZE(ctx->csi2_port), val);
+       ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->csi2_port,
+               reg_read(ctx->dev, CAL_WR_DMA_XSIZE(ctx->csi2_port)));
+}
+
+static void cal_wr_dma_addr(struct cal_ctx *ctx, unsigned int dmaaddr)
+{
+       reg_write(ctx->dev, CAL_WR_DMA_ADDR(ctx->csi2_port), dmaaddr);
+}
+
+/*
+ * TCLK values are OK at their reset values
+ */
+#define TCLK_TERM      0
+#define TCLK_MISS      1
+#define TCLK_SETTLE    14
+#define THS_SETTLE     15
+
+static void csi2_phy_config(struct cal_ctx *ctx)
+{
+       unsigned int reg0, reg1;
+       unsigned int ths_term, ths_settle;
+       unsigned int ddrclkperiod_us;
+
+       /*
+        * THS_TERM: Programmed value = floor(20 ns/DDRClk period) - 2.
+        */
+       ddrclkperiod_us = ctx->external_rate / 2000000;
+       ddrclkperiod_us = 1000000 / ddrclkperiod_us;
+       ctx_dbg(1, ctx, "ddrclkperiod_us: %d\n", ddrclkperiod_us);
+
+       ths_term = 20000 / ddrclkperiod_us;
+       ths_term = (ths_term >= 2) ? ths_term - 2 : ths_term;
+       ctx_dbg(1, ctx, "ths_term: %d (0x%02x)\n", ths_term, ths_term);
+
+       /*
+        * THS_SETTLE: Programmed value = floor(176.3 ns/CtrlClk period) - 1.
+        *      Since CtrlClk is fixed at 96Mhz then we get
+        *      ths_settle = floor(176.3 / 10.416) - 1 = 15
+        * If we ever switch to a dynamic clock then this code might be useful
+        *
+        * unsigned int ctrlclkperiod_us;
+        * ctrlclkperiod_us = 96000000 / 1000000;
+        * ctrlclkperiod_us = 1000000 / ctrlclkperiod_us;
+        * ctx_dbg(1, ctx, "ctrlclkperiod_us: %d\n", ctrlclkperiod_us);
+
+        * ths_settle = 176300  / ctrlclkperiod_us;
+        * ths_settle = (ths_settle > 1) ? ths_settle - 1 : ths_settle;
+        */
+
+       ths_settle = THS_SETTLE;
+       ctx_dbg(1, ctx, "ths_settle: %d (0x%02x)\n", ths_settle, ths_settle);
+
+       reg0 = reg_read(ctx->cc, CAL_CSI2_PHY_REG0);
+       set_field(&reg0, CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE,
+                 CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_MASK);
+       set_field(&reg0, ths_term, CAL_CSI2_PHY_REG0_THS_TERM_MASK);
+       set_field(&reg0, ths_settle, CAL_CSI2_PHY_REG0_THS_SETTLE_MASK);
+
+       ctx_dbg(1, ctx, "CSI2_%d_REG0 = 0x%08x\n", (ctx->csi2_port - 1), reg0);
+       reg_write(ctx->cc, CAL_CSI2_PHY_REG0, reg0);
+
+       reg1 = reg_read(ctx->cc, CAL_CSI2_PHY_REG1);
+       set_field(&reg1, TCLK_TERM, CAL_CSI2_PHY_REG1_TCLK_TERM_MASK);
+       set_field(&reg1, 0xb8, CAL_CSI2_PHY_REG1_DPHY_HS_SYNC_PATTERN_MASK);
+       set_field(&reg1, TCLK_MISS, CAL_CSI2_PHY_REG1_CTRLCLK_DIV_FACTOR_MASK);
+       set_field(&reg1, TCLK_SETTLE, CAL_CSI2_PHY_REG1_TCLK_SETTLE_MASK);
+
+       ctx_dbg(1, ctx, "CSI2_%d_REG1 = 0x%08x\n", (ctx->csi2_port - 1), reg1);
+       reg_write(ctx->cc, CAL_CSI2_PHY_REG1, reg1);
+}
+
+static int cal_get_external_info(struct cal_ctx *ctx)
+{
+       struct v4l2_ctrl *ctrl;
+
+       ctrl = v4l2_ctrl_find(ctx->sensor->ctrl_handler, V4L2_CID_PIXEL_RATE);
+       if (!ctrl) {
+               ctx_err(ctx, "no pixel rate control in subdev: %s\n",
+                       ctx->sensor->name);
+               return -EPIPE;
+       }
+
+       ctx->external_rate = v4l2_ctrl_g_ctrl_int64(ctrl);
+       ctx_dbg(3, ctx, "sensor Pixel Rate: %d\n", ctx->external_rate);
+
+       return 0;
+}
+
+static inline void cal_schedule_next_buffer(struct cal_ctx *ctx)
+{
+       struct cal_dmaqueue *dma_q = &ctx->vidq;
+       struct cal_buffer *buf;
+       unsigned long addr;
+
+       buf = list_entry(dma_q->active.next, struct cal_buffer, list);
+       ctx->next_frm = buf;
+       list_del(&buf->list);
+
+       addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+       cal_wr_dma_addr(ctx, addr);
+}
+
+static inline void cal_process_buffer_complete(struct cal_ctx *ctx)
+{
+       ctx->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
+       ctx->cur_frm->vb.field = ctx->m_fmt.field;
+       ctx->cur_frm->vb.sequence = ctx->sequence++;
+
+       vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
+       ctx->cur_frm = ctx->next_frm;
+}
+
+#define isvcirqset(irq, vc, ff) (irq & \
+       (CAL_CSI2_VC_IRQENABLE_ ##ff ##_IRQ_##vc ##_MASK))
+
+#define isportirqset(irq, port) (irq & CAL_HL_IRQ_MASK(port))
+
+static irqreturn_t cal_irq(int irq_cal, void *data)
+{
+       struct cal_dev *dev = (struct cal_dev *)data;
+       struct cal_ctx *ctx;
+       struct cal_dmaqueue *dma_q;
+       u32 irqst2, irqst3;
+
+       /* Check which DMA just finished */
+       irqst2 = reg_read(dev, CAL_HL_IRQSTATUS(2));
+       if (irqst2) {
+               /* Clear Interrupt status */
+               reg_write(dev, CAL_HL_IRQSTATUS(2), irqst2);
+
+               /* Need to check both port */
+               if (isportirqset(irqst2, 1)) {
+                       ctx = dev->ctx[0];
+
+                       if (ctx->cur_frm != ctx->next_frm)
+                               cal_process_buffer_complete(ctx);
+               }
+
+               if (isportirqset(irqst2, 2)) {
+                       ctx = dev->ctx[1];
+
+                       if (ctx->cur_frm != ctx->next_frm)
+                               cal_process_buffer_complete(ctx);
+               }
+       }
+
+       /* Check which DMA just started */
+       irqst3 = reg_read(dev, CAL_HL_IRQSTATUS(3));
+       if (irqst3) {
+               /* Clear Interrupt status */
+               reg_write(dev, CAL_HL_IRQSTATUS(3), irqst3);
+
+               /* Need to check both port */
+               if (isportirqset(irqst3, 1)) {
+                       ctx = dev->ctx[0];
+                       dma_q = &ctx->vidq;
+
+                       spin_lock(&ctx->slock);
+                       if (!list_empty(&dma_q->active) &&
+                           ctx->cur_frm == ctx->next_frm)
+                               cal_schedule_next_buffer(ctx);
+                       spin_unlock(&ctx->slock);
+               }
+
+               if (isportirqset(irqst3, 2)) {
+                       ctx = dev->ctx[1];
+                       dma_q = &ctx->vidq;
+
+                       spin_lock(&ctx->slock);
+                       if (!list_empty(&dma_q->active) &&
+                           ctx->cur_frm == ctx->next_frm)
+                               cal_schedule_next_buffer(ctx);
+                       spin_unlock(&ctx->slock);
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * video ioctls
+ */
+static int cal_querycap(struct file *file, void *priv,
+                       struct v4l2_capability *cap)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+
+       strlcpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver));
+       strlcpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card));
+
+       snprintf(cap->bus_info, sizeof(cap->bus_info),
+                "platform:%s", ctx->v4l2_dev.name);
+       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+                           V4L2_CAP_READWRITE;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+       return 0;
+}
+
+static int cal_enum_fmt_vid_cap(struct file *file, void  *priv,
+                               struct v4l2_fmtdesc *f)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+       const struct cal_fmt *fmt = NULL;
+
+       if (f->index >= ctx->num_active_fmt)
+               return -EINVAL;
+
+       fmt = ctx->active_fmt[f->index];
+
+       f->pixelformat = fmt->fourcc;
+       f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       return 0;
+}
+
+static int __subdev_get_format(struct cal_ctx *ctx,
+                              struct v4l2_mbus_framefmt *fmt)
+{
+       struct v4l2_subdev_format sd_fmt;
+       struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
+       int ret;
+
+       if (!ctx->sensor)
+               return -EINVAL;
+
+       sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+       sd_fmt.pad = 0;
+
+       ret = v4l2_subdev_call(ctx->sensor, pad, get_fmt, NULL, &sd_fmt);
+       if (ret)
+               return ret;
+
+       *fmt = *mbus_fmt;
+
+       ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
+               fmt->width, fmt->height, fmt->code);
+
+       return 0;
+}
+
+static int __subdev_set_format(struct cal_ctx *ctx,
+                              struct v4l2_mbus_framefmt *fmt)
+{
+       struct v4l2_subdev_format sd_fmt;
+       struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
+       int ret;
+
+       if (!ctx->sensor)
+               return -EINVAL;
+
+       sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+       sd_fmt.pad = 0;
+       *mbus_fmt = *fmt;
+
+       ret = v4l2_subdev_call(ctx->sensor, pad, set_fmt, NULL, &sd_fmt);
+       if (ret)
+               return ret;
+
+       ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
+               fmt->width, fmt->height, fmt->code);
+
+       return 0;
+}
+
+static int cal_calc_format_size(struct cal_ctx *ctx,
+                               const struct cal_fmt *fmt,
+                               struct v4l2_format *f)
+{
+       if (!fmt) {
+               ctx_dbg(3, ctx, "No cal_fmt provided!\n");
+               return -EINVAL;
+       }
+
+       v4l_bound_align_image(&f->fmt.pix.width, 48, MAX_WIDTH, 2,
+                             &f->fmt.pix.height, 32, MAX_HEIGHT, 0, 0);
+       f->fmt.pix.bytesperline = bytes_per_line(f->fmt.pix.width,
+                                                fmt->depth >> 3);
+       f->fmt.pix.sizeimage = f->fmt.pix.height *
+                              f->fmt.pix.bytesperline;
+
+       ctx_dbg(3, ctx, "%s: fourcc: %s size: %dx%d bpl:%d img_size:%d\n",
+               __func__, fourcc_to_str(f->fmt.pix.pixelformat),
+               f->fmt.pix.width, f->fmt.pix.height,
+               f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+
+       return 0;
+}
+
+static int cal_g_fmt_vid_cap(struct file *file, void *priv,
+                            struct v4l2_format *f)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+
+       *f = ctx->v_fmt;
+
+       return 0;
+}
+
+static int cal_try_fmt_vid_cap(struct file *file, void *priv,
+                              struct v4l2_format *f)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+       const struct cal_fmt *fmt;
+       struct v4l2_subdev_frame_size_enum fse;
+       int ret, found;
+
+       fmt = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
+       if (!fmt) {
+               ctx_dbg(3, ctx, "Fourcc format (0x%08x) not found.\n",
+                       f->fmt.pix.pixelformat);
+
+               /* Just get the first one enumerated */
+               fmt = ctx->active_fmt[0];
+               f->fmt.pix.pixelformat = fmt->fourcc;
+       }
+
+       f->fmt.pix.field = ctx->v_fmt.fmt.pix.field;
+
+       /* check for/find a valid width/height */
+       ret = 0;
+       found = false;
+       fse.pad = 0;
+       fse.code = fmt->code;
+       fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+       for (fse.index = 0; ; fse.index++) {
+               ret = v4l2_subdev_call(ctx->sensor, pad, enum_frame_size,
+                                      NULL, &fse);
+               if (ret)
+                       break;
+
+               if ((f->fmt.pix.width == fse.max_width) &&
+                   (f->fmt.pix.height == fse.max_height)) {
+                       found = true;
+                       break;
+               } else if ((f->fmt.pix.width >= fse.min_width) &&
+                        (f->fmt.pix.width <= fse.max_width) &&
+                        (f->fmt.pix.height >= fse.min_height) &&
+                        (f->fmt.pix.height <= fse.max_height)) {
+                       found = true;
+                       break;
+               }
+       }
+
+       if (!found) {
+               /* use existing values as default */
+               f->fmt.pix.width = ctx->v_fmt.fmt.pix.width;
+               f->fmt.pix.height =  ctx->v_fmt.fmt.pix.height;
+       }
+
+       /*
+        * Use current colorspace for now, it will get
+        * updated properly during s_fmt
+        */
+       f->fmt.pix.colorspace = ctx->v_fmt.fmt.pix.colorspace;
+       return cal_calc_format_size(ctx, fmt, f);
+}
+
+static int cal_s_fmt_vid_cap(struct file *file, void *priv,
+                            struct v4l2_format *f)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+       struct vb2_queue *q = &ctx->vb_vidq;
+       const struct cal_fmt *fmt;
+       struct v4l2_mbus_framefmt mbus_fmt;
+       int ret;
+
+       if (vb2_is_busy(q)) {
+               ctx_dbg(3, ctx, "%s device busy\n", __func__);
+               return -EBUSY;
+       }
+
+       ret = cal_try_fmt_vid_cap(file, priv, f);
+       if (ret < 0)
+               return ret;
+
+       fmt = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
+
+       v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code);
+
+       ret = __subdev_set_format(ctx, &mbus_fmt);
+       if (ret)
+               return ret;
+
+       /* Just double check nothing has gone wrong */
+       if (mbus_fmt.code != fmt->code) {
+               ctx_dbg(3, ctx,
+                       "%s subdev changed format on us, this should not happen\n",
+                       __func__);
+               return -EINVAL;
+       }
+
+       v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &mbus_fmt);
+       ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       ctx->v_fmt.fmt.pix.pixelformat  = fmt->fourcc;
+       cal_calc_format_size(ctx, fmt, &ctx->v_fmt);
+       ctx->fmt = fmt;
+       ctx->m_fmt = mbus_fmt;
+       *f = ctx->v_fmt;
+
+       return 0;
+}
+
+static int cal_enum_framesizes(struct file *file, void *fh,
+                              struct v4l2_frmsizeenum *fsize)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+       const struct cal_fmt *fmt;
+       struct v4l2_subdev_frame_size_enum fse;
+       int ret;
+
+       /* check for valid format */
+       fmt = find_format_by_pix(ctx, fsize->pixel_format);
+       if (!fmt) {
+               ctx_dbg(3, ctx, "Invalid pixel code: %x\n",
+                       fsize->pixel_format);
+               return -EINVAL;
+       }
+
+       fse.index = fsize->index;
+       fse.pad = 0;
+       fse.code = fmt->code;
+
+       ret = v4l2_subdev_call(ctx->sensor, pad, enum_frame_size, NULL, &fse);
+       if (ret)
+               return -EINVAL;
+
+       ctx_dbg(1, ctx, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
+               __func__, fse.index, fse.code, fse.min_width, fse.max_width,
+               fse.min_height, fse.max_height);
+
+       fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       fsize->discrete.width = fse.max_width;
+       fsize->discrete.height = fse.max_height;
+
+       return 0;
+}
+
+static int cal_enum_input(struct file *file, void *priv,
+                         struct v4l2_input *inp)
+{
+       if (inp->index >= CAL_NUM_INPUT)
+               return -EINVAL;
+
+       inp->type = V4L2_INPUT_TYPE_CAMERA;
+       sprintf(inp->name, "Camera %u", inp->index);
+       return 0;
+}
+
+static int cal_g_input(struct file *file, void *priv, unsigned int *i)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+
+       *i = ctx->input;
+       return 0;
+}
+
+static int cal_s_input(struct file *file, void *priv, unsigned int i)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+
+       if (i >= CAL_NUM_INPUT)
+               return -EINVAL;
+
+       ctx->input = i;
+       return 0;
+}
+
+/* timeperframe is arbitrary and continuous */
+static int cal_enum_frameintervals(struct file *file, void *priv,
+                                  struct v4l2_frmivalenum *fival)
+{
+       struct cal_ctx *ctx = video_drvdata(file);
+       const struct cal_fmt *fmt;
+       struct v4l2_subdev_frame_size_enum fse;
+       int ret;
+
+       if (fival->index)
+               return -EINVAL;
+
+       fmt = find_format_by_pix(ctx, fival->pixel_format);
+       if (!fmt)
+               return -EINVAL;
+
+       /* check for valid width/height */
+       ret = 0;
+       fse.pad = 0;
+       fse.code = fmt->code;
+       fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+       for (fse.index = 0; ; fse.index++) {
+               ret = v4l2_subdev_call(ctx->sensor, pad, enum_frame_size,
+                                      NULL, &fse);
+               if (ret)
+                       return -EINVAL;
+
+               if ((fival->width == fse.max_width) &&
+                   (fival->height == fse.max_height))
+                       break;
+               else if ((fival->width >= fse.min_width) &&
+                        (fival->width <= fse.max_width) &&
+                        (fival->height >= fse.min_height) &&
+                        (fival->height <= fse.max_height))
+                       break;
+
+               return -EINVAL;
+       }
+
+       fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+       fival->discrete.numerator = 1;
+       fival->discrete.denominator = 30;
+
+       return 0;
+}
+
+/*
+ * Videobuf operations
+ */
+static int cal_queue_setup(struct vb2_queue *vq,
+                          unsigned int *nbuffers, unsigned int *nplanes,
+                          unsigned int sizes[], void *alloc_ctxs[])
+{
+       struct cal_ctx *ctx = vb2_get_drv_priv(vq);
+       unsigned size = ctx->v_fmt.fmt.pix.sizeimage;
+
+       if (vq->num_buffers + *nbuffers < 3)
+               *nbuffers = 3 - vq->num_buffers;
+       alloc_ctxs[0] = ctx->alloc_ctx;
+
+       if (*nplanes) {
+               if (sizes[0] < size)
+                       return -EINVAL;
+               size = sizes[0];
+       }
+
+       *nplanes = 1;
+       sizes[0] = size;
+
+       ctx_dbg(3, ctx, "nbuffers=%d, size=%d\n", *nbuffers, sizes[0]);
+
+       return 0;
+}
+
+static int cal_buffer_prepare(struct vb2_buffer *vb)
+{
+       struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+       struct cal_buffer *buf = container_of(vb, struct cal_buffer,
+                                             vb.vb2_buf);
+       unsigned long size;
+
+       if (WARN_ON(!ctx->fmt))
+               return -EINVAL;
+
+       size = ctx->v_fmt.fmt.pix.sizeimage;
+       if (vb2_plane_size(vb, 0) < size) {
+               ctx_err(ctx,
+                       "data will not fit into plane (%lu < %lu)\n",
+                       vb2_plane_size(vb, 0), size);
+               return -EINVAL;
+       }
+
+       vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
+       return 0;
+}
+
+static void cal_buffer_queue(struct vb2_buffer *vb)
+{
+       struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+       struct cal_buffer *buf = container_of(vb, struct cal_buffer,
+                                             vb.vb2_buf);
+       struct cal_dmaqueue *vidq = &ctx->vidq;
+       unsigned long flags = 0;
+
+       /* recheck locking */
+       spin_lock_irqsave(&ctx->slock, flags);
+       list_add_tail(&buf->list, &vidq->active);
+       spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct cal_ctx *ctx = vb2_get_drv_priv(vq);
+       struct cal_dmaqueue *dma_q = &ctx->vidq;
+       struct cal_buffer *buf, *tmp;
+       unsigned long addr = 0;
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&ctx->slock, flags);
+       if (list_empty(&dma_q->active)) {
+               spin_unlock_irqrestore(&ctx->slock, flags);
+               ctx_dbg(3, ctx, "buffer queue is empty\n");
+               return -EIO;
+       }
+
+       buf = list_entry(dma_q->active.next, struct cal_buffer, list);
+       ctx->cur_frm = buf;
+       ctx->next_frm = buf;
+       list_del(&buf->list);
+       spin_unlock_irqrestore(&ctx->slock, flags);
+
+       addr = vb2_dma_contig_plane_dma_addr(&ctx->cur_frm->vb.vb2_buf, 0);
+       ctx->sequence = 0;
+
+       ret = cal_get_external_info(ctx);
+       if (ret < 0)
+               goto err;
+
+       cal_runtime_get(ctx->dev);
+
+       enable_irqs(ctx);
+       camerarx_phy_enable(ctx);
+       csi2_init(ctx);
+       csi2_phy_config(ctx);
+       csi2_lane_config(ctx);
+       csi2_ctx_config(ctx);
+       pix_proc_config(ctx);
+       cal_wr_dma_config(ctx, ctx->v_fmt.fmt.pix.bytesperline);
+       cal_wr_dma_addr(ctx, addr);
+       csi2_ppi_enable(ctx);
+
+       if (ctx->sensor) {
+               if (v4l2_subdev_call(ctx->sensor, video, s_stream, 1)) {
+                       ctx_err(ctx, "stream on failed in subdev\n");
+                       cal_runtime_put(ctx->dev);
+                       ret = -EINVAL;
+                       goto err;
+               }
+       }
+
+       if (debug >= 4)
+               cal_quickdump_regs(ctx->dev);
+
+       return 0;
+
+err:
+       list_for_each_entry_safe(buf, tmp, &dma_q->active, list) {
+               list_del(&buf->list);
+               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+       }
+       return ret;
+}
+
+static void cal_stop_streaming(struct vb2_queue *vq)
+{
+       struct cal_ctx *ctx = vb2_get_drv_priv(vq);
+       struct cal_dmaqueue *dma_q = &ctx->vidq;
+       struct cal_buffer *buf, *tmp;
+       unsigned long flags;
+
+       if (ctx->sensor) {
+               if (v4l2_subdev_call(ctx->sensor, video, s_stream, 0))
+                       ctx_err(ctx, "stream off failed in subdev\n");
+       }
+
+       csi2_ppi_disable(ctx);
+       disable_irqs(ctx);
+
+       /* Release all active buffers */
+       spin_lock_irqsave(&ctx->slock, flags);
+       list_for_each_entry_safe(buf, tmp, &dma_q->active, list) {
+               list_del(&buf->list);
+               vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+       }
+
+       if (ctx->cur_frm == ctx->next_frm) {
+               vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+       } else {
+               vb2_buffer_done(&ctx->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+               vb2_buffer_done(&ctx->next_frm->vb.vb2_buf,
+                               VB2_BUF_STATE_ERROR);
+       }
+       ctx->cur_frm = NULL;
+       ctx->next_frm = NULL;
+       spin_unlock_irqrestore(&ctx->slock, flags);
+
+       cal_runtime_put(ctx->dev);
+}
+
+static struct vb2_ops cal_video_qops = {
+       .queue_setup            = cal_queue_setup,
+       .buf_prepare            = cal_buffer_prepare,
+       .buf_queue              = cal_buffer_queue,
+       .start_streaming        = cal_start_streaming,
+       .stop_streaming         = cal_stop_streaming,
+       .wait_prepare           = vb2_ops_wait_prepare,
+       .wait_finish            = vb2_ops_wait_finish,
+};
+
+static const struct v4l2_file_operations cal_fops = {
+       .owner          = THIS_MODULE,
+       .open           = v4l2_fh_open,
+       .release        = vb2_fop_release,
+       .read           = vb2_fop_read,
+       .poll           = vb2_fop_poll,
+       .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+       .mmap           = vb2_fop_mmap,
+};
+
+static const struct v4l2_ioctl_ops cal_ioctl_ops = {
+       .vidioc_querycap      = cal_querycap,
+       .vidioc_enum_fmt_vid_cap  = cal_enum_fmt_vid_cap,
+       .vidioc_g_fmt_vid_cap     = cal_g_fmt_vid_cap,
+       .vidioc_try_fmt_vid_cap   = cal_try_fmt_vid_cap,
+       .vidioc_s_fmt_vid_cap     = cal_s_fmt_vid_cap,
+       .vidioc_enum_framesizes   = cal_enum_framesizes,
+       .vidioc_reqbufs       = vb2_ioctl_reqbufs,
+       .vidioc_create_bufs   = vb2_ioctl_create_bufs,
+       .vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+       .vidioc_querybuf      = vb2_ioctl_querybuf,
+       .vidioc_qbuf          = vb2_ioctl_qbuf,
+       .vidioc_dqbuf         = vb2_ioctl_dqbuf,
+       .vidioc_enum_input    = cal_enum_input,
+       .vidioc_g_input       = cal_g_input,
+       .vidioc_s_input       = cal_s_input,
+       .vidioc_enum_frameintervals = cal_enum_frameintervals,
+       .vidioc_streamon      = vb2_ioctl_streamon,
+       .vidioc_streamoff     = vb2_ioctl_streamoff,
+       .vidioc_log_status    = v4l2_ctrl_log_status,
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static struct video_device cal_videodev = {
+       .name           = CAL_MODULE_NAME,
+       .fops           = &cal_fops,
+       .ioctl_ops      = &cal_ioctl_ops,
+       .minor          = -1,
+       .release        = video_device_release_empty,
+};
+
+/* -----------------------------------------------------------------
+ *     Initialization and module stuff
+ * ------------------------------------------------------------------
+ */
+static int cal_complete_ctx(struct cal_ctx *ctx);
+
+static int cal_async_bound(struct v4l2_async_notifier *notifier,
+                          struct v4l2_subdev *subdev,
+                          struct v4l2_async_subdev *asd)
+{
+       struct cal_ctx *ctx = notifier_to_ctx(notifier);
+       struct v4l2_subdev_mbus_code_enum mbus_code;
+       int ret = 0;
+       int i, j, k;
+
+       if (ctx->sensor) {
+               ctx_info(ctx, "Rejecting subdev %s (Already set!!)",
+                        subdev->name);
+               return 0;
+       }
+
+       ctx->sensor = subdev;
+       ctx_dbg(1, ctx, "Using sensor %s for capture\n", subdev->name);
+
+       /* Enumerate sub device formats and enable all matching local formats */
+       ctx->num_active_fmt = 0;
+       for (j = 0, i = 0; ret != -EINVAL; ++j) {
+               struct cal_fmt *fmt;
+
+               memset(&mbus_code, 0, sizeof(mbus_code));
+               mbus_code.index = j;
+               ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
+                                      NULL, &mbus_code);
+               if (ret)
+                       continue;
+
+               ctx_dbg(2, ctx,
+                       "subdev %s: code: %04x idx: %d\n",
+                       subdev->name, mbus_code.code, j);
+
+               for (k = 0; k < ARRAY_SIZE(cal_formats); k++) {
+                       fmt = &cal_formats[k];
+
+                       if (mbus_code.code == fmt->code) {
+                               ctx->active_fmt[i] = fmt;
+                               ctx_dbg(2, ctx,
+                                       "matched fourcc: %s: code: %04x idx: %d\n",
+                                       fourcc_to_str(fmt->fourcc),
+                                       fmt->code, i);
+                               ctx->num_active_fmt = ++i;
+                       }
+               }
+       }
+
+       if (i == 0) {
+               ctx_err(ctx, "No suitable format reported by subdev %s\n",
+                       subdev->name);
+               return -EINVAL;
+       }
+
+       cal_complete_ctx(ctx);
+
+       return 0;
+}
+
+static int cal_async_complete(struct v4l2_async_notifier *notifier)
+{
+       struct cal_ctx *ctx = notifier_to_ctx(notifier);
+       const struct cal_fmt *fmt;
+       struct v4l2_mbus_framefmt mbus_fmt;
+       int ret;
+
+       ret = __subdev_get_format(ctx, &mbus_fmt);
+       if (ret)
+               return ret;
+
+       fmt = find_format_by_code(ctx, mbus_fmt.code);
+       if (!fmt) {
+               ctx_dbg(3, ctx, "mbus code format (0x%08x) not found.\n",
+                       mbus_fmt.code);
+               return -EINVAL;
+       }
+
+       /* Save current subdev format */
+       v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &mbus_fmt);
+       ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       ctx->v_fmt.fmt.pix.pixelformat  = fmt->fourcc;
+       cal_calc_format_size(ctx, fmt, &ctx->v_fmt);
+       ctx->fmt = fmt;
+       ctx->m_fmt = mbus_fmt;
+
+       return 0;
+}
+
+static int cal_complete_ctx(struct cal_ctx *ctx)
+{
+       struct video_device *vfd;
+       struct vb2_queue *q;
+       int ret;
+
+       ctx->timeperframe = tpf_default;
+       ctx->external_rate = 192000000;
+
+       /* initialize locks */
+       spin_lock_init(&ctx->slock);
+       mutex_init(&ctx->mutex);
+
+       /* initialize queue */
+       q = &ctx->vb_vidq;
+       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
+       q->drv_priv = ctx;
+       q->buf_struct_size = sizeof(struct cal_buffer);
+       q->ops = &cal_video_qops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       q->lock = &ctx->mutex;
+       q->min_buffers_needed = 3;
+
+       ret = vb2_queue_init(q);
+       if (ret)
+               return ret;
+
+       /* init video dma queues */
+       INIT_LIST_HEAD(&ctx->vidq.active);
+
+       vfd = &ctx->vdev;
+       *vfd = cal_videodev;
+       vfd->v4l2_dev = &ctx->v4l2_dev;
+       vfd->queue = q;
+
+       /*
+        * Provide a mutex to v4l2 core. It will be used to protect
+        * all fops and v4l2 ioctls.
+        */
+       vfd->lock = &ctx->mutex;
+       video_set_drvdata(vfd, ctx);
+
+       ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
+       if (ret < 0)
+               return ret;
+
+       v4l2_info(&ctx->v4l2_dev, "V4L2 device registered as %s\n",
+                 video_device_node_name(vfd));
+
+       ctx->alloc_ctx = vb2_dma_contig_init_ctx(vfd->v4l2_dev->dev);
+       if (IS_ERR(ctx->alloc_ctx)) {
+               ctx_err(ctx, "Failed to alloc vb2 context\n");
+               ret = PTR_ERR(ctx->alloc_ctx);
+               goto vdev_unreg;
+       }
+
+       return 0;
+
+vdev_unreg:
+       video_unregister_device(vfd);
+       return ret;
+}
+
+static struct device_node *
+of_get_next_port(const struct device_node *parent,
+                struct device_node *prev)
+{
+       struct device_node *port = NULL;
+
+       if (!parent)
+               return NULL;
+
+       if (!prev) {
+               struct device_node *ports;
+               /*
+                * It's the first call, we have to find a port subnode
+                * within this node or within an optional 'ports' node.
+                */
+               ports = of_get_child_by_name(parent, "ports");
+               if (ports)
+                       parent = ports;
+
+               port = of_get_child_by_name(parent, "port");
+
+               /* release the 'ports' node */
+               of_node_put(ports);
+       } else {
+               struct device_node *ports;
+
+               ports = of_get_parent(prev);
+               if (!ports)
+                       return NULL;
+
+               do {
+                       port = of_get_next_child(ports, prev);
+                       if (!port) {
+                               of_node_put(ports);
+                               return NULL;
+                       }
+                       prev = port;
+               } while (of_node_cmp(port->name, "port") != 0);
+       }
+
+       return port;
+}
+
+static struct device_node *
+of_get_next_endpoint(const struct device_node *parent,
+                    struct device_node *prev)
+{
+       struct device_node *ep = NULL;
+
+       if (!parent)
+               return NULL;
+
+       do {
+               ep = of_get_next_child(parent, prev);
+               if (!ep)
+                       return NULL;
+               prev = ep;
+       } while (of_node_cmp(ep->name, "endpoint") != 0);
+
+       return ep;
+}
+
+static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
+{
+       struct platform_device *pdev = ctx->dev->pdev;
+       struct device_node *ep_node, *port, *remote_ep,
+                       *sensor_node, *parent;
+       struct v4l2_of_endpoint *endpoint;
+       struct v4l2_async_subdev *asd;
+       u32 regval = 0;
+       int ret, index, found_port = 0, lane;
+
+       parent = pdev->dev.of_node;
+
+       asd = &ctx->asd;
+       endpoint = &ctx->endpoint;
+
+       ep_node = NULL;
+       port = NULL;
+       remote_ep = NULL;
+       sensor_node = NULL;
+       ret = -EINVAL;
+
+       ctx_dbg(3, ctx, "Scanning Port node for csi2 port: %d\n", inst);
+       for (index = 0; index < CAL_NUM_CSI2_PORTS; index++) {
+               port = of_get_next_port(parent, port);
+               if (!port) {
+                       ctx_dbg(1, ctx, "No port node found for csi2 port:%d\n",
+                               index);
+                       goto cleanup_exit;
+               }
+
+               /* Match the slice number with <REG> */
+               of_property_read_u32(port, "reg", &regval);
+               ctx_dbg(3, ctx, "port:%d inst:%d <reg>:%d\n",
+                       index, inst, regval);
+               if ((regval == inst) && (index == inst)) {
+                       found_port = 1;
+                       break;
+               }
+       }
+
+       if (!found_port) {
+               ctx_dbg(1, ctx, "No port node matches csi2 port:%d\n",
+                       inst);
+               goto cleanup_exit;
+       }
+
+       ctx_dbg(3, ctx, "Scanning sub-device for csi2 port: %d\n",
+               inst);
+
+       ep_node = of_get_next_endpoint(port, ep_node);
+       if (!ep_node) {
+               ctx_dbg(3, ctx, "can't get next endpoint\n");
+               goto cleanup_exit;
+       }
+
+       sensor_node = of_graph_get_remote_port_parent(ep_node);
+       if (!sensor_node) {
+               ctx_dbg(3, ctx, "can't get remote parent\n");
+               goto cleanup_exit;
+       }
+       asd->match_type = V4L2_ASYNC_MATCH_OF;
+       asd->match.of.node = sensor_node;
+
+       remote_ep = of_parse_phandle(ep_node, "remote-endpoint", 0);
+       if (!remote_ep) {
+               ctx_dbg(3, ctx, "can't get remote-endpoint\n");
+               goto cleanup_exit;
+       }
+       v4l2_of_parse_endpoint(remote_ep, endpoint);
+
+       if (endpoint->bus_type != V4L2_MBUS_CSI2) {
+               ctx_err(ctx, "Port:%d sub-device %s is not a CSI2 device\n",
+                       inst, sensor_node->name);
+               goto cleanup_exit;
+       }
+
+       /* Store Virtual Channel number */
+       ctx->virtual_channel = endpoint->base.id;
+
+       ctx_dbg(3, ctx, "Port:%d v4l2-endpoint: CSI2\n", inst);
+       ctx_dbg(3, ctx, "Virtual Channel=%d\n", ctx->virtual_channel);
+       ctx_dbg(3, ctx, "flags=0x%08x\n", endpoint->bus.mipi_csi2.flags);
+       ctx_dbg(3, ctx, "clock_lane=%d\n", endpoint->bus.mipi_csi2.clock_lane);
+       ctx_dbg(3, ctx, "num_data_lanes=%d\n",
+               endpoint->bus.mipi_csi2.num_data_lanes);
+       ctx_dbg(3, ctx, "data_lanes= <\n");
+       for (lane = 0; lane < endpoint->bus.mipi_csi2.num_data_lanes; lane++)
+               ctx_dbg(3, ctx, "\t%d\n",
+                       endpoint->bus.mipi_csi2.data_lanes[lane]);
+       ctx_dbg(3, ctx, "\t>\n");
+
+       ctx_dbg(1, ctx, "Port: %d found sub-device %s\n",
+               inst, sensor_node->name);
+
+       ctx->asd_list[0] = asd;
+       ctx->notifier.subdevs = ctx->asd_list;
+       ctx->notifier.num_subdevs = 1;
+       ctx->notifier.bound = cal_async_bound;
+       ctx->notifier.complete = cal_async_complete;
+       ret = v4l2_async_notifier_register(&ctx->v4l2_dev,
+                                          &ctx->notifier);
+       if (ret) {
+               ctx_err(ctx, "Error registering async notifier\n");
+               ret = -EINVAL;
+       }
+
+cleanup_exit:
+       if (!remote_ep)
+               of_node_put(remote_ep);
+       if (!sensor_node)
+               of_node_put(sensor_node);
+       if (!ep_node)
+               of_node_put(ep_node);
+       if (!port)
+               of_node_put(port);
+
+       return ret;
+}
+
+static struct cal_ctx *cal_create_instance(struct cal_dev *dev, int inst)
+{
+       struct cal_ctx *ctx;
+       struct v4l2_ctrl_handler *hdl;
+       int ret;
+
+       ctx = devm_kzalloc(&dev->pdev->dev, sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return 0;
+
+       /* save the cal_dev * for future ref */
+       ctx->dev = dev;
+
+       snprintf(ctx->v4l2_dev.name, sizeof(ctx->v4l2_dev.name),
+                "%s-%03d", CAL_MODULE_NAME, inst);
+       ret = v4l2_device_register(&dev->pdev->dev, &ctx->v4l2_dev);
+       if (ret)
+               goto err_exit;
+
+       hdl = &ctx->ctrl_handler;
+       ret = v4l2_ctrl_handler_init(hdl, 11);
+       if (ret) {
+               ctx_err(ctx, "Failed to init ctrl handler\n");
+               goto unreg_dev;
+       }
+       ctx->v4l2_dev.ctrl_handler = hdl;
+
+       /* Make sure Camera Core H/W register area is available */
+       ctx->cc = dev->cc[inst];
+
+       /* Store the instance id */
+       ctx->csi2_port = inst + 1;
+
+       ret = of_cal_create_instance(ctx, inst);
+       if (ret) {
+               ret = -EINVAL;
+               goto free_hdl;
+       }
+       return ctx;
+
+free_hdl:
+       v4l2_ctrl_handler_free(hdl);
+unreg_dev:
+       v4l2_device_unregister(&ctx->v4l2_dev);
+err_exit:
+       return 0;
+}
+
+static int cal_probe(struct platform_device *pdev)
+{
+       struct cal_dev *dev;
+       int ret;
+       int irq;
+
+       dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return -ENOMEM;
+
+       /* set pseudo v4l2 device name so we can use v4l2_printk */
+       strlcpy(dev->v4l2_dev.name, CAL_MODULE_NAME,
+               sizeof(dev->v4l2_dev.name));
+
+       /* save pdev pointer */
+       dev->pdev = pdev;
+
+       dev->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                               "cal_top");
+       dev->base = devm_ioremap_resource(&pdev->dev, dev->res);
+       if (IS_ERR(dev->base))
+               return PTR_ERR(dev->base);
+
+       cal_dbg(1, dev, "ioresource %s at %pa - %pa\n",
+               dev->res->name, &dev->res->start, &dev->res->end);
+
+       irq = platform_get_irq(pdev, 0);
+       cal_dbg(1, dev, "got irq# %d\n", irq);
+       ret = devm_request_irq(&pdev->dev, irq, cal_irq, 0, CAL_MODULE_NAME,
+                              dev);
+       if (ret)
+               return ret;
+
+       platform_set_drvdata(pdev, dev);
+
+       dev->cm = cm_create(dev);
+       if (IS_ERR(dev->cm))
+               return PTR_ERR(dev->cm);
+
+       dev->cc[0] = cc_create(dev, 0);
+       if (IS_ERR(dev->cc[0]))
+               return PTR_ERR(dev->cc[0]);
+
+       dev->cc[1] = cc_create(dev, 1);
+       if (IS_ERR(dev->cc[1]))
+               return PTR_ERR(dev->cc[1]);
+
+       dev->ctx[0] = NULL;
+       dev->ctx[1] = NULL;
+
+       dev->ctx[0] = cal_create_instance(dev, 0);
+       dev->ctx[1] = cal_create_instance(dev, 1);
+       if (!dev->ctx[0] && !dev->ctx[1]) {
+               cal_err(dev, "Neither port is configured, no point in staying up\n");
+               return -ENODEV;
+       }
+
+       pm_runtime_enable(&pdev->dev);
+
+       ret = cal_runtime_get(dev);
+       if (ret)
+               goto runtime_disable;
+
+       /* Just check we can actually access the module */
+       cal_get_hwinfo(dev);
+
+       cal_runtime_put(dev);
+
+       return 0;
+
+runtime_disable:
+       pm_runtime_disable(&pdev->dev);
+       return ret;
+}
+
+static int cal_remove(struct platform_device *pdev)
+{
+       struct cal_dev *dev =
+               (struct cal_dev *)platform_get_drvdata(pdev);
+       struct cal_ctx *ctx;
+       int i;
+
+       cal_dbg(1, dev, "Removing %s\n", CAL_MODULE_NAME);
+
+       cal_runtime_get(dev);
+
+       for (i = 0; i < CAL_NUM_CONTEXT; i++) {
+               ctx = dev->ctx[i];
+               if (ctx) {
+                       ctx_dbg(1, ctx, "unregistering %s\n",
+                               video_device_node_name(&ctx->vdev));
+                       camerarx_phy_disable(ctx);
+                       v4l2_async_notifier_unregister(&ctx->notifier);
+                       vb2_dma_contig_cleanup_ctx(ctx->alloc_ctx);
+                       v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+                       v4l2_device_unregister(&ctx->v4l2_dev);
+                       video_unregister_device(&ctx->vdev);
+               }
+       }
+
+       cal_runtime_put(dev);
+       pm_runtime_disable(&pdev->dev);
+
+       return 0;
+}
+
+#if defined(CONFIG_OF)
+static const struct of_device_id cal_of_match[] = {
+       { .compatible = "ti,dra72-cal", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, cal_of_match);
+#endif
+
+static struct platform_driver cal_pdrv = {
+       .probe          = cal_probe,
+       .remove         = cal_remove,
+       .driver         = {
+               .name   = CAL_MODULE_NAME,
+               .of_match_table = of_match_ptr(cal_of_match),
+       },
+};
+
+module_platform_driver(cal_pdrv);
diff --git a/drivers/media/platform/ti-vpe/cal_regs.h b/drivers/media/platform/ti-vpe/cal_regs.h
new file mode 100644 (file)
index 0000000..82b3dcf
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * TI CAL camera interface driver
+ *
+ * Copyright (c) 2015 Texas Instruments Inc.
+ *
+ * Benoit Parrot, <bparrot@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef __TI_CAL_REGS_H
+#define __TI_CAL_REGS_H
+
+#define CAL_NUM_CSI2_PORTS             2
+
+/* CAL register offsets */
+
+#define CAL_HL_REVISION                        0x0000
+#define CAL_HL_HWINFO                  0x0004
+#define CAL_HL_SYSCONFIG               0x0010
+#define CAL_HL_IRQ_EOI                 0x001c
+#define CAL_HL_IRQSTATUS_RAW(m)                (0x20U + ((m-1) * 0x10U))
+#define CAL_HL_IRQSTATUS(m)            (0x24U + ((m-1) * 0x10U))
+#define CAL_HL_IRQENABLE_SET(m)                (0x28U + ((m-1) * 0x10U))
+#define CAL_HL_IRQENABLE_CLR(m)                (0x2cU + ((m-1) * 0x10U))
+#define CAL_PIX_PROC(m)                        (0xc0U + ((m-1) * 0x4U))
+#define CAL_CTRL                       0x100
+#define CAL_CTRL1                      0x104
+#define CAL_LINE_NUMBER_EVT            0x108
+#define CAL_VPORT_CTRL1                        0x120
+#define CAL_VPORT_CTRL2                        0x124
+#define CAL_BYS_CTRL1                  0x130
+#define CAL_BYS_CTRL2                  0x134
+#define CAL_RD_DMA_CTRL                        0x140
+#define CAL_RD_DMA_PIX_ADDR            0x144
+#define CAL_RD_DMA_PIX_OFST            0x148
+#define CAL_RD_DMA_XSIZE               0x14c
+#define CAL_RD_DMA_YSIZE               0x150
+#define CAL_RD_DMA_INIT_ADDR           0x154
+#define CAL_RD_DMA_INIT_OFST           0x168
+#define CAL_RD_DMA_CTRL2               0x16c
+#define CAL_WR_DMA_CTRL(m)             (0x200U + ((m-1) * 0x10U))
+#define CAL_WR_DMA_ADDR(m)             (0x204U + ((m-1) * 0x10U))
+#define CAL_WR_DMA_OFST(m)             (0x208U + ((m-1) * 0x10U))
+#define CAL_WR_DMA_XSIZE(m)            (0x20cU + ((m-1) * 0x10U))
+#define CAL_CSI2_PPI_CTRL(m)           (0x300U + ((m-1) * 0x80U))
+#define CAL_CSI2_COMPLEXIO_CFG(m)      (0x304U + ((m-1) * 0x80U))
+#define CAL_CSI2_COMPLEXIO_IRQSTATUS(m)        (0x308U + ((m-1) * 0x80U))
+#define CAL_CSI2_SHORT_PACKET(m)       (0x30cU + ((m-1) * 0x80U))
+#define CAL_CSI2_COMPLEXIO_IRQENABLE(m)        (0x310U + ((m-1) * 0x80U))
+#define CAL_CSI2_TIMING(m)             (0x314U + ((m-1) * 0x80U))
+#define CAL_CSI2_VC_IRQENABLE(m)       (0x318U + ((m-1) * 0x80U))
+#define CAL_CSI2_VC_IRQSTATUS(m)       (0x328U + ((m-1) * 0x80U))
+#define CAL_CSI2_CTX0(m)               (0x330U + ((m-1) * 0x80U))
+#define CAL_CSI2_CTX1(m)               (0x334U + ((m-1) * 0x80U))
+#define CAL_CSI2_CTX2(m)               (0x338U + ((m-1) * 0x80U))
+#define CAL_CSI2_CTX3(m)               (0x33cU + ((m-1) * 0x80U))
+#define CAL_CSI2_CTX4(m)               (0x340U + ((m-1) * 0x80U))
+#define CAL_CSI2_CTX5(m)               (0x344U + ((m-1) * 0x80U))
+#define CAL_CSI2_CTX6(m)               (0x348U + ((m-1) * 0x80U))
+#define CAL_CSI2_CTX7(m)               (0x34cU + ((m-1) * 0x80U))
+#define CAL_CSI2_STATUS0(m)            (0x350U + ((m-1) * 0x80U))
+#define CAL_CSI2_STATUS1(m)            (0x354U + ((m-1) * 0x80U))
+#define CAL_CSI2_STATUS2(m)            (0x358U + ((m-1) * 0x80U))
+#define CAL_CSI2_STATUS3(m)            (0x35cU + ((m-1) * 0x80U))
+#define CAL_CSI2_STATUS4(m)            (0x360U + ((m-1) * 0x80U))
+#define CAL_CSI2_STATUS5(m)            (0x364U + ((m-1) * 0x80U))
+#define CAL_CSI2_STATUS6(m)            (0x368U + ((m-1) * 0x80U))
+#define CAL_CSI2_STATUS7(m)            (0x36cU + ((m-1) * 0x80U))
+
+/* CAL CSI2 PHY register offsets */
+#define CAL_CSI2_PHY_REG0              0x000
+#define CAL_CSI2_PHY_REG1              0x004
+#define CAL_CSI2_PHY_REG2              0x008
+
+/* CAL Control Module Core Camerrx Control register offsets */
+#define CM_CTRL_CORE_CAMERRX_CONTROL   0x000
+
+/*********************************************************************
+* Generic value used in various field below
+*********************************************************************/
+
+#define CAL_GEN_DISABLE                        0
+#define CAL_GEN_ENABLE                 1
+#define CAL_GEN_FALSE                  0
+#define CAL_GEN_TRUE                   1
+
+/*********************************************************************
+* Field Definition Macros
+*********************************************************************/
+
+#define CAL_HL_REVISION_MINOR_MASK             GENMASK(5, 0)
+#define CAL_HL_REVISION_CUSTOM_MASK            GENMASK(7, 6)
+#define CAL_HL_REVISION_MAJOR_MASK             GENMASK(10, 8)
+#define CAL_HL_REVISION_RTL_MASK               GENMASK(15, 11)
+#define CAL_HL_REVISION_FUNC_MASK              GENMASK(27, 16)
+#define CAL_HL_REVISION_SCHEME_MASK            GENMASK(31, 30)
+#define CAL_HL_REVISION_SCHEME_H08                     1
+#define CAL_HL_REVISION_SCHEME_LEGACY                  0
+
+#define CAL_HL_HWINFO_WFIFO_MASK               GENMASK(3, 0)
+#define CAL_HL_HWINFO_RFIFO_MASK               GENMASK(7, 4)
+#define CAL_HL_HWINFO_PCTX_MASK                        GENMASK(12, 8)
+#define CAL_HL_HWINFO_WCTX_MASK                        GENMASK(18, 13)
+#define CAL_HL_HWINFO_VFIFO_MASK               GENMASK(22, 19)
+#define CAL_HL_HWINFO_NCPORT_MASK              GENMASK(27, 23)
+#define CAL_HL_HWINFO_NPPI_CTXS0_MASK          GENMASK(29, 28)
+#define CAL_HL_HWINFO_NPPI_CTXS1_MASK          GENMASK(31, 30)
+#define CAL_HL_HWINFO_NPPI_CONTEXTS_ZERO               0
+#define CAL_HL_HWINFO_NPPI_CONTEXTS_FOUR               1
+#define CAL_HL_HWINFO_NPPI_CONTEXTS_EIGHT              2
+#define CAL_HL_HWINFO_NPPI_CONTEXTS_RESERVED           3
+
+#define CAL_HL_SYSCONFIG_SOFTRESET_MASK                BIT_MASK(0)
+#define CAL_HL_SYSCONFIG_SOFTRESET_DONE                        0x0
+#define CAL_HL_SYSCONFIG_SOFTRESET_PENDING             0x1
+#define CAL_HL_SYSCONFIG_SOFTRESET_NOACTION            0x0
+#define CAL_HL_SYSCONFIG_SOFTRESET_RESET               0x1
+#define CAL_HL_SYSCONFIG_IDLE_MASK             GENMASK(3, 2)
+#define CAL_HL_SYSCONFIG_IDLEMODE_FORCE                        0
+#define CAL_HL_SYSCONFIG_IDLEMODE_NO                   1
+#define CAL_HL_SYSCONFIG_IDLEMODE_SMART1               2
+#define CAL_HL_SYSCONFIG_IDLEMODE_SMART2               3
+
+#define CAL_HL_IRQ_EOI_LINE_NUMBER_MASK                BIT_MASK(0)
+#define CAL_HL_IRQ_EOI_LINE_NUMBER_READ0               0
+#define CAL_HL_IRQ_EOI_LINE_NUMBER_EOI0                        0
+
+#define CAL_HL_IRQ_MASK(m)                     BIT_MASK(m-1)
+#define CAL_HL_IRQ_NOACTION                            0x0
+#define CAL_HL_IRQ_ENABLE                              0x1
+#define CAL_HL_IRQ_CLEAR                               0x1
+#define CAL_HL_IRQ_DISABLED                            0x0
+#define CAL_HL_IRQ_ENABLED                             0x1
+#define CAL_HL_IRQ_PENDING                             0x1
+
+#define CAL_PIX_PROC_EN_MASK                   BIT_MASK(0)
+#define CAL_PIX_PROC_EXTRACT_MASK              GENMASK(4, 1)
+#define CAL_PIX_PROC_EXTRACT_B6                                0x0
+#define CAL_PIX_PROC_EXTRACT_B7                                0x1
+#define CAL_PIX_PROC_EXTRACT_B8                                0x2
+#define CAL_PIX_PROC_EXTRACT_B10                       0x3
+#define CAL_PIX_PROC_EXTRACT_B10_MIPI                  0x4
+#define CAL_PIX_PROC_EXTRACT_B12                       0x5
+#define CAL_PIX_PROC_EXTRACT_B12_MIPI                  0x6
+#define CAL_PIX_PROC_EXTRACT_B14                       0x7
+#define CAL_PIX_PROC_EXTRACT_B14_MIPI                  0x8
+#define CAL_PIX_PROC_EXTRACT_B16_BE                    0x9
+#define CAL_PIX_PROC_EXTRACT_B16_LE                    0xa
+#define CAL_PIX_PROC_DPCMD_MASK                        GENMASK(9, 5)
+#define CAL_PIX_PROC_DPCMD_BYPASS                      0x0
+#define CAL_PIX_PROC_DPCMD_DPCM_10_8_1                 0x2
+#define CAL_PIX_PROC_DPCMD_DPCM_12_8_1                 0x8
+#define CAL_PIX_PROC_DPCMD_DPCM_10_7_1                 0x4
+#define CAL_PIX_PROC_DPCMD_DPCM_10_7_2                 0x5
+#define CAL_PIX_PROC_DPCMD_DPCM_10_6_1                 0x6
+#define CAL_PIX_PROC_DPCMD_DPCM_10_6_2                 0x7
+#define CAL_PIX_PROC_DPCMD_DPCM_12_7_1                 0xa
+#define CAL_PIX_PROC_DPCMD_DPCM_12_6_1                 0xc
+#define CAL_PIX_PROC_DPCMD_DPCM_14_10                  0xe
+#define CAL_PIX_PROC_DPCMD_DPCM_14_8_1                 0x10
+#define CAL_PIX_PROC_DPCMD_DPCM_16_12_1                        0x12
+#define CAL_PIX_PROC_DPCMD_DPCM_16_10_1                        0x14
+#define CAL_PIX_PROC_DPCMD_DPCM_16_8_1                 0x16
+#define CAL_PIX_PROC_DPCME_MASK                        GENMASK(15, 11)
+#define CAL_PIX_PROC_DPCME_BYPASS                      0x0
+#define CAL_PIX_PROC_DPCME_DPCM_10_8_1                 0x2
+#define CAL_PIX_PROC_DPCME_DPCM_12_8_1                 0x8
+#define CAL_PIX_PROC_DPCME_DPCM_14_10                  0xe
+#define CAL_PIX_PROC_DPCME_DPCM_14_8_1                 0x10
+#define CAL_PIX_PROC_DPCME_DPCM_16_12_1                        0x12
+#define CAL_PIX_PROC_DPCME_DPCM_16_10_1                        0x14
+#define CAL_PIX_PROC_DPCME_DPCM_16_8_1                 0x16
+#define CAL_PIX_PROC_PACK_MASK                 GENMASK(18, 16)
+#define CAL_PIX_PROC_PACK_B8                           0x0
+#define CAL_PIX_PROC_PACK_B10_MIPI                     0x2
+#define CAL_PIX_PROC_PACK_B12                          0x3
+#define CAL_PIX_PROC_PACK_B12_MIPI                     0x4
+#define CAL_PIX_PROC_PACK_B16                          0x5
+#define CAL_PIX_PROC_PACK_ARGB                         0x6
+#define CAL_PIX_PROC_CPORT_MASK                        GENMASK(23, 19)
+
+#define CAL_CTRL_POSTED_WRITES_MASK            BIT_MASK(0)
+#define CAL_CTRL_POSTED_WRITES_NONPOSTED               0
+#define CAL_CTRL_POSTED_WRITES                         1
+#define CAL_CTRL_TAGCNT_MASK                   GENMASK(4, 1)
+#define CAL_CTRL_BURSTSIZE_MASK                        GENMASK(6, 5)
+#define CAL_CTRL_BURSTSIZE_BURST16                     0x0
+#define CAL_CTRL_BURSTSIZE_BURST32                     0x1
+#define CAL_CTRL_BURSTSIZE_BURST64                     0x2
+#define CAL_CTRL_BURSTSIZE_BURST128                    0x3
+#define CAL_CTRL_LL_FORCE_STATE_MASK           GENMASK(12, 7)
+#define CAL_CTRL_MFLAGL_MASK                   GENMASK(20, 13)
+#define CAL_CTRL_PWRSCPCLK_MASK                        BIT_MASK(21)
+#define CAL_CTRL_PWRSCPCLK_AUTO                                0
+#define CAL_CTRL_PWRSCPCLK_FORCE                       1
+#define CAL_CTRL_RD_DMA_STALL_MASK             BIT_MASK(22)
+#define CAL_CTRL_MFLAGH_MASK                   GENMASK(31, 24)
+
+#define CAL_CTRL1_PPI_GROUPING_MASK            GENMASK(1, 0)
+#define CAL_CTRL1_PPI_GROUPING_DISABLED                        0
+#define CAL_CTRL1_PPI_GROUPING_RESERVED                        1
+#define CAL_CTRL1_PPI_GROUPING_0                       2
+#define CAL_CTRL1_PPI_GROUPING_1                       3
+#define CAL_CTRL1_INTERLEAVE01_MASK            GENMASK(3, 2)
+#define CAL_CTRL1_INTERLEAVE01_DISABLED                        0
+#define CAL_CTRL1_INTERLEAVE01_PIX1                    1
+#define CAL_CTRL1_INTERLEAVE01_PIX4                    2
+#define CAL_CTRL1_INTERLEAVE01_RESERVED                        3
+#define CAL_CTRL1_INTERLEAVE23_MASK            GENMASK(5, 4)
+#define CAL_CTRL1_INTERLEAVE23_DISABLED                        0
+#define CAL_CTRL1_INTERLEAVE23_PIX1                    1
+#define CAL_CTRL1_INTERLEAVE23_PIX4                    2
+#define CAL_CTRL1_INTERLEAVE23_RESERVED                        3
+
+#define CAL_LINE_NUMBER_EVT_CPORT_MASK         GENMASK(4, 0)
+#define CAL_LINE_NUMBER_EVT_MASK               GENMASK(29, 16)
+
+#define CAL_VPORT_CTRL1_PCLK_MASK              GENMASK(16, 0)
+#define CAL_VPORT_CTRL1_XBLK_MASK              GENMASK(24, 17)
+#define CAL_VPORT_CTRL1_YBLK_MASK              GENMASK(30, 25)
+#define CAL_VPORT_CTRL1_WIDTH_MASK             BIT_MASK(31)
+#define CAL_VPORT_CTRL1_WIDTH_ONE                      0
+#define CAL_VPORT_CTRL1_WIDTH_TWO                      1
+
+#define CAL_VPORT_CTRL2_CPORT_MASK             GENMASK(4, 0)
+#define CAL_VPORT_CTRL2_FREERUNNING_MASK       BIT_MASK(15)
+#define CAL_VPORT_CTRL2_FREERUNNING_GATED              0
+#define CAL_VPORT_CTRL2_FREERUNNING_FREE               1
+#define CAL_VPORT_CTRL2_FS_RESETS_MASK         BIT_MASK(16)
+#define CAL_VPORT_CTRL2_FS_RESETS_NO                   0
+#define CAL_VPORT_CTRL2_FS_RESETS_YES                  1
+#define CAL_VPORT_CTRL2_FSM_RESET_MASK         BIT_MASK(17)
+#define CAL_VPORT_CTRL2_FSM_RESET_NOEFFECT             0
+#define CAL_VPORT_CTRL2_FSM_RESET                      1
+#define CAL_VPORT_CTRL2_RDY_THR_MASK           GENMASK(31, 18)
+
+#define CAL_BYS_CTRL1_PCLK_MASK                        GENMASK(16, 0)
+#define CAL_BYS_CTRL1_XBLK_MASK                        GENMASK(24, 17)
+#define CAL_BYS_CTRL1_YBLK_MASK                        GENMASK(30, 25)
+#define CAL_BYS_CTRL1_BYSINEN_MASK             BIT_MASK(31)
+
+#define CAL_BYS_CTRL2_CPORTIN_MASK             GENMASK(4, 0)
+#define CAL_BYS_CTRL2_CPORTOUT_MASK            GENMASK(9, 5)
+#define CAL_BYS_CTRL2_DUPLICATEDDATA_MASK      BIT_MASK(10)
+#define CAL_BYS_CTRL2_DUPLICATEDDATA_NO                        0
+#define CAL_BYS_CTRL2_DUPLICATEDDATA_YES               1
+#define CAL_BYS_CTRL2_FREERUNNING_MASK         BIT_MASK(11)
+#define CAL_BYS_CTRL2_FREERUNNING_NO                   0
+#define CAL_BYS_CTRL2_FREERUNNING_YES                  1
+
+#define CAL_RD_DMA_CTRL_GO_MASK                        BIT_MASK(0)
+#define CAL_RD_DMA_CTRL_GO_DIS                         0
+#define CAL_RD_DMA_CTRL_GO_EN                          1
+#define CAL_RD_DMA_CTRL_GO_IDLE                                0
+#define CAL_RD_DMA_CTRL_GO_BUSY                                1
+#define CAL_RD_DMA_CTRL_INIT_MASK              BIT_MASK(1)
+#define CAL_RD_DMA_CTRL_BW_LIMITER_MASK                GENMASK(10, 2)
+#define CAL_RD_DMA_CTRL_OCP_TAG_CNT_MASK       GENMASK(14, 11)
+#define CAL_RD_DMA_CTRL_PCLK_MASK              GENMASK(31, 15)
+
+#define CAL_RD_DMA_PIX_ADDR_MASK               GENMASK(31, 3)
+
+#define CAL_RD_DMA_PIX_OFST_MASK               GENMASK(31, 4)
+
+#define CAL_RD_DMA_XSIZE_MASK                  GENMASK(31, 19)
+
+#define CAL_RD_DMA_YSIZE_MASK                  GENMASK(29, 16)
+
+#define CAL_RD_DMA_INIT_ADDR_MASK              GENMASK(31, 3)
+
+#define CAL_RD_DMA_INIT_OFST_MASK              GENMASK(31, 3)
+
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_MASK                GENMASK(2, 0)
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_DIS                 0
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_ONE                 1
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_FOUR                        2
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_SIXTEEN             3
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_SIXTYFOUR           4
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_RESERVED            5
+#define CAL_RD_DMA_CTRL2_ICM_CSTART_MASK       BIT_MASK(3)
+#define CAL_RD_DMA_CTRL2_PATTERN_MASK          GENMASK(5, 4)
+#define CAL_RD_DMA_CTRL2_PATTERN_LINEAR                        0
+#define CAL_RD_DMA_CTRL2_PATTERN_YUV420                        1
+#define CAL_RD_DMA_CTRL2_PATTERN_RD2SKIP2              2
+#define CAL_RD_DMA_CTRL2_PATTERN_RD2SKIP4              3
+#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_MASK   BIT_MASK(6)
+#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_FREERUNNING    0
+#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_WAITFORBYSOUT  1
+#define CAL_RD_DMA_CTRL2_CIRC_SIZE_MASK                GENMASK(29, 16)
+
+#define CAL_WR_DMA_CTRL_MODE_MASK              GENMASK(2, 0)
+#define CAL_WR_DMA_CTRL_MODE_DIS                       0
+#define CAL_WR_DMA_CTRL_MODE_SHD                       1
+#define CAL_WR_DMA_CTRL_MODE_CNT                       2
+#define CAL_WR_DMA_CTRL_MODE_CNT_INIT                  3
+#define CAL_WR_DMA_CTRL_MODE_CONST                     4
+#define CAL_WR_DMA_CTRL_MODE_RESERVED                  5
+#define CAL_WR_DMA_CTRL_PATTERN_MASK           GENMASK(4, 3)
+#define CAL_WR_DMA_CTRL_PATTERN_LINEAR                 0
+#define CAL_WR_DMA_CTRL_PATTERN_WR2SKIP2               2
+#define CAL_WR_DMA_CTRL_PATTERN_WR2SKIP4               3
+#define CAL_WR_DMA_CTRL_PATTERN_RESERVED               1
+#define CAL_WR_DMA_CTRL_ICM_PSTART_MASK                BIT_MASK(5)
+#define CAL_WR_DMA_CTRL_DTAG_MASK              GENMASK(8, 6)
+#define CAL_WR_DMA_CTRL_DTAG_ATT_HDR                   0
+#define CAL_WR_DMA_CTRL_DTAG_ATT_DAT                   1
+#define CAL_WR_DMA_CTRL_DTAG                           2
+#define CAL_WR_DMA_CTRL_DTAG_PIX_HDR                   3
+#define CAL_WR_DMA_CTRL_DTAG_PIX_DAT                   4
+#define CAL_WR_DMA_CTRL_DTAG_D5                                5
+#define CAL_WR_DMA_CTRL_DTAG_D6                                6
+#define CAL_WR_DMA_CTRL_DTAG_D7                                7
+#define CAL_WR_DMA_CTRL_CPORT_MASK             GENMASK(13, 9)
+#define CAL_WR_DMA_CTRL_STALL_RD_MASK          BIT_MASK(14)
+#define CAL_WR_DMA_CTRL_YSIZE_MASK             GENMASK(31, 18)
+
+#define CAL_WR_DMA_ADDR_MASK                   GENMASK(31, 4)
+
+#define CAL_WR_DMA_OFST_MASK                   GENMASK(18, 4)
+#define CAL_WR_DMA_OFST_CIRC_MODE_MASK         GENMASK(23, 22)
+#define CAL_WR_DMA_OFST_CIRC_MODE_ONE                  1
+#define CAL_WR_DMA_OFST_CIRC_MODE_FOUR                 2
+#define CAL_WR_DMA_OFST_CIRC_MODE_SIXTYFOUR            3
+#define CAL_WR_DMA_OFST_CIRC_MODE_DISABLED             0
+#define CAL_WR_DMA_OFST_CIRC_SIZE_MASK         GENMASK(31, 24)
+
+#define CAL_WR_DMA_XSIZE_XSKIP_MASK            GENMASK(15, 3)
+#define CAL_WR_DMA_XSIZE_MASK                  GENMASK(31, 19)
+
+#define CAL_CSI2_PPI_CTRL_IF_EN_MASK           BIT_MASK(0)
+#define CAL_CSI2_PPI_CTRL_ECC_EN_MASK          BIT_MASK(2)
+#define CAL_CSI2_PPI_CTRL_FRAME_MASK           BIT_MASK(3)
+#define CAL_CSI2_PPI_CTRL_FRAME_IMMEDIATE              0
+#define CAL_CSI2_PPI_CTRL_FRAME                                1
+
+#define CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK     GENMASK(2, 0)
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_5                      5
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_4                      4
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_3                      3
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_2                      2
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_1                      1
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_NOT_USED               0
+#define CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK          BIT_MASK(3)
+#define CAL_CSI2_COMPLEXIO_CFG_POL_PLUSMINUS                   0
+#define CAL_CSI2_COMPLEXIO_CFG_POL_MINUSPLUS                   1
+#define CAL_CSI2_COMPLEXIO_CFG_DATA1_POSITION_MASK     GENMASK(6, 4)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA1_POL_MASK          BIT_MASK(7)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA2_POSITION_MASK     GENMASK(10, 8)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA2_POL_MASK          BIT_MASK(11)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA3_POSITION_MASK     GENMASK(14, 12)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA3_POL_MASK          BIT_MASK(15)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA4_POSITION_MASK     GENMASK(18, 16)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA4_POL_MASK          BIT_MASK(19)
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_AUTO_MASK           BIT_MASK(24)
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK         GENMASK(26, 25)
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_OFF            0
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_ON             1
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_ULP            2
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK            GENMASK(28, 27)
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF               0
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON                        1
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ULP               2
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK         BIT_MASK(29)
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED       1
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETONGOING         0
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK         BIT_MASK(30)
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL                      0
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL          1
+
+#define CAL_CSI2_SHORT_PACKET_MASK     GENMASK(23, 0)
+
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS1_MASK          BIT_MASK(0)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS2_MASK          BIT_MASK(1)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS3_MASK          BIT_MASK(2)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS4_MASK          BIT_MASK(3)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS5_MASK          BIT_MASK(4)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS1_MASK      BIT_MASK(5)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS2_MASK      BIT_MASK(6)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS3_MASK      BIT_MASK(7)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS4_MASK      BIT_MASK(8)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS5_MASK      BIT_MASK(9)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC1_MASK            BIT_MASK(10)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC2_MASK            BIT_MASK(11)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC3_MASK            BIT_MASK(12)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC4_MASK            BIT_MASK(13)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC5_MASK            BIT_MASK(14)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL1_MASK                BIT_MASK(15)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL2_MASK                BIT_MASK(16)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL3_MASK                BIT_MASK(17)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL4_MASK                BIT_MASK(18)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL5_MASK                BIT_MASK(19)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM1_MASK         BIT_MASK(20)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM2_MASK         BIT_MASK(21)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM3_MASK         BIT_MASK(22)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM4_MASK         BIT_MASK(23)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM5_MASK         BIT_MASK(24)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEALLULPMENTER_MASK  BIT_MASK(25)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEALLULPMEXIT_MASK   BIT_MASK(26)
+#define CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK           BIT_MASK(27)
+#define CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK       BIT_MASK(28)
+#define CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK  BIT_MASK(30)
+
+#define CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK    GENMASK(12, 0)
+#define CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK         BIT_MASK(13)
+#define CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK                BIT_MASK(14)
+#define CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK         BIT_MASK(15)
+
+#define CAL_CSI2_VC_IRQ_FS_IRQ_0_MASK                  BIT_MASK(0)
+#define CAL_CSI2_VC_IRQ_FE_IRQ_0_MASK                  BIT_MASK(1)
+#define CAL_CSI2_VC_IRQ_LS_IRQ_0_MASK                  BIT_MASK(2)
+#define CAL_CSI2_VC_IRQ_LE_IRQ_0_MASK                  BIT_MASK(3)
+#define CAL_CSI2_VC_IRQ_CS_IRQ_0_MASK                  BIT_MASK(4)
+#define CAL_CSI2_VC_IRQ_ECC_CORRECTION0_IRQ_0_MASK     BIT_MASK(5)
+#define CAL_CSI2_VC_IRQ_FS_IRQ_1_MASK                  BIT_MASK(8)
+#define CAL_CSI2_VC_IRQ_FE_IRQ_1_MASK                  BIT_MASK(9)
+#define CAL_CSI2_VC_IRQ_LS_IRQ_1_MASK                  BIT_MASK(10)
+#define CAL_CSI2_VC_IRQ_LE_IRQ_1_MASK                  BIT_MASK(11)
+#define CAL_CSI2_VC_IRQ_CS_IRQ_1_MASK                  BIT_MASK(12)
+#define CAL_CSI2_VC_IRQ_ECC_CORRECTION0_IRQ_1_MASK     BIT_MASK(13)
+#define CAL_CSI2_VC_IRQ_FS_IRQ_2_MASK                  BIT_MASK(16)
+#define CAL_CSI2_VC_IRQ_FE_IRQ_2_MASK                  BIT_MASK(17)
+#define CAL_CSI2_VC_IRQ_LS_IRQ_2_MASK                  BIT_MASK(18)
+#define CAL_CSI2_VC_IRQ_LE_IRQ_2_MASK                  BIT_MASK(19)
+#define CAL_CSI2_VC_IRQ_CS_IRQ_2_MASK                  BIT_MASK(20)
+#define CAL_CSI2_VC_IRQ_ECC_CORRECTION0_IRQ_2_MASK     BIT_MASK(21)
+#define CAL_CSI2_VC_IRQ_FS_IRQ_3_MASK                  BIT_MASK(24)
+#define CAL_CSI2_VC_IRQ_FE_IRQ_3_MASK                  BIT_MASK(25)
+#define CAL_CSI2_VC_IRQ_LS_IRQ_3_MASK                  BIT_MASK(26)
+#define CAL_CSI2_VC_IRQ_LE_IRQ_3_MASK                  BIT_MASK(27)
+#define CAL_CSI2_VC_IRQ_CS_IRQ_3_MASK                  BIT_MASK(28)
+#define CAL_CSI2_VC_IRQ_ECC_CORRECTION0_IRQ_3_MASK     BIT_MASK(29)
+
+#define CAL_CSI2_CTX_DT_MASK           GENMASK(5, 0)
+#define CAL_CSI2_CTX_VC_MASK           GENMASK(7, 6)
+#define CAL_CSI2_CTX_CPORT_MASK                GENMASK(12, 8)
+#define CAL_CSI2_CTX_ATT_MASK          BIT_MASK(13)
+#define CAL_CSI2_CTX_ATT_PIX                   0
+#define CAL_CSI2_CTX_ATT                       1
+#define CAL_CSI2_CTX_PACK_MODE_MASK    BIT_MASK(14)
+#define CAL_CSI2_CTX_PACK_MODE_LINE            0
+#define CAL_CSI2_CTX_PACK_MODE_FRAME           1
+#define CAL_CSI2_CTX_LINES_MASK                GENMASK(29, 16)
+
+#define CAL_CSI2_STATUS_FRAME_MASK     GENMASK(15, 0)
+
+#define CAL_CSI2_PHY_REG0_THS_SETTLE_MASK      GENMASK(7, 0)
+#define CAL_CSI2_PHY_REG0_THS_TERM_MASK                GENMASK(15, 8)
+#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_MASK   BIT_MASK(24)
+#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE                1
+#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_ENABLE         0
+
+#define CAL_CSI2_PHY_REG1_TCLK_SETTLE_MASK                     GENMASK(7, 0)
+#define CAL_CSI2_PHY_REG1_CTRLCLK_DIV_FACTOR_MASK              GENMASK(9, 8)
+#define CAL_CSI2_PHY_REG1_DPHY_HS_SYNC_PATTERN_MASK            GENMASK(17, 10)
+#define CAL_CSI2_PHY_REG1_TCLK_TERM_MASK                       GENMASK(24, 18)
+#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_MASK      BIT_MASK(25)
+#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_ERROR             1
+#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_SUCCESS           0
+#define CAL_CSI2_PHY_REG1_RESET_DONE_STATUS_MASK               GENMASK(29, 28)
+
+#define CAL_CSI2_PHY_REG2_CCP2_SYNC_PATTERN_MASK               GENMASK(23, 0)
+#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC3_MASK          GENMASK(25, 24)
+#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC2_MASK          GENMASK(27, 26)
+#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC1_MASK          GENMASK(29, 28)
+#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC0_MASK          GENMASK(31, 30)
+
+#define CM_CAMERRX_CTRL_CSI1_CTRLCLKEN_MASK                    BIT_MASK(0)
+#define CM_CAMERRX_CTRL_CSI1_CAMMODE_MASK                      GENMASK(2, 1)
+#define CM_CAMERRX_CTRL_CSI1_LANEENABLE_MASK                   GENMASK(4, 3)
+#define CM_CAMERRX_CTRL_CSI1_MODE_MASK                         BIT_MASK(5)
+#define CM_CAMERRX_CTRL_CSI0_CTRLCLKEN_MASK                    BIT_MASK(10)
+#define CM_CAMERRX_CTRL_CSI0_CAMMODE_MASK                      GENMASK(12, 11)
+#define CM_CAMERRX_CTRL_CSI0_LANEENABLE_MASK                   GENMASK(16, 13)
+#define CM_CAMERRX_CTRL_CSI0_MODE_MASK                         BIT_MASK(17)
+
+#endif
index 418113c998013d5fabc083364b662dc17d259e79..c4b5fab836663d2ea07f9c240327d52f80529e83 100644 (file)
@@ -1074,7 +1074,7 @@ static int __init vim2m_init(void)
        if (ret)
                platform_device_unregister(&vim2m_pdev);
 
-       return 0;
+       return ret;
 }
 
 module_init(vim2m_init);
index 9baed6a1033433e9ebd3f23eb35d7d65b7d2f2ca..93fbaee69675a3988033c2af1af9bd3613597d7f 100644 (file)
@@ -418,6 +418,8 @@ static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsi
 
                tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p];
        }
+       if (tpg_g_interleaved(tpg))
+               tpg->bytesperline[1] = tpg->bytesperline[0];
 }
 
 
index 859f0c08ee0543c67af2a4ecbf368906722fbba0..271f725b17e85c77017f08ac9181510369f16872 100644 (file)
@@ -1530,11 +1530,11 @@ static int si476x_radio_probe(struct platform_device *pdev)
        if (si476x_core_has_diversity(radio->core)) {
                si476x_ctrls[SI476X_IDX_DIVERSITY_MODE].def =
                        si476x_phase_diversity_mode_to_idx(radio->core->diversity_mode);
-               si476x_radio_add_new_custom(radio, SI476X_IDX_DIVERSITY_MODE);
+               rval = si476x_radio_add_new_custom(radio, SI476X_IDX_DIVERSITY_MODE);
                if (rval < 0)
                        goto exit;
 
-               si476x_radio_add_new_custom(radio, SI476X_IDX_INTERCHIP_LINK);
+               rval = si476x_radio_add_new_custom(radio, SI476X_IDX_INTERCHIP_LINK);
                if (rval < 0)
                        goto exit;
        }
index ebc73b03424960fe65f3db7721ffedb79a0e1d41..3f9e6df7d837ac27d060a1d7a5413de92273f57f 100644 (file)
@@ -68,7 +68,7 @@ MODULE_PARM_DESC(default_radio_region, "Region: 0=Europe/US, 1=Japan");
 /* RDS buffer blocks */
 static u32 default_rds_buf = 300;
 module_param(default_rds_buf, uint, 0444);
-MODULE_PARM_DESC(rds_buf, "RDS buffer entries");
+MODULE_PARM_DESC(default_rds_buf, "RDS buffer entries");
 
 /* Radio Nr */
 static u32 radio_nr = -1;
index 18adf580f502443bafc7c0e310d2556e5908f7dc..c96da3aaf00b56b0489644b835a466942727bfe9 100644 (file)
@@ -80,17 +80,24 @@ static inline void nvt_clear_reg_bit(struct nvt_dev *nvt, u8 val, u8 reg)
 }
 
 /* enter extended function mode */
-static inline void nvt_efm_enable(struct nvt_dev *nvt)
+static inline int nvt_efm_enable(struct nvt_dev *nvt)
 {
+       if (!request_muxed_region(nvt->cr_efir, 2, NVT_DRIVER_NAME))
+               return -EBUSY;
+
        /* Enabling Extended Function Mode explicitly requires writing 2x */
        outb(EFER_EFM_ENABLE, nvt->cr_efir);
        outb(EFER_EFM_ENABLE, nvt->cr_efir);
+
+       return 0;
 }
 
 /* exit extended function mode */
 static inline void nvt_efm_disable(struct nvt_dev *nvt)
 {
        outb(EFER_EFM_DISABLE, nvt->cr_efir);
+
+       release_region(nvt->cr_efir, 2);
 }
 
 /*
@@ -100,8 +107,25 @@ static inline void nvt_efm_disable(struct nvt_dev *nvt)
  */
 static inline void nvt_select_logical_dev(struct nvt_dev *nvt, u8 ldev)
 {
-       outb(CR_LOGICAL_DEV_SEL, nvt->cr_efir);
-       outb(ldev, nvt->cr_efdr);
+       nvt_cr_write(nvt, ldev, CR_LOGICAL_DEV_SEL);
+}
+
+/* select and enable logical device with setting EFM mode*/
+static inline void nvt_enable_logical_dev(struct nvt_dev *nvt, u8 ldev)
+{
+       nvt_efm_enable(nvt);
+       nvt_select_logical_dev(nvt, ldev);
+       nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN);
+       nvt_efm_disable(nvt);
+}
+
+/* select and disable logical device with setting EFM mode*/
+static inline void nvt_disable_logical_dev(struct nvt_dev *nvt, u8 ldev)
+{
+       nvt_efm_enable(nvt);
+       nvt_select_logical_dev(nvt, ldev);
+       nvt_cr_write(nvt, LOGICAL_DEV_DISABLE, CR_LOGICAL_DEV_EN);
+       nvt_efm_disable(nvt);
 }
 
 /* write val to cir config register */
@@ -137,6 +161,22 @@ static u8 nvt_cir_wake_reg_read(struct nvt_dev *nvt, u8 offset)
        return val;
 }
 
+/* don't override io address if one is set already */
+static void nvt_set_ioaddr(struct nvt_dev *nvt, unsigned long *ioaddr)
+{
+       unsigned long old_addr;
+
+       old_addr = nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8;
+       old_addr |= nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO);
+
+       if (old_addr)
+               *ioaddr = old_addr;
+       else {
+               nvt_cr_write(nvt, *ioaddr >> 8, CR_CIR_BASE_ADDR_HI);
+               nvt_cr_write(nvt, *ioaddr & 0xff, CR_CIR_BASE_ADDR_LO);
+       }
+}
+
 /* dump current cir register contents */
 static void cir_dump_regs(struct nvt_dev *nvt)
 {
@@ -251,7 +291,7 @@ static inline const char *nvt_find_chip(struct nvt_dev *nvt, int id)
 
 
 /* detect hardware features */
-static void nvt_hw_detect(struct nvt_dev *nvt)
+static int nvt_hw_detect(struct nvt_dev *nvt)
 {
        const char *chip_name;
        int chip_id;
@@ -266,10 +306,17 @@ static void nvt_hw_detect(struct nvt_dev *nvt)
                nvt_efm_enable(nvt);
                nvt->chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI);
        }
-
        nvt->chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO);
 
+       nvt_efm_disable(nvt);
+
        chip_id = nvt->chip_major << 8 | nvt->chip_minor;
+       if (chip_id == NVT_INVALID) {
+               dev_err(&nvt->pdev->dev,
+                       "No device found on either EFM port\n");
+               return -ENODEV;
+       }
+
        chip_name = nvt_find_chip(nvt, chip_id);
 
        /* warn, but still let the driver load, if we don't know this chip */
@@ -282,7 +329,7 @@ static void nvt_hw_detect(struct nvt_dev *nvt)
                         "found %s or compatible: chip id: 0x%02x 0x%02x",
                         chip_name, nvt->chip_major, nvt->chip_minor);
 
-       nvt_efm_disable(nvt);
+       return 0;
 }
 
 static void nvt_cir_ldev_init(struct nvt_dev *nvt)
@@ -305,12 +352,10 @@ static void nvt_cir_ldev_init(struct nvt_dev *nvt)
        val |= psval;
        nvt_cr_write(nvt, val, psreg);
 
-       /* Select CIR logical device and enable */
+       /* Select CIR logical device */
        nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
-       nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN);
 
-       nvt_cr_write(nvt, nvt->cir_addr >> 8, CR_CIR_BASE_ADDR_HI);
-       nvt_cr_write(nvt, nvt->cir_addr & 0xff, CR_CIR_BASE_ADDR_LO);
+       nvt_set_ioaddr(nvt, &nvt->cir_addr);
 
        nvt_cr_write(nvt, nvt->cir_irq, CR_CIR_IRQ_RSRC);
 
@@ -320,7 +365,7 @@ static void nvt_cir_ldev_init(struct nvt_dev *nvt)
 
 static void nvt_cir_wake_ldev_init(struct nvt_dev *nvt)
 {
-       /* Select ACPI logical device, enable it and CIR Wake */
+       /* Select ACPI logical device and anable it */
        nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI);
        nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN);
 
@@ -330,12 +375,10 @@ static void nvt_cir_wake_ldev_init(struct nvt_dev *nvt)
        /* enable pme interrupt of cir wakeup event */
        nvt_set_reg_bit(nvt, PME_INTR_CIR_PASS_BIT, CR_ACPI_IRQ_EVENTS2);
 
-       /* Select CIR Wake logical device and enable */
+       /* Select CIR Wake logical device */
        nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE);
-       nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN);
 
-       nvt_cr_write(nvt, nvt->cir_wake_addr >> 8, CR_CIR_BASE_ADDR_HI);
-       nvt_cr_write(nvt, nvt->cir_wake_addr & 0xff, CR_CIR_BASE_ADDR_LO);
+       nvt_set_ioaddr(nvt, &nvt->cir_wake_addr);
 
        nvt_cr_write(nvt, nvt->cir_wake_irq, CR_CIR_IRQ_RSRC);
 
@@ -355,11 +398,19 @@ static void nvt_clear_cir_fifo(struct nvt_dev *nvt)
 /* clear out the hardware's cir wake rx fifo */
 static void nvt_clear_cir_wake_fifo(struct nvt_dev *nvt)
 {
-       u8 val;
+       u8 val, config;
+
+       config = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON);
+
+       /* clearing wake fifo works in learning mode only */
+       nvt_cir_wake_reg_write(nvt, config & ~CIR_WAKE_IRCON_MODE0,
+                              CIR_WAKE_IRCON);
 
        val = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON);
        nvt_cir_wake_reg_write(nvt, val | CIR_WAKE_FIFOCON_RXFIFOCLR,
                               CIR_WAKE_FIFOCON);
+
+       nvt_cir_wake_reg_write(nvt, config, CIR_WAKE_IRCON);
 }
 
 /* clear out the hardware's cir tx fifo */
@@ -408,6 +459,9 @@ static void nvt_cir_regs_init(struct nvt_dev *nvt)
 
        /* and finally, enable interrupts */
        nvt_set_cir_iren(nvt);
+
+       /* enable the CIR logical device */
+       nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR);
 }
 
 static void nvt_cir_wake_regs_init(struct nvt_dev *nvt)
@@ -442,10 +496,15 @@ static void nvt_cir_wake_regs_init(struct nvt_dev *nvt)
 
        /* clear any and all stray interrupts */
        nvt_cir_wake_reg_write(nvt, 0xff, CIR_WAKE_IRSTS);
+
+       /* enable the CIR WAKE logical device */
+       nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE);
 }
 
 static void nvt_enable_wake(struct nvt_dev *nvt)
 {
+       unsigned long flags;
+
        nvt_efm_enable(nvt);
 
        nvt_select_logical_dev(nvt, LOGICAL_DEV_ACPI);
@@ -457,12 +516,16 @@ static void nvt_enable_wake(struct nvt_dev *nvt)
 
        nvt_efm_disable(nvt);
 
+       spin_lock_irqsave(&nvt->nvt_lock, flags);
+
        nvt_cir_wake_reg_write(nvt, CIR_WAKE_IRCON_MODE0 | CIR_WAKE_IRCON_RXEN |
                               CIR_WAKE_IRCON_R | CIR_WAKE_IRCON_RXINV |
                               CIR_WAKE_IRCON_SAMPLE_PERIOD_SEL,
                               CIR_WAKE_IRCON);
        nvt_cir_wake_reg_write(nvt, 0xff, CIR_WAKE_IRSTS);
        nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN);
+
+       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 }
 
 #if 0 /* Currently unused */
@@ -670,7 +733,6 @@ static void nvt_handle_rx_fifo_overrun(struct nvt_dev *nvt)
 /* copy data from hardware rx fifo into driver buffer */
 static void nvt_get_rx_ir_data(struct nvt_dev *nvt)
 {
-       unsigned long flags;
        u8 fifocount, val;
        unsigned int b_idx;
        bool overrun = false;
@@ -689,8 +751,6 @@ static void nvt_get_rx_ir_data(struct nvt_dev *nvt)
 
        nvt_dbg("attempting to fetch %u bytes from hw rx fifo", fifocount);
 
-       spin_lock_irqsave(&nvt->nvt_lock, flags);
-
        b_idx = nvt->pkts;
 
        /* This should never happen, but lets check anyway... */
@@ -712,8 +772,6 @@ static void nvt_get_rx_ir_data(struct nvt_dev *nvt)
 
        if (overrun)
                nvt_handle_rx_fifo_overrun(nvt);
-
-       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 }
 
 static void nvt_cir_log_irqs(u8 status, u8 iren)
@@ -736,16 +794,13 @@ static void nvt_cir_log_irqs(u8 status, u8 iren)
 static bool nvt_cir_tx_inactive(struct nvt_dev *nvt)
 {
        unsigned long flags;
-       bool tx_inactive;
        u8 tx_state;
 
        spin_lock_irqsave(&nvt->tx.lock, flags);
        tx_state = nvt->tx.tx_state;
        spin_unlock_irqrestore(&nvt->tx.lock, flags);
 
-       tx_inactive = (tx_state == ST_TX_NONE);
-
-       return tx_inactive;
+       return tx_state == ST_TX_NONE;
 }
 
 /* interrupt service routine for incoming and outgoing CIR data */
@@ -757,9 +812,7 @@ static irqreturn_t nvt_cir_isr(int irq, void *data)
 
        nvt_dbg_verbose("%s firing", __func__);
 
-       nvt_efm_enable(nvt);
-       nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
-       nvt_efm_disable(nvt);
+       spin_lock_irqsave(&nvt->nvt_lock, flags);
 
        /*
         * Get IR Status register contents. Write 1 to ack/clear
@@ -775,9 +828,14 @@ static irqreturn_t nvt_cir_isr(int irq, void *data)
         *   0: CIR_IRSTS_GH  - Min Length Detected
         */
        status = nvt_cir_reg_read(nvt, CIR_IRSTS);
-       if (!status) {
+       iren = nvt_cir_reg_read(nvt, CIR_IREN);
+
+       /* IRQ may be shared with CIR WAKE, therefore check for each
+        * status bit whether the related interrupt source is enabled
+        */
+       if (!(status & iren)) {
+               spin_unlock_irqrestore(&nvt->nvt_lock, flags);
                nvt_dbg_verbose("%s exiting, IRSTS 0x0", __func__);
-               nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS);
                return IRQ_NONE;
        }
 
@@ -785,13 +843,6 @@ static irqreturn_t nvt_cir_isr(int irq, void *data)
        nvt_cir_reg_write(nvt, status, CIR_IRSTS);
        nvt_cir_reg_write(nvt, 0, CIR_IRSTS);
 
-       /* Interrupt may be shared with CIR Wake, bail if CIR not enabled */
-       iren = nvt_cir_reg_read(nvt, CIR_IREN);
-       if (!iren) {
-               nvt_dbg_verbose("%s exiting, CIR not enabled", __func__);
-               return IRQ_NONE;
-       }
-
        nvt_cir_log_irqs(status, iren);
 
        if (status & CIR_IRSTS_RTR) {
@@ -805,16 +856,14 @@ static irqreturn_t nvt_cir_isr(int irq, void *data)
                if (nvt_cir_tx_inactive(nvt))
                        nvt_get_rx_ir_data(nvt);
 
-               spin_lock_irqsave(&nvt->nvt_lock, flags);
-
                cur_state = nvt->study_state;
 
-               spin_unlock_irqrestore(&nvt->nvt_lock, flags);
-
                if (cur_state == ST_STUDY_NONE)
                        nvt_clear_cir_fifo(nvt);
        }
 
+       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
+
        if (status & CIR_IRSTS_TE)
                nvt_clear_tx_fifo(nvt);
 
@@ -863,9 +912,18 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data)
 
        nvt_dbg_wake("%s firing", __func__);
 
+       spin_lock_irqsave(&nvt->nvt_lock, flags);
+
        status = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS);
-       if (!status)
+       iren = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN);
+
+       /* IRQ may be shared with CIR, therefore check for each
+        * status bit whether the related interrupt source is enabled
+        */
+       if (!(status & iren)) {
+               spin_unlock_irqrestore(&nvt->nvt_lock, flags);
                return IRQ_NONE;
+       }
 
        if (status & CIR_WAKE_IRSTS_IR_PENDING)
                nvt_clear_cir_wake_fifo(nvt);
@@ -873,13 +931,6 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data)
        nvt_cir_wake_reg_write(nvt, status, CIR_WAKE_IRSTS);
        nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IRSTS);
 
-       /* Interrupt may be shared with CIR, bail if Wake not enabled */
-       iren = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN);
-       if (!iren) {
-               nvt_dbg_wake("%s exiting, wake not enabled", __func__);
-               return IRQ_HANDLED;
-       }
-
        if ((status & CIR_WAKE_IRSTS_PE) &&
            (nvt->wake_state == ST_WAKE_START)) {
                while (nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)) {
@@ -888,39 +939,21 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data)
                }
 
                nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN);
-               spin_lock_irqsave(&nvt->nvt_lock, flags);
                nvt->wake_state = ST_WAKE_FINISH;
-               spin_unlock_irqrestore(&nvt->nvt_lock, flags);
        }
 
+       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
+
        nvt_dbg_wake("%s done", __func__);
        return IRQ_HANDLED;
 }
 
-static void nvt_enable_cir(struct nvt_dev *nvt)
+static void nvt_disable_cir(struct nvt_dev *nvt)
 {
-       /* set function enable flags */
-       nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN |
-                         CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL,
-                         CIR_IRCON);
-
-       nvt_efm_enable(nvt);
-
-       /* enable the CIR logical device */
-       nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
-       nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN);
-
-       nvt_efm_disable(nvt);
-
-       /* clear all pending interrupts */
-       nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS);
+       unsigned long flags;
 
-       /* enable interrupts */
-       nvt_set_cir_iren(nvt);
-}
+       spin_lock_irqsave(&nvt->nvt_lock, flags);
 
-static void nvt_disable_cir(struct nvt_dev *nvt)
-{
        /* disable CIR interrupts */
        nvt_cir_reg_write(nvt, 0, CIR_IREN);
 
@@ -934,13 +967,10 @@ static void nvt_disable_cir(struct nvt_dev *nvt)
        nvt_clear_cir_fifo(nvt);
        nvt_clear_tx_fifo(nvt);
 
-       nvt_efm_enable(nvt);
+       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 
        /* disable the CIR logical device */
-       nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
-       nvt_cr_write(nvt, LOGICAL_DEV_DISABLE, CR_LOGICAL_DEV_EN);
-
-       nvt_efm_disable(nvt);
+       nvt_disable_logical_dev(nvt, LOGICAL_DEV_CIR);
 }
 
 static int nvt_open(struct rc_dev *dev)
@@ -949,20 +979,31 @@ static int nvt_open(struct rc_dev *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&nvt->nvt_lock, flags);
-       nvt_enable_cir(nvt);
+
+       /* set function enable flags */
+       nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN |
+                         CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL,
+                         CIR_IRCON);
+
+       /* clear all pending interrupts */
+       nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS);
+
+       /* enable interrupts */
+       nvt_set_cir_iren(nvt);
+
        spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 
+       /* enable the CIR logical device */
+       nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR);
+
        return 0;
 }
 
 static void nvt_close(struct rc_dev *dev)
 {
        struct nvt_dev *nvt = dev->priv;
-       unsigned long flags;
 
-       spin_lock_irqsave(&nvt->nvt_lock, flags);
        nvt_disable_cir(nvt);
-       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 }
 
 /* Allocate memory, probe hardware, and initialize everything */
@@ -1024,7 +1065,9 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
 
        init_waitqueue_head(&nvt->tx.queue);
 
-       nvt_hw_detect(nvt);
+       ret = nvt_hw_detect(nvt);
+       if (ret)
+               goto exit_free_dev_rdev;
 
        /* Initialize CIR & CIR Wake Logical Devices */
        nvt_efm_enable(nvt);
@@ -1032,7 +1075,10 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
        nvt_cir_wake_ldev_init(nvt);
        nvt_efm_disable(nvt);
 
-       /* Initialize CIR & CIR Wake Config Registers */
+       /*
+        * Initialize CIR & CIR Wake Config Registers
+        * and enable logical devices
+        */
        nvt_cir_regs_init(nvt);
        nvt_cir_wake_regs_init(nvt);
 
@@ -1079,12 +1125,12 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
                goto exit_unregister_device;
 
        if (!devm_request_region(&pdev->dev, nvt->cir_wake_addr,
-                           CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
+                           CIR_IOREG_LENGTH, NVT_DRIVER_NAME "-wake"))
                goto exit_unregister_device;
 
        if (devm_request_irq(&pdev->dev, nvt->cir_wake_irq,
                             nvt_cir_wake_isr, IRQF_SHARED,
-                            NVT_DRIVER_NAME, (void *)nvt))
+                            NVT_DRIVER_NAME "-wake", (void *)nvt))
                goto exit_unregister_device;
 
        device_init_wakeup(&pdev->dev, true);
@@ -1109,15 +1155,11 @@ exit_free_dev_rdev:
 static void nvt_remove(struct pnp_dev *pdev)
 {
        struct nvt_dev *nvt = pnp_get_drvdata(pdev);
-       unsigned long flags;
 
-       spin_lock_irqsave(&nvt->nvt_lock, flags);
-       /* disable CIR */
-       nvt_cir_reg_write(nvt, 0, CIR_IREN);
        nvt_disable_cir(nvt);
+
        /* enable CIR Wake (for IR power-on) */
        nvt_enable_wake(nvt);
-       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 
        rc_unregister_device(nvt->rdev);
 }
@@ -1129,26 +1171,23 @@ static int nvt_suspend(struct pnp_dev *pdev, pm_message_t state)
 
        nvt_dbg("%s called", __func__);
 
-       /* zero out misc state tracking */
-       spin_lock_irqsave(&nvt->nvt_lock, flags);
-       nvt->study_state = ST_STUDY_NONE;
-       nvt->wake_state = ST_WAKE_NONE;
-       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
-
        spin_lock_irqsave(&nvt->tx.lock, flags);
        nvt->tx.tx_state = ST_TX_NONE;
        spin_unlock_irqrestore(&nvt->tx.lock, flags);
 
+       spin_lock_irqsave(&nvt->nvt_lock, flags);
+
+       /* zero out misc state tracking */
+       nvt->study_state = ST_STUDY_NONE;
+       nvt->wake_state = ST_WAKE_NONE;
+
        /* disable all CIR interrupts */
        nvt_cir_reg_write(nvt, 0, CIR_IREN);
 
-       nvt_efm_enable(nvt);
+       spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 
        /* disable cir logical dev */
-       nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
-       nvt_cr_write(nvt, LOGICAL_DEV_DISABLE, CR_LOGICAL_DEV_EN);
-
-       nvt_efm_disable(nvt);
+       nvt_disable_logical_dev(nvt, LOGICAL_DEV_CIR);
 
        /* make sure wake is enabled */
        nvt_enable_wake(nvt);
@@ -1162,16 +1201,6 @@ static int nvt_resume(struct pnp_dev *pdev)
 
        nvt_dbg("%s called", __func__);
 
-       /* open interrupt */
-       nvt_set_cir_iren(nvt);
-
-       /* Enable CIR logical device */
-       nvt_efm_enable(nvt);
-       nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
-       nvt_cr_write(nvt, LOGICAL_DEV_ENABLE, CR_LOGICAL_DEV_EN);
-
-       nvt_efm_disable(nvt);
-
        nvt_cir_regs_init(nvt);
        nvt_cir_wake_regs_init(nvt);
 
@@ -1181,6 +1210,7 @@ static int nvt_resume(struct pnp_dev *pdev)
 static void nvt_shutdown(struct pnp_dev *pdev)
 {
        struct nvt_dev *nvt = pnp_get_drvdata(pdev);
+
        nvt_enable_wake(nvt);
 }
 
index 0ad15d34e9c93ce8adedd5f114f84543776f3055..4a5650dffa29a67fad87022659c71b3e2c601910 100644 (file)
@@ -68,7 +68,8 @@ enum nvt_chip_ver {
        NVT_W83667HG    = 0xa510,
        NVT_6775F       = 0xb470,
        NVT_6776F       = 0xc330,
-       NVT_6779D       = 0xc560
+       NVT_6779D       = 0xc560,
+       NVT_INVALID     = 0xffff,
 };
 
 struct nvt_chip {
@@ -157,8 +158,8 @@ struct nvt_dev {
 /* total length of CIR and CIR WAKE */
 #define CIR_IOREG_LENGTH       0x0f
 
-/* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL (0x7d0 = 2000) */
-#define CIR_RX_LIMIT_COUNT     0x7d0
+/* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL */
+#define CIR_RX_LIMIT_COUNT  (IR_DEFAULT_TIMEOUT / US_TO_NS(SAMPLE_PERIOD))
 
 /* CIR Regs */
 #define CIR_IRCON      0x00
@@ -292,10 +293,7 @@ struct nvt_dev {
 #define CIR_WAKE_IREN_RTR              0x40
 #define CIR_WAKE_IREN_PE               0x20
 #define CIR_WAKE_IREN_RFO              0x10
-#define CIR_WAKE_IREN_TE               0x08
-#define CIR_WAKE_IREN_TTR              0x04
-#define CIR_WAKE_IREN_TFU              0x02
-#define CIR_WAKE_IREN_GH               0x01
+#define CIR_WAKE_IREN_GH               0x08
 
 /* CIR WAKE FIFOCON settings */
 #define CIR_WAKE_FIFOCON_RXFIFOCLR     0x08
index 7359f3d03b647244baeb8c99ad7076e9a11ba74d..585d5e52118d538f7fc764d2793bd98384c72b44 100644 (file)
@@ -16,6 +16,9 @@
 #ifndef _RC_CORE_PRIV
 #define _RC_CORE_PRIV
 
+/* Define the max number of pulse/space transitions to buffer */
+#define        MAX_IR_EVENT_SIZE       512
+
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <media/rc-core.h>
@@ -35,7 +38,8 @@ struct ir_raw_event_ctrl {
        struct list_head                list;           /* to keep track of raw clients */
        struct task_struct              *thread;
        spinlock_t                      lock;
-       struct kfifo_rec_ptr_1          kfifo;          /* fifo for the pulse/space durations */
+       /* fifo for the pulse/space durations */
+       DECLARE_KFIFO(kfifo, struct ir_raw_event, MAX_IR_EVENT_SIZE);
        ktime_t                         last_event;     /* when last event occurred */
        enum raw_event_type             last_type;      /* last event type */
        struct rc_dev                   *dev;           /* pointer to the parent rc_dev */
index c69807fe2feff08c47441dc2bf3c780c4440d505..144304c94606169773566ef4f3132f0dc188d4ce 100644 (file)
@@ -20,9 +20,6 @@
 #include <linux/freezer.h>
 #include "rc-core-priv.h"
 
-/* Define the max number of pulse/space transitions to buffer */
-#define MAX_IR_EVENT_SIZE      512
-
 /* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */
 static LIST_HEAD(ir_raw_client_list);
 
@@ -36,14 +33,12 @@ static int ir_raw_event_thread(void *data)
        struct ir_raw_event ev;
        struct ir_raw_handler *handler;
        struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
-       int retval;
 
        while (!kthread_should_stop()) {
 
                spin_lock_irq(&raw->lock);
-               retval = kfifo_len(&raw->kfifo);
 
-               if (retval < sizeof(ev)) {
+               if (!kfifo_len(&raw->kfifo)) {
                        set_current_state(TASK_INTERRUPTIBLE);
 
                        if (kthread_should_stop())
@@ -54,7 +49,8 @@ static int ir_raw_event_thread(void *data)
                        continue;
                }
 
-               retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev));
+               if(!kfifo_out(&raw->kfifo, &ev, 1))
+                       dev_err(&raw->dev->dev, "IR event FIFO is empty!\n");
                spin_unlock_irq(&raw->lock);
 
                mutex_lock(&ir_raw_handler_lock);
@@ -87,8 +83,10 @@ int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev)
        IR_dprintk(2, "sample: (%05dus %s)\n",
                   TO_US(ev->duration), TO_STR(ev->pulse));
 
-       if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
-               return -ENOMEM;
+       if (!kfifo_put(&dev->raw->kfifo, *ev)) {
+               dev_err(&dev->dev, "IR event FIFO is full!\n");
+               return -ENOSPC;
+       }
 
        return 0;
 }
@@ -273,11 +271,7 @@ int ir_raw_event_register(struct rc_dev *dev)
 
        dev->raw->dev = dev;
        dev->change_protocol = change_protocol;
-       rc = kfifo_alloc(&dev->raw->kfifo,
-                        sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
-                        GFP_KERNEL);
-       if (rc < 0)
-               goto out;
+       INIT_KFIFO(dev->raw->kfifo);
 
        spin_lock_init(&dev->raw->lock);
        dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
@@ -319,7 +313,6 @@ void ir_raw_event_unregister(struct rc_dev *dev)
                        handler->raw_unregister(dev);
        mutex_unlock(&ir_raw_handler_lock);
 
-       kfifo_free(&dev->raw->kfifo);
        kfree(dev->raw);
        dev->raw = NULL;
 }
index 504bfbc4027adc4953ebdde65658782491182b34..9f3e0fd4cad9f6c63faf32ed914bba50af29ab6a 100644 (file)
@@ -461,13 +461,12 @@ static int m88rs6000t_sleep(struct dvb_frontend *fe)
        dev_dbg(&dev->client->dev, "%s:\n", __func__);
 
        ret = regmap_write(dev->regmap, 0x07, 0x6d);
-       if (ret)
-               goto err;
-       usleep_range(5000, 10000);
-err:
-       if (ret)
+       if (ret) {
                dev_dbg(&dev->client->dev, "failed=%d\n", ret);
-       return ret;
+               return ret;
+       }
+       usleep_range(5000, 10000);
+       return 0;
 }
 
 static int m88rs6000t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
index a7a8452e99d23b2598e4bcb11bbe61a63d735c31..6ab35e315fe7a2dd11ce4078357b0dffff98d1b8 100644 (file)
@@ -1295,7 +1295,7 @@ static int generic_set_freq(struct dvb_frontend *fe,
                            v4l2_std_id std, u32 delsys)
 {
        struct r820t_priv               *priv = fe->tuner_priv;
-       int                             rc = -EINVAL;
+       int                             rc;
        u32                             lo_freq;
 
        tuner_dbg("should set frequency to %d kHz, bw %d MHz\n",
index 0e1ca2b00e61e3e78e3f30f1f357a2902aebb7d0..3450dfb7c427ad1841cfa31cde2647eee31fde72 100644 (file)
@@ -364,8 +364,8 @@ static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
 static const struct dvb_tuner_ops si2157_ops = {
        .info = {
                .name           = "Silicon Labs Si2146/2147/2148/2157/2158",
-               .frequency_min  = 55000000,
-               .frequency_max  = 862000000,
+               .frequency_min  = 42000000,
+               .frequency_max  = 870000000,
        },
 
        .init = si2157_init,
@@ -458,6 +458,9 @@ static int si2157_remove(struct i2c_client *client)
 
        dev_dbg(&client->dev, "\n");
 
+       /* stop statistics polling */
+       cancel_delayed_work_sync(&dev->stat_work);
+
        memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
        fe->tuner_priv = NULL;
        kfree(dev);
index 4e941f00b6008f286b839d8e2f72c41978cc98e5..082ff5608455c273ea9c53e1824bbb76fad15a0e 100644 (file)
@@ -1403,11 +1403,12 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
         * in order to avoid troubles during device release.
         */
        kfree(priv->ctrl.fname);
+       priv->ctrl.fname = NULL;
        memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
        if (p->fname) {
                priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
                if (priv->ctrl.fname == NULL)
-                       rc = -ENOMEM;
+                       return -ENOMEM;
        }
 
        /*
index aee2d76e8dfc996dd3fa4e1f09ca0c55be47e2ed..8def19d9ab921698af30fef7bf7ce5529e097c0b 100644 (file)
@@ -52,7 +52,7 @@ struct as10x_bus_adapter_t {
        struct as10x_cmd_t *cmd, *rsp;
 
        /* bus adapter private ops callback */
-       struct as102_priv_ops_t *ops;
+       const struct as102_priv_ops_t *ops;
 };
 
 struct as102_dev_t {
index 3f669066ccf6837dd8b4022c7f03ab166e3a2f42..0e8030c071b8e74bfdd46e229f258f9b50aa64ca 100644 (file)
@@ -189,7 +189,7 @@ static int as102_read_ep2(struct as10x_bus_adapter_t *bus_adap,
        return actual_len;
 }
 
-static struct as102_priv_ops_t as102_priv_ops = {
+static const struct as102_priv_ops_t as102_priv_ops = {
        .upload_fw_pkt  = as102_send_ep1,
        .xfer_cmd       = as102_usb_xfer_cmd,
        .as102_read_ep2 = as102_read_ep2,
index 9e29e70a78d7b20f8b250cbde914c2a589a82052..df2bc3f732b697b359ef4574bd7db1e9f297bd1f 100644 (file)
@@ -276,7 +276,7 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
                return -EINVAL;
 
        if (tuner) {
-               ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
+               ret = media_create_pad_link(tuner, TUNER_PAD_OUTPUT,
                                            decoder, 0,
                                            MEDIA_LNK_FL_ENABLED);
                if (ret)
index 94363a3ba400a3ccdcaa3d6ec88ebc082d1ecdf2..0e174e86061404d6e01f36d8ff2db5e0f856702b 100644 (file)
@@ -181,7 +181,7 @@ static int stop_urb_transfer(struct au0828_dev *dev)
 static int start_urb_transfer(struct au0828_dev *dev)
 {
        struct urb *purb;
-       int i, ret = -ENOMEM;
+       int i, ret;
 
        dprintk(2, "%s()\n", __func__);
 
@@ -194,7 +194,7 @@ static int start_urb_transfer(struct au0828_dev *dev)
 
                dev->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
                if (!dev->urbs[i])
-                       goto err;
+                       return -ENOMEM;
 
                purb = dev->urbs[i];
 
@@ -207,9 +207,10 @@ static int start_urb_transfer(struct au0828_dev *dev)
                if (!purb->transfer_buffer) {
                        usb_free_urb(purb);
                        dev->urbs[i] = NULL;
+                       ret = -ENOMEM;
                        pr_err("%s: failed big buffer allocation, err = %d\n",
                               __func__, ret);
-                       goto err;
+                       return ret;
                }
 
                purb->status = -EINPROGRESS;
@@ -235,10 +236,7 @@ static int start_urb_transfer(struct au0828_dev *dev)
        }
 
        dev->urb_streaming = true;
-       ret = 0;
-
-err:
-       return ret;
+       return 0;
 }
 
 static void au0828_start_transport(struct au0828_dev *dev)
index 0bd96906339227ec8b3df4e78640fc500be4fb87..d4bdba60b0f71436065e4884d5622cc34dffbfe6 100644 (file)
@@ -10,7 +10,7 @@
 /* Version information */
 #define DRIVER_VERSION "0.1"
 #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV USB Driver"
-#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
+#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@posteo.de>"
 
 /* debug */
 #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
index 48643b94e69449503618e2d95fc16a8da01c319b..c9320d6c613145888fe41f43034bfb32b88aabb5 100644 (file)
@@ -1382,6 +1382,8 @@ static int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
        buffer_size = urb->actual_length;
 
        buffer = kmalloc(buffer_size, GFP_ATOMIC);
+       if (!buffer)
+               return -ENOMEM;
 
        memcpy(buffer, dma_q->ps_head, 3);
        memcpy(buffer+3, p_buffer, buffer_size-3);
index de4ae5eb4830bc4ce6c5c1513bf7f3b29bfa09a6..a6a9508418f8eebef0a4ae41c1e312610afb598c 100644 (file)
@@ -499,6 +499,11 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
        }
 
        dev->adev.users--;
+       if (substream->runtime->dma_area) {
+               dev_dbg(dev->dev, "freeing\n");
+               vfree(substream->runtime->dma_area);
+               substream->runtime->dma_area = NULL;
+       }
        mutex_unlock(&dev->lock);
 
        if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
index 620b83d03f75a1c6952f4982d2a85c53fe0e54aa..54e43fe13e6d35da096e2b0faf08be166cc404b8 100644 (file)
@@ -1259,7 +1259,7 @@ static int cx231xx_create_media_graph(struct cx231xx *dev)
                return 0;
 
        if (tuner) {
-               ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0,
+               ret = media_create_pad_link(tuner, TUNER_PAD_OUTPUT, decoder, 0,
                                            MEDIA_LNK_FL_ENABLED);
                if (ret < 0)
                        return ret;
index 6e02a15d39ce90a1da6c95f6431fa5d04cdb9ec9..b3c09fe54d9bf7f681fb9a964cc8e65b617b1741 100644 (file)
@@ -684,7 +684,7 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
        if (ret < 0)
                goto err;
 
-       if (tmp == 1 || tmp == 3) {
+       if (tmp == 1 || tmp == 3 || tmp == 5) {
                /* configure gpioh1, reset & power slave demod */
                ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01);
                if (ret < 0)
@@ -823,7 +823,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
        if (ret < 0)
                goto err;
 
-       if (tmp == 1 || tmp == 3)
+       if (tmp == 1 || tmp == 3 || tmp == 5)
                state->dual_mode = true;
 
        dev_dbg(&d->udev->dev, "%s: ts mode=%d dual mode=%d\n", __func__,
index 416a97f05ec8539fbc2c11dad23e1261a819650c..df22001f9e41273d137ab0c92979ecbb9c9b29b3 100644 (file)
@@ -112,9 +112,10 @@ static const u32 clock_lut_it9135[] = {
  * 0  TS
  * 1  DCA + PIP
  * 3  PIP
+ * 5  DCA + PIP
  * n  DCA
  *
- * Values 0 and 3 are seen to this day. 0 for single TS and 3 for dual TS.
+ * Values 0, 3 and 5 are seen to this day. 0 for single TS and 3/5 for dual TS.
  */
 
 #define EEPROM_BASE_AF9035        0x42fd
index 023d91f7e6542f0905af07964648988c252a5ad7..35f27e2e4e284f5a6554fe963c60931034d13864 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DVB USB framework
  *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@posteo.de>
  * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
  *
  *    This program is free software; you can redistribute it and/or modify
index 45f07090d431a25c3c2b2c645d90bf9c5b113c14..a1622bda2a5e00be3529309b1afe18bfa4ee3872 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DVB USB framework
  *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@posteo.de>
  * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
  *
  *    This program is free software; you can redistribute it and/or modify
index f0565bf3673e8687ba16599aafc59152ad85f1da..5ec159f2239974ca14bbf8038ce865b49ac58a4b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DVB USB framework
  *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@posteo.de>
  * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
  *
  *    This program is free software; you can redistribute it and/or modify
@@ -1129,7 +1129,7 @@ int dvb_usbv2_reset_resume(struct usb_interface *intf)
 EXPORT_SYMBOL(dvb_usbv2_reset_resume);
 
 MODULE_VERSION("2.0");
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_DESCRIPTION("DVB USB common");
 MODULE_LICENSE("GPL");
index 22bdce15ecf31fcd351309ca7fa5794cb228869d..5bafeb6486beb3c7da3459e63a74ca0de6994957 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DVB USB framework
  *
- * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@posteo.de>
  * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
  *
  *    This program is free software; you can redistribute it and/or modify
index 1dd962535f972dda834a913cd4e5ae6bd26b9bc7..02dbc6c45423a157b0ae857dbb9963dc483e712a 100644 (file)
@@ -847,10 +847,17 @@ static const struct usb_device_id dvbsky_id_table[] = {
                USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI,
                &dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI",
                RC_MAP_TT_1500) },
+       { DVB_USB_DEVICE(USB_VID_TECHNOTREND,
+               USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2,
+               &dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI v1.1",
+               RC_MAP_TT_1500) },
        { DVB_USB_DEVICE(USB_VID_TERRATEC,
                USB_PID_TERRATEC_H7_3,
                &dvbsky_t680c_props, "Terratec H7 Rev.4",
                RC_MAP_TT_1500) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R4,
+               &dvbsky_s960_props, "Terratec Cinergy S2 Rev.4",
+               RC_MAP_DVBSKY) },
        { }
 };
 MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
index 444579be0b779618d63c61ad23cb7d531faee64e..7d16252dbb71f2c053ac52466592f555487051af 100644 (file)
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
 struct mxl111sf_tuner_state {
        struct mxl111sf_state *mxl_state;
 
-       struct mxl111sf_tuner_config *cfg;
+       const struct mxl111sf_tuner_config *cfg;
 
        enum mxl_if_freq if_freq;
 
@@ -489,8 +489,8 @@ static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
 };
 
 struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_tuner_config *cfg)
+                               struct mxl111sf_state *mxl_state,
+                               const struct mxl111sf_tuner_config *cfg)
 {
        struct mxl111sf_tuner_state *state = NULL;
 
index e6caab21a1973e2a918de7d095fb2c548a052e22..509b5507121849fea1c0526dd1cbc4494ec49930 100644 (file)
@@ -63,13 +63,13 @@ struct mxl111sf_tuner_config {
 #if IS_ENABLED(CONFIG_DVB_USB_MXL111SF)
 extern
 struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_tuner_config *cfg);
+                               struct mxl111sf_state *mxl_state,
+                               const struct mxl111sf_tuner_config *cfg);
 #else
 static inline
 struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
-                                          struct mxl111sf_state *mxl_state,
-                                          struct mxl111sf_tuner_config *cfg)
+                               struct mxl111sf_state *mxl_state,
+                               const struct mxl111sf_tuner_config *cfg)
 {
        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
        return NULL;
index b669deccc34c64065e801ee29a68d85b05c8dedc..5d676b533a3ab245956764592047219d035c0069 100644 (file)
@@ -856,7 +856,7 @@ static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
        return 0;
 }
 
-static struct mxl111sf_tuner_config mxl_tuner_config = {
+static const struct mxl111sf_tuner_config mxl_tuner_config = {
        .if_freq         = MXL_IF_6_0, /* applies to external IF output, only */
        .invert_spectrum = 0,
        .read_reg        = mxl111sf_read_reg,
@@ -888,7 +888,7 @@ static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
        state->tuner.function = MEDIA_ENT_F_TUNER;
        state->tuner.name = "mxl111sf tuner";
        state->tuner_pads[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
-       state->tuner_pads[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
+       state->tuner_pads[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
 
        ret = media_entity_pads_init(&state->tuner,
                                     TUNER_NUM_PADS, state->tuner_pads);
index eb5787a3191e7afc31e69e6e9757297b745279c0..c4c6e92e8643c0f782617d534ec60b08ddfc01ce 100644 (file)
@@ -259,6 +259,10 @@ static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                ret = -EOPNOTSUPP;
        }
 
+       /* Retry failed I2C messages */
+       if (ret == -EPIPE)
+               ret = -EAGAIN;
+
 err_mutex_unlock:
        mutex_unlock(&d->i2c_mutex);
 
@@ -619,6 +623,10 @@ static int rtl28xxu_identify_state(struct dvb_usb_device *d, const char **name)
        }
        dev_dbg(&d->intf->dev, "chip_id=%u\n", dev->chip_id);
 
+       /* Retry failed I2C messages */
+       d->i2c_adap.retries = 1;
+       d->i2c_adap.timeout = msecs_to_jiffies(10);
+
        return WARM;
 err:
        dev_dbg(&d->intf->dev, "failed=%d\n", ret);
index ca8f3c2b10824c29c28f4be0e54ae931f08a8059..55136cde38f57c8841974b5f734054ee178adbdf 100644 (file)
@@ -1,6 +1,6 @@
 /* usb-urb.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file keeps functions for initializing and handling the
index 83684ed023cd9bba08a20ae9cfe682f636da5a36..7ba975bea96a6d0ba03f5276f53322bfd29715a1 100644 (file)
@@ -1,7 +1,7 @@
 /* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
  * USB2.0 (A800) DVB-T receiver.
  *
- * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * Thanks to
  *   - AVerMedia who kindly provided information and
@@ -185,7 +185,7 @@ static struct usb_driver a800_driver = {
 
 module_usb_driver(a800_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index ab715118172878ff52c8ba3e1002ec2357971a8c..907ac01ae2979a56657e6ddc32fafecfbb9c9042 100644 (file)
@@ -13,7 +13,7 @@
  *
  * TODO: Use the cx25840-driver for the analogue part
  *
- * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.de)
  * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
  * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
  *
@@ -2314,7 +2314,7 @@ static struct usb_driver cxusb_driver = {
 
 module_usb_driver(cxusb_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
 MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
index 0d248ce02a9b2eb02b9da6fecbb6175319110574..c16f999b9d7c9de8c2cc75526256ba30fa69a33c 100644 (file)
@@ -881,7 +881,7 @@ static struct usb_driver dib0700_driver = {
 module_usb_driver(dib0700_driver);
 
 MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw");
-MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index 7ed49646a699dd750fe7eded35632de7fd7cf4a4..ea0391e32d23b16ac848e33d60492a9e9e3dbb22 100644 (file)
@@ -1736,8 +1736,13 @@ static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
        struct dib0700_adapter_state *st = adap->priv;
        struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
 
-       if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
-               return -ENODEV;
+       if (adap->id == 0) {
+               if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
+                       return -ENODEV;
+       } else {
+               if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
+                       return -ENODEV;
+       }
 
        st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
        adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
@@ -1773,6 +1778,20 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
        return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
 }
 
+static int stk809x_frontend1_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *state = adap->priv;
+
+       if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
+               return -ENODEV;
+
+       state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x82, 0);
+
+       adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
+
+       return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
 static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
 {
        struct dib0700_adapter_state *st = adap->priv;
@@ -3794,6 +3813,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
 /* 80 */{ USB_DEVICE(USB_VID_ELGATO,   USB_PID_ELGATO_EYETV_DTT_2) },
        { USB_DEVICE(USB_VID_PCTV,      USB_PID_PCTV_2002E) },
        { USB_DEVICE(USB_VID_PCTV,      USB_PID_PCTV_2002E_SE) },
+       { USB_DEVICE(USB_VID_PCTV,      USB_PID_DIBCOM_STK8096PVR) },
        { 0 }           /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -4959,6 +4979,59 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                            RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                               .num_frontends = 1,
+                               .fe = {{
+                                       .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                                       .pid_filter_count = 32,
+                                       .pid_filter = stk80xx_pid_filter,
+                                       .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                                       .frontend_attach  = stk809x_frontend_attach,
+                                       .tuner_attach     = dib809x_tuner_attach,
+
+                                       DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                               } },
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       }, {
+                               .num_frontends = 1,
+                               .fe = { {
+                                       .caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+                                               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                                       .pid_filter_count = 32,
+                                       .pid_filter = stk80xx_pid_filter,
+                                       .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+                                       .frontend_attach  = stk809x_frontend1_attach,
+                                       .tuner_attach     = dib809x_tuner_attach,
+
+                                       DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                               } },
+                               .size_of_priv =
+                                       sizeof(struct dib0700_adapter_state),
+                       },
+               },
+               .num_device_descs = 1,
+               .devices = {
+                       {   "DiBcom STK8096-PVR reference design",
+                               { &dib0700_usb_id_table[83], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc.core = {
+                       .rc_interval      = DEFAULT_RC_INTERVAL,
+                       .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+                       .module_name  = "dib0700",
+                       .rc_query         = dib0700_rc_query_old_firmware,
+                       .allowed_protos   = RC_BIT_RC5 |
+                               RC_BIT_RC6_MCE |
+                               RC_BIT_NEC,
+                       .change_protocol  = dib0700_change_protocol,
+               },
        },
 };
 
index ef3a8f75f82ebe21b4ee5b7963aed9bbf8449c32..35de6095926df2289fa089a5b2a4410a9f0d15d8 100644 (file)
@@ -1,6 +1,6 @@
 /* Common methods for dibusb-based-receivers.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the Free
index a4ac37e0e98b692ccc4a72ea5f93c556bcaf1447..a0057641cc86838d80d694ca9511e8547a37e480 100644 (file)
@@ -1,10 +1,10 @@
 /* DVB USB compliant linux driver for mobile DVB-T USB devices based on
  * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * based on GPL code from DiBcom, which has
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ * Copyright (C) 2004 Amaury Demol for DiBcom
  *
  *     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
@@ -465,7 +465,7 @@ static struct usb_driver dibusb_driver = {
 
 module_usb_driver(dibusb_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index 9d1a59d09c523c3fb8d6ae4be4f6641a0b6c1507..08fb8a3f6e0cc23e87ff150c747361fd5259b1f6 100644 (file)
@@ -1,10 +1,10 @@
 /* DVB USB compliant linux driver for mobile DVB-T USB devices based on
  * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P)
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * based on GPL code from DiBcom, which has
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ * Copyright (C) 2004 Amaury Demol for DiBcom
  *
  *     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
@@ -143,7 +143,7 @@ static struct usb_driver dibusb_mc_driver = {
 
 module_usb_driver(dibusb_mc_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index 32ab1392313fbdaed6ec67591cbd38e964bde878..3f82163d8ab89061410bdff4b68bea2e1d153c27 100644 (file)
@@ -1,6 +1,6 @@
 /* Header file for all dibusb-based-receivers.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the Free
index 772bde3c5020a63b026567cf6e62ba44f2c8714b..63134335c99406ca7df3d284cd3ba95d4154cae3 100644 (file)
@@ -1,7 +1,7 @@
 /* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
  * receiver
  *
- * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * partly based on the SDK published by Nebula Electronics
  *
@@ -348,7 +348,7 @@ static struct usb_driver digitv_driver = {
 
 module_usb_driver(digitv_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
 MODULE_VERSION("1.0-alpha");
 MODULE_LICENSE("GPL");
index 8637ad1be6be430895c403ef2382f38d58494f0b..7e72a1bef76a22d6070a20ea71297e6a5da280ec 100644 (file)
@@ -1,7 +1,7 @@
 /* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
  * Typhoon/ Yuan DVB-T USB2.0 receiver.
  *
- * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@posteo.de>
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the Free
index c357fb3b0a883c382a6c480a0c9567f665f8d10e..ca3b69aa96882f47692e5bbac10b12943dbba418 100644 (file)
@@ -1,7 +1,7 @@
 /* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
  * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * Thanks to Steve Chang from WideView for providing support for the WT-220U.
  *
@@ -362,7 +362,7 @@ static struct usb_driver dtt200u_usb_driver = {
 
 module_usb_driver(dtt200u_usb_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index 005b0a7df3585d1653e61d8b8a63a9278a0ab7cf..efccc399b1cba7cdb92f59b48b7033fa1619b7d1 100644 (file)
@@ -1,7 +1,7 @@
 /* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
  * Typhoon/ Yuan DVB-T USB2.0 receiver.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the Free
index 6b7b2a89242e797d9bbe0c959ddef57515a25a8f..7e619d638809b12fce6c5fe9c7d744e0b56ef87a 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-common.h is part of the DVB USB library.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * a header file containing prototypes and types for internal use of the dvb-usb-lib
index 9ddfcab268be9c797e7ce6a276dc4168fe0651df..71de19ba0e01e211fc4d071ddc61b35755953513 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-dvb.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for initializing and handling the
index 733a7ff7b207819bcd05f2a816388fa21e9f69b5..dd048a7c461c8ffe1884b52ca80ff2b35233adaf 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-firmware.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
index 88e4a62abc44db45e72ea93bc46334805e0ef2f7..4f0b0adce7f5dfe18d47af28968b9d2d307fb3ff 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-i2c.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for (de-)initializing an I2C adapter.
index 1adf325012f7340f9648ae46b5df72532beeb94c..3896ba9a4179670687eadb63bdd199e251dc904e 100644 (file)
@@ -3,7 +3,7 @@
  *
  * dvb-usb-init.c
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the Free
@@ -299,6 +299,6 @@ void dvb_usb_device_exit(struct usb_interface *intf)
 EXPORT_SYMBOL(dvb_usb_device_exit);
 
 MODULE_VERSION("1.0");
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
 MODULE_LICENSE("GPL");
index 7b5dae3077f6a2550584b2eaada3da0a1d7632ca..c259f9e43542970d87a32ca2e79806d87d193a8e 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-remote.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file contains functions for initializing the input-device and for handling remote-control-queries.
index 5c8f651344fc1fd2a713014a82d14cea8cc3718c..95f9097498cb86259f0209013ab499894ab39839 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb-urb.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file keeps functions for initializing and handling the
index ce4c4e3b58bb7516f9bdff338d1b6b8ed2d0332e..639c4678c65b96c82293f7546919768401f43dbd 100644 (file)
@@ -1,6 +1,6 @@
 /* dvb-usb.h is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * the headerfile, all dvb-usb-drivers have to include.
index 14ef25dc6cd33076a288573ba413eb4e7ded6454..dd46d6c78c4ea27deea934dbb6515b0560a69017 100644 (file)
@@ -1688,6 +1688,7 @@ enum dw2102_table_entry {
        TECHNOTREND_S2_4600,
        TEVII_S482_1,
        TEVII_S482_2,
+       TERRATEC_CINERGY_S2_BOX,
 };
 
 static struct usb_device_id dw2102_table[] = {
@@ -1702,19 +1703,20 @@ static struct usb_device_id dw2102_table[] = {
        [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
        [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)},
        [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)},
-       [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
+       [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R1)},
        [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
        [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
        [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
        [TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)},
        [TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
-       [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)},
+       [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R2)},
        [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
        [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
        [TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND,
                USB_PID_TECHNOTREND_CONNECT_S2_4600)},
        [TEVII_S482_1] = {USB_DEVICE(0x9022, 0xd483)},
        [TEVII_S482_2] = {USB_DEVICE(0x9022, 0xd484)},
+       [TERRATEC_CINERGY_S2_BOX] = {USB_DEVICE(USB_VID_TERRATEC, 0x0105)},
        { }
 };
 
@@ -2232,7 +2234,7 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = {
                } },
                }
        },
-       .num_device_descs = 3,
+       .num_device_descs = 4,
        .devices = {
                { "TechnoTrend TT-connect S2-4600",
                        { &dw2102_table[TECHNOTREND_S2_4600], NULL },
@@ -2246,6 +2248,10 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = {
                        { &dw2102_table[TEVII_S482_2], NULL },
                        { NULL },
                },
+               { "Terratec Cinergy S2 USB BOX",
+                       { &dw2102_table[TERRATEC_CINERGY_S2_BOX], NULL },
+                       { NULL },
+               },
        }
 };
 
index 6c55384e2fca8638d7846241dfeffcda528fa96a..fc7569e2728d2201e14897cddd41c9a9504a9716 100644 (file)
@@ -1,7 +1,7 @@
 /* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
  * DVB-T receiver.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the Free
@@ -227,7 +227,7 @@ static struct usb_driver nova_t_driver = {
 
 module_usb_driver(nova_t_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index 6c3c477229551642fc762d753337a115c3d64b10..51487d2f7764cfcec87cb365bc15817123e68ef0 100644 (file)
@@ -512,7 +512,7 @@ static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
                        &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
 
        if (a->fe_adap[0].fe) {
-               struct stv6110x_devctl *ctl;
+               const struct stv6110x_devctl *ctl;
 
                ctl = dvb_attach(stv6110x_attach,
                                a->fe_adap[0].fe,
index f10717311e05bb9873c3fa24e40b369b1d9c4237..ecc207fbaf3cfffd54595492bd0e6f7427afa9d2 100644 (file)
@@ -820,7 +820,7 @@ static struct usb_driver ttusb2_driver = {
 
 module_usb_driver(ttusb2_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index 9b042292e788db67d5576515e10d54b6e6b6415e..58ad5b4f856c5dd5e1ba0d2a824026dc10cc5e97 100644 (file)
@@ -1,7 +1,7 @@
 /* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
  * DVB-T receiver.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the Free
@@ -145,7 +145,7 @@ static struct usb_driver umt_driver = {
 
 module_usb_driver(umt_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index d62ee0f5a1658d64cf165ba1a9fe6dde2a34774a..89173603be6754e1e8e30c68a06affcfa89482fe 100644 (file)
@@ -1,6 +1,6 @@
 /* usb-urb.c is part of the DVB USB library.
  *
- * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@posteo.de)
  * see dvb-usb-init.c for copyright information.
  *
  * This file keeps functions for initializing and handling the
index d361a72ca0fa227d396d64ebe9e187c2aaa6d393..27398c08c69dc4c6cfec28703ebc53d64949fe75 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
  *
- * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@posteo.de>
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
index ee1e19e364452e142f4e35c393714c53a4e6d7d3..40de33de90a7aef04ae6cf95153c8177596a16ba 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
  *                    Metzler Brothers Systementwicklung GbR
  *
- * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@posteo.de>
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
@@ -439,7 +439,7 @@ static struct usb_driver vp702x_usb_driver = {
 
 module_usb_driver(vp702x_usb_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index e708afc6a57fbce136a0b894ba660645552f3c64..7765602ea658c4ecf6ef951949dec5a912c8ae26 100644 (file)
@@ -1,7 +1,7 @@
 /* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
  * DVB-T receiver.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
index d750724132ee372902340fcf8f3bec2e4ef3401a..13340af0d39c34bee810a8b225da511e950dcfc5 100644 (file)
@@ -2,7 +2,7 @@
  *  - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
  *  - DigitalNow TinyUSB2 DVB-t receiver
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
@@ -296,7 +296,7 @@ static struct usb_driver vp7045_usb_driver = {
 
 module_usb_driver(vp7045_usb_driver);
 
-MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index cf5ec46f8bb1bbc40138af764be3f0a79f763aa1..66499932ca767f97156bb9bce08e82a0dfc9d8ef 100644 (file)
@@ -1,7 +1,7 @@
 /* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
  * USB2.0 DVB-T receiver.
  *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
  *
  * Thanks to Twinhan who kindly provided hardware and information.
  *
index b58acd3fcd9918368b2eadac79d61a5f64d80b38..72f3f4d50253a5041573140b6b5afa4b758dd3b8 100644 (file)
@@ -64,6 +64,8 @@ static int em28xx_initialize_mt9m111(struct em28xx *dev)
                i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
                                &regs[i][0], 3);
 
+       /* FIXME: This won't be creating a sensor at the media graph */
+
        return 0;
 }
 
@@ -91,6 +93,8 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev)
                i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
                                &regs[i][0], 3);
 
+       /* FIXME: This won't be creating a sensor at the media graph */
+
        return 0;
 }
 
index a1b6ef5894a689a39c6597aa668db2d1d4115b33..ba442c9674155ad94197f0c4f9fbde7446f0d55c 100644 (file)
@@ -570,7 +570,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type    = TUNER_ABSENT,
                .is_webcam     = 1,
                .input         = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = 0,
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = silvercrest_reg_seq,
@@ -583,7 +583,7 @@ struct em28xx_board em28xx_boards[] = {
                .decoder      = EM28XX_SAA711X,
                .tuner_type   = TUNER_ABSENT,
                .input        = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -605,7 +605,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type    = TUNER_ABSENT,
                .is_webcam     = 1,
                .input         = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = 0,
                        .amux     = EM28XX_AMUX_VIDEO,
                } },
@@ -616,7 +616,7 @@ struct em28xx_board em28xx_boards[] = {
                .tda9887_conf = TDA9887_PRESENT,
                .decoder      = EM28XX_SAA711X,
                .input        = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -635,7 +635,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -655,7 +655,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -675,7 +675,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -715,7 +715,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -735,7 +735,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -755,7 +755,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -775,7 +775,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -800,7 +800,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE4,
                        .amux     = EM28XX_AMUX_AUX,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE5,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -819,7 +819,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type   = TUNER_ABSENT,
                .is_webcam    = 1,
                .input        = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = 0,
                        .amux     = EM28XX_AMUX_VIDEO,
                } },
@@ -829,7 +829,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type   = TUNER_ABSENT,
                .is_webcam    = 1,
                .input        = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = 0,
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = silvercrest_reg_seq,
@@ -848,7 +848,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
@@ -863,7 +863,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type   = TUNER_ABSENT,   /* Capture only device */
                .decoder      = EM28XX_SAA711X,
                .input        = { {
-                       .type  = EM28XX_VMUX_COMPOSITE1,
+                       .type  = EM28XX_VMUX_COMPOSITE,
                        .vmux  = SAA7115_COMPOSITE0,
                        .amux  = EM28XX_AMUX_LINE_IN,
                }, {
@@ -879,7 +879,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type   = TUNER_ABSENT,
                .is_webcam    = 1,
                .input        = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = 0,
                        .amux     = EM28XX_AMUX_VIDEO,
                } },
@@ -889,7 +889,7 @@ struct em28xx_board em28xx_boards[] = {
                .decoder      = EM28XX_SAA711X,
                .tuner_type   = TUNER_ABSENT,   /* Capture only device */
                .input        = { {
-                       .type  = EM28XX_VMUX_COMPOSITE1,
+                       .type  = EM28XX_VMUX_COMPOSITE,
                        .vmux  = SAA7115_COMPOSITE0,
                        .amux  = EM28XX_AMUX_LINE_IN,
                }, {
@@ -909,7 +909,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -930,7 +930,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -952,7 +952,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -974,7 +974,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = TVP5150_COMPOSITE0,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -992,7 +992,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = TVP5150_COMPOSITE0,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1006,7 +1006,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type    = TUNER_ABSENT,  /* Capture only device */
                .decoder       = EM28XX_TVP5150,
                .input         = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1029,7 +1029,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = pinnacle_hybrid_pro_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = pinnacle_hybrid_pro_analog,
@@ -1100,7 +1100,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = terratec_cinergy_USB_XS_FR_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = terratec_cinergy_USB_XS_FR_analog,
@@ -1186,7 +1186,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1213,7 +1213,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1239,7 +1239,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1265,7 +1265,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1291,7 +1291,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1317,7 +1317,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1343,7 +1343,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = default_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = default_analog,
@@ -1368,7 +1368,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1392,7 +1392,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux      = SAA7115_COMPOSITE4,
                        .amux      = EM28XX_AMUX_VIDEO,
                }, {
-                       .type      = EM28XX_VMUX_COMPOSITE1,
+                       .type      = EM28XX_VMUX_COMPOSITE,
                        .vmux      = SAA7115_COMPOSITE0,
                        .amux      = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1413,7 +1413,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1428,7 +1428,7 @@ struct em28xx_board em28xx_boards[] = {
                .decoder    = EM28XX_SAA711X,
                .tuner_type = TUNER_ABSENT, /* capture only board */
                .input      = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1443,7 +1443,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type   = TUNER_ABSENT,   /* Capture-only board */
                .decoder      = EM28XX_SAA711X,
                .input        = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = vc211a_enable,
@@ -1465,7 +1465,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1485,7 +1485,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1500,7 +1500,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type   = TUNER_ABSENT, /* capture only board */
                .decoder      = EM28XX_SAA711X,
                .input        = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1520,7 +1520,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = SAA7115_COMPOSITE2,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1541,7 +1541,7 @@ struct em28xx_board em28xx_boards[] = {
                        .aout     = EM28XX_AOUT_MONO |  /* I2S */
                                    EM28XX_AOUT_MASTER, /* Line out pin */
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1555,6 +1555,7 @@ struct em28xx_board em28xx_boards[] = {
                .buttons = std_snapshot_button,
                .tda9887_conf = TDA9887_PRESENT,
                .tuner_type   = TUNER_YMEC_TVF_5533MF,
+               .tuner_addr   = 0x60,
                .decoder      = EM28XX_SAA711X,
                .input        = { {
                        .type     = EM28XX_VMUX_TELEVISION,
@@ -1563,7 +1564,7 @@ struct em28xx_board em28xx_boards[] = {
                        .aout     = EM28XX_AOUT_MONO |  /* I2S */
                                    EM28XX_AOUT_MASTER, /* Line out pin */
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1581,7 +1582,7 @@ struct em28xx_board em28xx_boards[] = {
                        .type     = EM28XX_VMUX_SVIDEO,
                        .vmux     = SAA7115_SVIDEO3,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                } },
        },
@@ -1610,7 +1611,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = em2880_msi_digivox_ad_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = em2880_msi_digivox_ad_analog,
@@ -1633,7 +1634,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = em2880_msi_digivox_ad_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = em2880_msi_digivox_ad_analog,
@@ -1654,7 +1655,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = TVP5150_COMPOSITE0,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1677,7 +1678,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = default_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = default_analog,
@@ -1708,7 +1709,7 @@ struct em28xx_board em28xx_boards[] = {
                        .gpio = em2882_kworld_315u_analog,
                        .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
                }, {
-                       .type = EM28XX_VMUX_COMPOSITE1,
+                       .type = EM28XX_VMUX_COMPOSITE,
                        .vmux = SAA7115_COMPOSITE0,
                        .amux = EM28XX_AMUX_LINE_IN,
                        .gpio = em2882_kworld_315u_analog1,
@@ -1735,7 +1736,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux = EM28XX_AMUX_VIDEO,
                        .gpio = default_analog,
                }, {
-                       .type = EM28XX_VMUX_COMPOSITE1,
+                       .type = EM28XX_VMUX_COMPOSITE,
                        .vmux = TVP5150_COMPOSITE1,
                        .amux = EM28XX_AMUX_LINE_IN,
                        .gpio = default_analog,
@@ -1758,7 +1759,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = default_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = default_analog,
@@ -1782,7 +1783,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = pinnacle_hybrid_pro_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = pinnacle_hybrid_pro_analog,
@@ -1808,7 +1809,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1834,7 +1835,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = TVP5150_COMPOSITE0,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1859,7 +1860,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = hauppauge_wintv_hvr_900_analog,
@@ -1904,7 +1905,7 @@ struct em28xx_board em28xx_boards[] = {
                        .gpio     = kworld_330u_analog,
                        .aout     = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = kworld_330u_analog,
@@ -1951,7 +1952,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
 
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1970,7 +1971,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type   = TUNER_ABSENT,
                .decoder      = EM28XX_SAA711X,
                .input           = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -1990,7 +1991,7 @@ struct em28xx_board em28xx_boards[] = {
                        .vmux     = TVP5150_COMPOSITE0,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, { /* Composite has not been tested yet */
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_VIDEO,
                }, { /* S-video has not been tested yet */
@@ -2006,7 +2007,7 @@ struct em28xx_board em28xx_boards[] = {
                .decoder         = EM28XX_SAA711X,
                .xclk            = EM28XX_XCLK_FREQUENCY_12MHZ,
                .input           = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -2023,7 +2024,7 @@ struct em28xx_board em28xx_boards[] = {
                .xclk            = EM28XX_XCLK_FREQUENCY_12MHZ,
                .mute_gpio       = terratec_av350_mute_gpio,
                .input           = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AUDIO_SRC_LINE,
                        .gpio     = terratec_av350_unmute_gpio,
@@ -2041,7 +2042,7 @@ struct em28xx_board em28xx_boards[] = {
                .decoder      = EM28XX_SAA711X,
                .tuner_type   = TUNER_ABSENT,   /* Capture only device */
                .input        = { {
-                       .type  = EM28XX_VMUX_COMPOSITE1,
+                       .type  = EM28XX_VMUX_COMPOSITE,
                        .vmux  = SAA7115_COMPOSITE0,
                        .amux  = EM28XX_AMUX_LINE_IN,
                }, {
@@ -2067,7 +2068,7 @@ struct em28xx_board em28xx_boards[] = {
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = evga_indtube_analog,
                }, {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                        .gpio     = evga_indtube_analog,
@@ -2125,7 +2126,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type          = TUNER_ABSENT,
                .decoder             = EM28XX_SAA711X,
                .input               = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = SAA7115_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -2238,7 +2239,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type   = TUNER_ABSENT,
                .is_webcam    = 1,
                .input        = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .amux     = EM28XX_AMUX_VIDEO,
                        .gpio     = speedlink_vad_laplace_reg_seq,
                } },
@@ -2272,7 +2273,7 @@ struct em28xx_board em28xx_boards[] = {
                .tuner_type    = TUNER_ABSENT,  /* Capture only device */
                .decoder       = EM28XX_TVP5150,
                .input         = { {
-                       .type     = EM28XX_VMUX_COMPOSITE1,
+                       .type     = EM28XX_VMUX_COMPOSITE,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
                }, {
@@ -3012,6 +3013,48 @@ static void flush_request_modules(struct em28xx *dev)
        flush_work(&dev->request_module_wk);
 }
 
+static int em28xx_media_device_init(struct em28xx *dev,
+                                   struct usb_device *udev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct media_device *mdev;
+
+       mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
+       if (!mdev)
+               return -ENOMEM;
+
+       mdev->dev = &udev->dev;
+
+       if (!dev->name)
+               strlcpy(mdev->model, "unknown em28xx", sizeof(mdev->model));
+       else
+               strlcpy(mdev->model, dev->name, sizeof(mdev->model));
+       if (udev->serial)
+               strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
+       strcpy(mdev->bus_info, udev->devpath);
+       mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
+       mdev->driver_version = LINUX_VERSION_CODE;
+
+       media_device_init(mdev);
+
+       dev->media_dev = mdev;
+#endif
+       return 0;
+}
+
+static void em28xx_unregister_media_device(struct em28xx *dev)
+{
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+       if (dev->media_dev) {
+               media_device_unregister(dev->media_dev);
+               media_device_cleanup(dev->media_dev);
+               kfree(dev->media_dev);
+               dev->media_dev = NULL;
+       }
+#endif
+}
+
 /*
  * em28xx_release_resources()
  * unregisters the v4l2,i2c and usb devices
@@ -3023,6 +3066,8 @@ static void em28xx_release_resources(struct em28xx *dev)
 
        mutex_lock(&dev->lock);
 
+       em28xx_unregister_media_device(dev);
+
        if (dev->def_i2c_bus)
                em28xx_i2c_unregister(dev, 1);
        em28xx_i2c_unregister(dev, 0);
@@ -3167,6 +3212,8 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
         */
        snprintf(dev->name, sizeof(dev->name), "%s #%d", chip_name, dev->devno);
 
+       em28xx_media_device_init(dev, udev);
+
        if (dev->is_audio_only) {
                retval = em28xx_audio_setup(dev);
                if (retval)
@@ -3467,7 +3514,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        /* save our data pointer in this interface device */
        usb_set_intfdata(interface, dev);
 
-       /* allocate device struct */
+       /* allocate device struct and check if the device is a webcam */
        mutex_init(&dev->lock);
        retval = em28xx_init_dev(dev, udev, interface, nr);
        if (retval) {
@@ -3483,6 +3530,15 @@ static int em28xx_usb_probe(struct usb_interface *interface,
                try_bulk = usb_xfer_mode > 0;
        }
 
+       /* Disable V4L2 if the device doesn't have a decoder */
+       if (has_video &&
+           dev->board.decoder == EM28XX_NODECODER && !dev->board.is_webcam) {
+               printk(DRIVER_NAME
+                      ": Currently, V4L2 is not supported on this model\n");
+               has_video = false;
+               dev->has_video = false;
+       }
+
        /* Select USB transfer types to use */
        if (has_video) {
                if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk))
@@ -3501,9 +3557,14 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 
        request_modules(dev);
 
-       /* Should be the last thing to do, to avoid newer udev's to
-          open the device before fully initializing it
+       /*
+        * Do it at the end, to reduce dynamic configuration changes during
+        * the device init. Yet, as request_modules() can be async, the
+        * topology will likely change after the load of the em28xx subdrivers.
         */
+#ifdef CONFIG_MEDIA_CONTROLLER
+       retval = media_device_register(dev->media_dev);
+#endif
 
        return 0;
 
index bf5c24467c65bec87b43c14b3f2552cb9dce6aab..ea80541d58f065190b738730d93b3e8cd048750f 100644 (file)
@@ -916,6 +916,9 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module,
                       dev->name, result);
                goto fail_adapter;
        }
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+       dvb->adapter.mdev = dev->media_dev;
+#endif
 
        /* Ensure all frontends negotiate bus access */
        dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
@@ -994,8 +997,15 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module,
 
        /* register network adapter */
        dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
+
+       result = dvb_create_media_graph(&dvb->adapter, false);
+       if (result < 0)
+               goto fail_create_graph;
+
        return 0;
 
+fail_create_graph:
+       dvb_net_release(&dvb->net);
 fail_fe_conn:
        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 fail_fe_mem:
index 0e86ff423c499d196303da2999215e7454d3867f..16a2d4039330307a295d760bef31919c099966b6 100644 (file)
@@ -196,7 +196,6 @@ static void em28xx_wake_i2c(struct em28xx *dev)
        v4l2_device_call_all(v4l2_dev, 0, core,  reset, 0);
        v4l2_device_call_all(v4l2_dev, 0, video, s_routing,
                             INPUT(dev->ctl_input)->vmux, 0, 0);
-       v4l2_device_call_all(v4l2_dev, 0, video, s_stream, 0);
 }
 
 static int em28xx_colorlevels_set_default(struct em28xx *dev)
@@ -867,6 +866,275 @@ static void res_free(struct em28xx *dev, enum v4l2_buf_type f_type)
        em28xx_videodbg("res: put %d\n", res_type);
 }
 
+static void em28xx_v4l2_media_release(struct em28xx *dev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+       int i;
+
+       for (i = 0; i < MAX_EM28XX_INPUT; i++) {
+               if (!INPUT(i)->type)
+                       return;
+               media_device_unregister_entity(&dev->input_ent[i]);
+       }
+#endif
+}
+
+/*
+ * Media Controller helper functions
+ */
+
+static int em28xx_v4l2_create_media_graph(struct em28xx *dev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct em28xx_v4l2 *v4l2 = dev->v4l2;
+       struct media_device *mdev = dev->media_dev;
+       struct media_entity *entity;
+       struct media_entity *if_vid = NULL, *if_aud = NULL;
+       struct media_entity *tuner = NULL, *decoder = NULL;
+       int i, ret;
+
+       if (!mdev)
+               return 0;
+
+       /* Webcams are really simple */
+       if (dev->board.is_webcam) {
+               media_device_for_each_entity(entity, mdev) {
+                       if (entity->function != MEDIA_ENT_F_CAM_SENSOR)
+                               continue;
+                       ret = media_create_pad_link(entity, 0,
+                                                   &v4l2->vdev.entity, 0,
+                                                   MEDIA_LNK_FL_ENABLED);
+                       if (ret)
+                               return ret;
+               }
+               return 0;
+       }
+
+       /* Non-webcams have analog TV decoder and other complexities */
+
+       media_device_for_each_entity(entity, mdev) {
+               switch (entity->function) {
+               case MEDIA_ENT_F_IF_VID_DECODER:
+                       if_vid = entity;
+                       break;
+               case MEDIA_ENT_F_IF_AUD_DECODER:
+                       if_aud = entity;
+                       break;
+               case MEDIA_ENT_F_TUNER:
+                       tuner = entity;
+                       break;
+               case MEDIA_ENT_F_ATV_DECODER:
+                       decoder = entity;
+                       break;
+               }
+       }
+
+       /* Analog setup, using tuner as a link */
+
+       /* Something bad happened! */
+       if (!decoder)
+               return -EINVAL;
+
+       if (tuner) {
+               if (if_vid) {
+                       ret = media_create_pad_link(tuner, TUNER_PAD_OUTPUT,
+                                                   if_vid,
+                                                   IF_VID_DEC_PAD_IF_INPUT,
+                                                   MEDIA_LNK_FL_ENABLED);
+                       if (ret)
+                               return ret;
+                       ret = media_create_pad_link(if_vid, IF_VID_DEC_PAD_OUT,
+                                               decoder, DEMOD_PAD_IF_INPUT,
+                                               MEDIA_LNK_FL_ENABLED);
+                       if (ret)
+                               return ret;
+               } else {
+                       ret = media_create_pad_link(tuner, TUNER_PAD_OUTPUT,
+                                               decoder, DEMOD_PAD_IF_INPUT,
+                                               MEDIA_LNK_FL_ENABLED);
+                       if (ret)
+                               return ret;
+               }
+
+               if (if_aud) {
+                       ret = media_create_pad_link(tuner, TUNER_PAD_AUD_OUT,
+                                                   if_aud,
+                                                   IF_AUD_DEC_PAD_IF_INPUT,
+                                                   MEDIA_LNK_FL_ENABLED);
+                       if (ret)
+                               return ret;
+               } else {
+                       if_aud = tuner;
+               }
+
+       }
+       ret = media_create_pad_link(decoder, DEMOD_PAD_VID_OUT,
+                                   &v4l2->vdev.entity, 0,
+                                   MEDIA_LNK_FL_ENABLED);
+       if (ret)
+               return ret;
+
+       if (em28xx_vbi_supported(dev)) {
+               ret = media_create_pad_link(decoder, DEMOD_PAD_VBI_OUT,
+                                           &v4l2->vbi_dev.entity, 0,
+                                           MEDIA_LNK_FL_ENABLED);
+               if (ret)
+                       return ret;
+       }
+
+       for (i = 0; i < MAX_EM28XX_INPUT; i++) {
+               struct media_entity *ent = &dev->input_ent[i];
+
+               if (!INPUT(i)->type)
+                       break;
+
+               switch (INPUT(i)->type) {
+               case EM28XX_VMUX_COMPOSITE:
+               case EM28XX_VMUX_SVIDEO:
+                       ret = media_create_pad_link(ent, 0, decoder,
+                                                   DEMOD_PAD_IF_INPUT, 0);
+                       if (ret)
+                               return ret;
+                       break;
+               default: /* EM28XX_VMUX_TELEVISION or EM28XX_RADIO */
+                       if (!tuner)
+                               break;
+
+                       ret = media_create_pad_link(ent, 0, tuner,
+                                                   TUNER_PAD_RF_INPUT,
+                                                   MEDIA_LNK_FL_ENABLED);
+                       if (ret)
+                               return ret;
+                       break;
+               }
+       }
+#endif
+       return 0;
+}
+
+static int em28xx_enable_analog_tuner(struct em28xx *dev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct media_device *mdev = dev->media_dev;
+       struct em28xx_v4l2 *v4l2 = dev->v4l2;
+       struct media_entity *source;
+       struct media_link *link, *found_link = NULL;
+       int ret, active_links = 0;
+
+       if (!mdev || !v4l2->decoder)
+               return 0;
+
+       /*
+        * This will find the tuner that is connected into the decoder.
+        * Technically, this is not 100% correct, as the device may be
+        * using an analog input instead of the tuner. However, as we can't
+        * do DVB streaming while the DMA engine is being used for V4L2,
+        * this should be enough for the actual needs.
+        */
+       list_for_each_entry(link, &v4l2->decoder->links, list) {
+               if (link->sink->entity == v4l2->decoder) {
+                       found_link = link;
+                       if (link->flags & MEDIA_LNK_FL_ENABLED)
+                               active_links++;
+                       break;
+               }
+       }
+
+       if (active_links == 1 || !found_link)
+               return 0;
+
+       source = found_link->source->entity;
+       list_for_each_entry(link, &source->links, list) {
+               struct media_entity *sink;
+               int flags = 0;
+
+               sink = link->sink->entity;
+
+               if (sink == v4l2->decoder)
+                       flags = MEDIA_LNK_FL_ENABLED;
+
+               ret = media_entity_setup_link(link, flags);
+               if (ret) {
+                       pr_err("Couldn't change link %s->%s to %s. Error %d\n",
+                              source->name, sink->name,
+                              flags ? "enabled" : "disabled",
+                              ret);
+                       return ret;
+               } else
+                       em28xx_videodbg("link %s->%s was %s\n",
+                                       source->name, sink->name,
+                                       flags ? "ENABLED" : "disabled");
+       }
+#endif
+       return 0;
+}
+
+static const char * const iname[] = {
+       [EM28XX_VMUX_COMPOSITE]  = "Composite",
+       [EM28XX_VMUX_SVIDEO]     = "S-Video",
+       [EM28XX_VMUX_TELEVISION] = "Television",
+       [EM28XX_RADIO]           = "Radio",
+};
+
+static void em28xx_v4l2_create_entities(struct em28xx *dev)
+{
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       struct em28xx_v4l2 *v4l2 = dev->v4l2;
+       int ret, i;
+
+       /* Initialize Video, VBI and Radio pads */
+       v4l2->video_pad.flags = MEDIA_PAD_FL_SINK;
+       ret = media_entity_pads_init(&v4l2->vdev.entity, 1, &v4l2->video_pad);
+       if (ret < 0)
+               pr_err("failed to initialize video media entity!\n");
+
+       if (em28xx_vbi_supported(dev)) {
+               v4l2->vbi_pad.flags = MEDIA_PAD_FL_SINK;
+               ret = media_entity_pads_init(&v4l2->vbi_dev.entity, 1,
+                                            &v4l2->vbi_pad);
+               if (ret < 0)
+                       pr_err("failed to initialize vbi media entity!\n");
+       }
+
+       /* Webcams don't have input connectors */
+       if (dev->board.is_webcam)
+               return;
+
+       /* Create entities for each input connector */
+       for (i = 0; i < MAX_EM28XX_INPUT; i++) {
+               struct media_entity *ent = &dev->input_ent[i];
+
+               if (!INPUT(i)->type)
+                       break;
+
+               ent->name = iname[INPUT(i)->type];
+               ent->flags = MEDIA_ENT_FL_CONNECTOR;
+               dev->input_pad[i].flags = MEDIA_PAD_FL_SOURCE;
+
+               switch (INPUT(i)->type) {
+               case EM28XX_VMUX_COMPOSITE:
+                       ent->function = MEDIA_ENT_F_CONN_COMPOSITE;
+                       break;
+               case EM28XX_VMUX_SVIDEO:
+                       ent->function = MEDIA_ENT_F_CONN_SVIDEO;
+                       break;
+               default: /* EM28XX_VMUX_TELEVISION or EM28XX_RADIO */
+                       ent->function = MEDIA_ENT_F_CONN_RF;
+                       break;
+               }
+
+               ret = media_entity_pads_init(ent, 1, &dev->input_pad[i]);
+               if (ret < 0)
+                       pr_err("failed to initialize input pad[%d]!\n", i);
+
+               ret = media_device_register_entity(dev->media_dev, ent);
+               if (ret < 0)
+                       pr_err("failed to register input entity %d!\n", i);
+       }
+#endif
+}
+
+
 /* ------------------------------------------------------------------
        Videobuf2 operations
    ------------------------------------------------------------------*/
@@ -884,6 +1152,9 @@ static int queue_setup(struct vb2_queue *vq,
                return sizes[0] < size ? -EINVAL : 0;
        *nplanes = 1;
        sizes[0] = size;
+
+       em28xx_enable_analog_tuner(dev);
+
        return 0;
 }
 
@@ -962,6 +1233,9 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
                        f.type = V4L2_TUNER_ANALOG_TV;
                v4l2_device_call_all(&v4l2->v4l2_dev,
                                     0, tuner, s_frequency, &f);
+
+               /* Enable video stream at TV decoder */
+               v4l2_device_call_all(&v4l2->v4l2_dev, 0, video, s_stream, 1);
        }
 
        v4l2->streaming_users++;
@@ -981,6 +1255,9 @@ static void em28xx_stop_streaming(struct vb2_queue *vq)
        res_free(dev, vq->type);
 
        if (v4l2->streaming_users-- == 1) {
+               /* Disable video stream at TV decoder */
+               v4l2_device_call_all(&v4l2->v4l2_dev, 0, video, s_stream, 0);
+
                /* Last active user, so shutdown all the URBS */
                em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
        }
@@ -1013,6 +1290,9 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq)
        res_free(dev, vq->type);
 
        if (v4l2->streaming_users-- == 1) {
+               /* Disable video stream at TV decoder */
+               v4l2_device_call_all(&v4l2->v4l2_dev, 0, video, s_stream, 0);
+
                /* Last active user, so shutdown all the URBS */
                em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
        }
@@ -1224,6 +1504,12 @@ static void scale_to_size(struct em28xx *dev,
 
        *width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
        *height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
+
+       /* Don't let width or height to be zero */
+       if (*width < 1)
+               *width = 1;
+       if (*height < 1)
+               *height = 1;
 }
 
 /* ------------------------------------------------------------------
@@ -1299,6 +1585,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
                v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
                                      1, 0);
        }
+       /* Avoid division by zero at size_to_scale */
+       if (width < 1)
+               width = 1;
+       if (height < 1)
+               height = 1;
 
        size_to_scale(dev, width, height, &hscale, &vscale);
        scale_to_size(dev, hscale, vscale, &width, &height);
@@ -1434,18 +1725,6 @@ static int vidioc_s_parm(struct file *file, void *priv,
                                          0, video, s_parm, p);
 }
 
-static const char *iname[] = {
-       [EM28XX_VMUX_COMPOSITE1] = "Composite1",
-       [EM28XX_VMUX_COMPOSITE2] = "Composite2",
-       [EM28XX_VMUX_COMPOSITE3] = "Composite3",
-       [EM28XX_VMUX_COMPOSITE4] = "Composite4",
-       [EM28XX_VMUX_SVIDEO]     = "S-Video",
-       [EM28XX_VMUX_TELEVISION] = "Television",
-       [EM28XX_VMUX_CABLE]      = "Cable TV",
-       [EM28XX_VMUX_DVB]        = "DVB",
-       [EM28XX_VMUX_DEBUG]      = "for debug only",
-};
-
 static int vidioc_enum_input(struct file *file, void *priv,
                             struct v4l2_input *i)
 {
@@ -1463,8 +1742,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
 
        strcpy(i->name, iname[INPUT(n)->type]);
 
-       if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
-           (EM28XX_VMUX_CABLE == INPUT(n)->type))
+       if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type))
                i->type = V4L2_INPUT_TYPE_TUNER;
 
        i->std = dev->v4l2->vdev.tvnorms;
@@ -1961,6 +2239,8 @@ static int em28xx_v4l2_fini(struct em28xx *dev)
 
        em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE);
 
+       em28xx_v4l2_media_release(dev);
+
        if (video_is_registered(&v4l2->radio_dev)) {
                em28xx_info("V4L2 device %s deregistered\n",
                            video_device_node_name(&v4l2->radio_dev));
@@ -2284,6 +2564,9 @@ static int em28xx_v4l2_init(struct em28xx *dev)
        v4l2->dev = dev;
        dev->v4l2 = v4l2;
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+       v4l2->v4l2_dev.mdev = dev->media_dev;
+#endif
        ret = v4l2_device_register(&dev->udev->dev, &v4l2->v4l2_dev);
        if (ret < 0) {
                em28xx_errdev("Call to v4l2_device_register() failed!\n");
@@ -2556,6 +2839,16 @@ static int em28xx_v4l2_init(struct em28xx *dev)
                            video_device_node_name(&v4l2->radio_dev));
        }
 
+       /* Init entities at the Media Controller */
+       em28xx_v4l2_create_entities(dev);
+
+       ret = em28xx_v4l2_create_media_graph(dev);
+       if (ret) {
+               em28xx_errdev("failed to create media graph\n");
+               em28xx_v4l2_media_release(dev);
+               goto unregister_dev;
+       }
+
        em28xx_info("V4L2 video device registered as %s\n",
                    video_device_node_name(&v4l2->vdev));
 
@@ -2577,6 +2870,22 @@ static int em28xx_v4l2_init(struct em28xx *dev)
        return 0;
 
 unregister_dev:
+       if (video_is_registered(&v4l2->radio_dev)) {
+               em28xx_info("V4L2 device %s deregistered\n",
+                           video_device_node_name(&v4l2->radio_dev));
+               video_unregister_device(&v4l2->radio_dev);
+       }
+       if (video_is_registered(&v4l2->vbi_dev)) {
+               em28xx_info("V4L2 device %s deregistered\n",
+                           video_device_node_name(&v4l2->vbi_dev));
+               video_unregister_device(&v4l2->vbi_dev);
+       }
+       if (video_is_registered(&v4l2->vdev)) {
+               em28xx_info("V4L2 device %s deregistered\n",
+                           video_device_node_name(&v4l2->vdev));
+               video_unregister_device(&v4l2->vdev);
+       }
+
        v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
        v4l2_device_unregister(&v4l2->v4l2_dev);
 err:
index 8ff066c977d9d3e88b3e32b05cfbd7c6974afaf4..2674449617757a92ec2cd97b9b407f60a32a0a63 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef _EM28XX_H
 #define _EM28XX_H
 
-#define EM28XX_VERSION "0.2.1"
+#define EM28XX_VERSION "0.2.2"
 #define DRIVER_DESC    "Empia em28xx device driver"
 
 #include <linux/workqueue.h>
@@ -291,15 +291,9 @@ struct em28xx_dmaqueue {
 
 #define MAX_EM28XX_INPUT 4
 enum enum28xx_itype {
-       EM28XX_VMUX_COMPOSITE1 = 1,
-       EM28XX_VMUX_COMPOSITE2,
-       EM28XX_VMUX_COMPOSITE3,
-       EM28XX_VMUX_COMPOSITE4,
+       EM28XX_VMUX_COMPOSITE = 1,
        EM28XX_VMUX_SVIDEO,
        EM28XX_VMUX_TELEVISION,
-       EM28XX_VMUX_CABLE,
-       EM28XX_VMUX_DVB,
-       EM28XX_VMUX_DEBUG,
        EM28XX_RADIO,
 };
 
@@ -558,6 +552,11 @@ struct em28xx_v4l2 {
        bool top_field;
        int vbi_read;
        unsigned int field_count;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct media_pad video_pad, vbi_pad;
+       struct media_entity *decoder;
+#endif
 };
 
 struct em28xx_audio {
@@ -718,6 +717,12 @@ struct em28xx {
        /* Snapshot button input device */
        char snapshot_button_path[30];  /* path of the input dev */
        struct input_dev *sbutton_input_dev;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+       struct media_device *media_dev;
+       struct media_entity input_ent[MAX_EM28XX_INPUT];
+       struct media_pad input_pad[MAX_EM28XX_INPUT];
+#endif
 };
 
 #define kref_to_dev(d) container_of(d, struct em28xx, ref)
index 745185eb060b5b4c104b220add58a89cac0d23b9..bebee8ca9981f85b05b46162f693aa87c4e28da1 100644 (file)
@@ -250,7 +250,7 @@ struct go7007 {
        struct i2c_adapter i2c_adapter;
 
        /* HPI driver */
-       struct go7007_hpi_ops *hpi_ops;
+       const struct go7007_hpi_ops *hpi_ops;
        void *hpi_context;
        int interrupt_available;
        wait_queue_head_t interrupt_waitq;
index 3dbf14c85c5c847ef8544ec78b96936b76677fd4..14d3f8c1ce4a4135193dab8b263dac34d2d9fe03 100644 (file)
@@ -932,7 +932,7 @@ static void go7007_usb_release(struct go7007 *go)
        kfree(go->hpi_context);
 }
 
-static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
+static const struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
        .interface_reset        = go7007_usb_interface_reset,
        .write_interrupt        = go7007_usb_ezusb_write_interrupt,
        .read_interrupt         = go7007_usb_read_interrupt,
@@ -942,7 +942,7 @@ static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
        .release                = go7007_usb_release,
 };
 
-static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
+static const struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
        .interface_reset        = go7007_usb_interface_reset,
        .write_interrupt        = go7007_usb_onboard_write_interrupt,
        .read_interrupt         = go7007_usb_read_interrupt,
index 3fc64197b4e6a6475c89b61d580bf3a4317e4b35..08f0ca7aa012e9bb4b335dd27fb3fc401717f8d6 100644 (file)
@@ -273,7 +273,9 @@ static int hdpvr_probe(struct usb_interface *interface,
        struct hdpvr_device *dev;
        struct usb_host_interface *iface_desc;
        struct usb_endpoint_descriptor *endpoint;
+#if IS_ENABLED(CONFIG_I2C)
        struct i2c_client *client;
+#endif
        size_t buffer_size;
        int i;
        int retval = -ENOMEM;
index 7dee22deebf3d8b5c85ca95a39e7cb30935b1885..ba7f02270c8391f3d8bc939bcd0af4acd23e837f 100644 (file)
@@ -462,10 +462,8 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
                        }
 
                        if (wait_event_interruptible(dev->wait_data,
-                                             buf->status == BUFSTAT_READY)) {
-                               ret = -ERESTARTSYS;
-                               goto err;
-                       }
+                                             buf->status == BUFSTAT_READY))
+                               return -ERESTARTSYS;
                }
 
                if (buf->status != BUFSTAT_READY)
index c104315fdc17217f4fad27b6c86e017fa126b7b2..2d33033682af3635a1237d14e0bef045185e7ef0 100644 (file)
@@ -839,8 +839,6 @@ static int msi2500_set_usb_adc(struct msi2500_dev *dev)
                goto err;
 
        ret = msi2500_ctrl_msg(dev, CMD_WREG, reg3);
-       if (ret)
-               goto err;
 err:
        return ret;
 }
index 086cf1c7bd7d19e0015950bd6af0d02c311bf090..18aed5dd325e024e1db0860ba954ae75ef50fa7e 100644 (file)
@@ -91,6 +91,7 @@ static const struct usb_device_id pwc_device_table [] = {
        { USB_DEVICE(0x0471, 0x0312) },
        { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
        { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
+       { USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC PC Camera */
        { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
        { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
        { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
@@ -810,6 +811,11 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
                        name = "Philips SPC 900NC webcam";
                        type_id = 740;
                        break;
+               case 0x032C:
+                       PWC_INFO("Philips SPC 880NC USB webcam detected.\n");
+                       name = "Philips SPC 880NC webcam";
+                       type_id = 740;
+                       break;
                default:
                        return -ENODEV;
                        break;
index 46191d5262eb07f3efb9fdf87c75c0665abe6687..6ecb0b48423f3d411cb0874c9c159727241eb3bd 100644 (file)
@@ -98,7 +98,6 @@ void stk1160_buffer_done(struct stk1160 *dev)
 
        buf->vb.sequence = dev->sequence++;
        buf->vb.field = V4L2_FIELD_INTERLACED;
-       buf->vb.vb2_buf.planes[0].bytesused = buf->bytesused;
        buf->vb.vb2_buf.timestamp = ktime_get_ns();
 
        vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->bytesused);
index 4ebb33943f9a03a5922c408cfef628847a1053d7..f6cfad46547ef5951923e95d4005aa3f317c1e56 100644 (file)
@@ -312,20 +312,24 @@ static void usbtv_image_chunk(struct usbtv *usbtv, __be32 *chunk)
        usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);
        usbtv->chunks_done++;
 
-       /* Last chunk in a frame, signalling an end */
-       if (odd && chunk_no == usbtv->n_chunks-1) {
-               int size = vb2_plane_size(&buf->vb.vb2_buf, 0);
-               enum vb2_buffer_state state = usbtv->chunks_done ==
-                                               usbtv->n_chunks ?
-                                               VB2_BUF_STATE_DONE :
-                                               VB2_BUF_STATE_ERROR;
-
-               buf->vb.field = V4L2_FIELD_INTERLACED;
-               buf->vb.sequence = usbtv->sequence++;
-               buf->vb.vb2_buf.timestamp = ktime_get_ns();
-               vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
-               vb2_buffer_done(&buf->vb.vb2_buf, state);
-               list_del(&buf->list);
+       /* Last chunk in a field */
+       if (chunk_no == usbtv->n_chunks-1) {
+               /* Last chunk in a frame, signalling an end */
+               if (odd && !usbtv->last_odd) {
+                       int size = vb2_plane_size(&buf->vb.vb2_buf, 0);
+                       enum vb2_buffer_state state = usbtv->chunks_done ==
+                               usbtv->n_chunks ?
+                               VB2_BUF_STATE_DONE :
+                               VB2_BUF_STATE_ERROR;
+
+                       buf->vb.field = V4L2_FIELD_INTERLACED;
+                       buf->vb.sequence = usbtv->sequence++;
+                       buf->vb.vb2_buf.timestamp = ktime_get_ns();
+                       vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
+                       vb2_buffer_done(&buf->vb.vb2_buf, state);
+                       list_del(&buf->list);
+               }
+               usbtv->last_odd = odd;
        }
 
        spin_unlock_irqrestore(&usbtv->buflock, flags);
@@ -389,6 +393,10 @@ static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv)
        ip->transfer_flags = URB_ISO_ASAP;
        ip->transfer_buffer = kzalloc(size * USBTV_ISOC_PACKETS,
                                                GFP_KERNEL);
+       if (!ip->transfer_buffer) {
+               usb_free_urb(ip);
+               return NULL;
+       }
        ip->complete = usbtv_iso_cb;
        ip->number_of_packets = USBTV_ISOC_PACKETS;
        ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS;
@@ -639,6 +647,7 @@ static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)
        if (usbtv->udev == NULL)
                return -ENODEV;
 
+       usbtv->last_odd = 1;
        usbtv->sequence = 0;
        return usbtv_start(usbtv);
 }
index 19cb8bf7c4e9b3c8befe5d82597ec2fdb8b258c7..161b38d5cfa0463e939af70fdfddfeb48510980e 100644 (file)
@@ -95,6 +95,7 @@ struct usbtv {
        int width, height;
        int n_chunks;
        int iso_size;
+       int last_odd;
        unsigned int sequence;
        struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
 
index de9ff3bb8edd8e7a94826bf58895d009dc420038..12f5ebbd0436e770022e7501a80f5dda7849f9a1 100644 (file)
@@ -162,8 +162,7 @@ MODULE_ALIAS(DRIVER_ALIAS);
 
 static inline struct usb_usbvision *cd_to_usbvision(struct device *cd)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        return video_get_drvdata(vdev);
 }
 
@@ -177,8 +176,7 @@ static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
 static ssize_t show_model(struct device *cd,
                          struct device_attribute *attr, char *buf)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        return sprintf(buf, "%s\n",
                       usbvision_device_data[usbvision->dev_model].model_string);
@@ -188,8 +186,7 @@ static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
 static ssize_t show_hue(struct device *cd,
                        struct device_attribute *attr, char *buf)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        struct v4l2_control ctrl;
        ctrl.id = V4L2_CID_HUE;
@@ -203,8 +200,7 @@ static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
 static ssize_t show_contrast(struct device *cd,
                             struct device_attribute *attr, char *buf)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        struct v4l2_control ctrl;
        ctrl.id = V4L2_CID_CONTRAST;
@@ -218,8 +214,7 @@ static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
 static ssize_t show_brightness(struct device *cd,
                               struct device_attribute *attr, char *buf)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        struct v4l2_control ctrl;
        ctrl.id = V4L2_CID_BRIGHTNESS;
@@ -233,8 +228,7 @@ static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
 static ssize_t show_saturation(struct device *cd,
                               struct device_attribute *attr, char *buf)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        struct v4l2_control ctrl;
        ctrl.id = V4L2_CID_SATURATION;
@@ -248,8 +242,7 @@ static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
 static ssize_t show_streaming(struct device *cd,
                              struct device_attribute *attr, char *buf)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        return sprintf(buf, "%s\n",
                       YES_NO(usbvision->streaming == stream_on ? 1 : 0));
@@ -259,8 +252,7 @@ static DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);
 static ssize_t show_compression(struct device *cd,
                                struct device_attribute *attr, char *buf)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        return sprintf(buf, "%s\n",
                       YES_NO(usbvision->isoc_mode == ISOC_MODE_COMPRESS));
@@ -270,8 +262,7 @@ static DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);
 static ssize_t show_device_bridge(struct device *cd,
                                  struct device_attribute *attr, char *buf)
 {
-       struct video_device *vdev =
-               container_of(cd, struct video_device, dev);
+       struct video_device *vdev = to_video_device(cd);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        return sprintf(buf, "%d\n", usbvision->bridge_type);
 }
@@ -1156,6 +1147,7 @@ static int usbvision_radio_close(struct file *file)
        usbvision_audio_off(usbvision);
        usbvision->radio = 0;
        usbvision->user--;
+       mutex_unlock(&usbvision->v4l2_lock);
 
        if (usbvision->remove_pending) {
                printk(KERN_INFO "%s: Final disconnect\n", __func__);
@@ -1164,7 +1156,6 @@ static int usbvision_radio_close(struct file *file)
                return 0;
        }
 
-       mutex_unlock(&usbvision->v4l2_lock);
        PDEBUG(DBG_IO, "success");
        return v4l2_fh_release(file);
 }
index 9beece00869bf0e27a99fc641b8f926c0d3bad8f..29b3436d0910fbd0c1a591b0aea408dc34aca74a 100644 (file)
@@ -37,7 +37,6 @@ config VIDEO_PCI_SKELETON
 # Used by drivers that need tuner.ko
 config VIDEO_TUNER
        tristate
-       depends on MEDIA_TUNER
 
 # Used by drivers that need v4l2-mem2mem.ko
 config V4L2_MEM2MEM_DEV
index 76496fd282aa532da3e84960ea7dddeedc013ccf..731487be5baa993147206ec8f85242cd20dbbc91 100644 (file)
@@ -696,16 +696,32 @@ static int tuner_probe(struct i2c_client *client,
        /* Should be just before return */
 register_client:
 #if defined(CONFIG_MEDIA_CONTROLLER)
-       t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
-       t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
-       t->sd.entity.function = MEDIA_ENT_F_TUNER;
        t->sd.entity.name = t->name;
+       /*
+        * Handle the special case where the tuner has actually
+        * two stages: the PLL to tune into a frequency and the
+        * IF-PLL demodulator (tda988x).
+        */
+       if (t->type == TUNER_TDA9887) {
+               t->pad[IF_VID_DEC_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+               t->pad[IF_VID_DEC_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
+               ret = media_entity_pads_init(&t->sd.entity,
+                                            IF_VID_DEC_PAD_NUM_PADS,
+                                            &t->pad[0]);
+               t->sd.entity.function = MEDIA_ENT_F_IF_VID_DECODER;
+       } else {
+               t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
+               t->pad[TUNER_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
+               t->pad[TUNER_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE;
+               ret = media_entity_pads_init(&t->sd.entity, TUNER_NUM_PADS,
+                                            &t->pad[0]);
+               t->sd.entity.function = MEDIA_ENT_F_TUNER;
+       }
 
-       ret = media_entity_pads_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]);
        if (ret < 0) {
                tuner_err("failed to initialize media entity!\n");
                kfree(t);
-               return -ENODEV;
+               return ret;
        }
 #endif
        /* Sets a default mode */
index 8fd84a67478a77423cc6bc051e0654276561502c..019644ff627d775f7f4b67e29b46baab9dadabbf 100644 (file)
@@ -415,7 +415,8 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
                get_user(kp->index, &up->index) ||
                get_user(kp->type, &up->type) ||
                get_user(kp->flags, &up->flags) ||
-               get_user(kp->memory, &up->memory))
+               get_user(kp->memory, &up->memory) ||
+               get_user(kp->length, &up->length))
                        return -EFAULT;
 
        if (V4L2_TYPE_IS_OUTPUT(kp->type))
@@ -427,9 +428,6 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
                        return -EFAULT;
 
        if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
-               if (get_user(kp->length, &up->length))
-                       return -EFAULT;
-
                num_planes = kp->length;
                if (num_planes == 0) {
                        kp->m.planes = NULL;
@@ -462,16 +460,14 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
        } else {
                switch (kp->memory) {
                case V4L2_MEMORY_MMAP:
-                       if (get_user(kp->length, &up->length) ||
-                               get_user(kp->m.offset, &up->m.offset))
+                       if (get_user(kp->m.offset, &up->m.offset))
                                return -EFAULT;
                        break;
                case V4L2_MEMORY_USERPTR:
                        {
                        compat_long_t tmp;
 
-                       if (get_user(kp->length, &up->length) ||
-                           get_user(tmp, &up->m.userptr))
+                       if (get_user(tmp, &up->m.userptr))
                                return -EFAULT;
 
                        kp->m.userptr = (unsigned long)compat_ptr(tmp);
@@ -513,7 +509,8 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
                copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
                put_user(kp->sequence, &up->sequence) ||
                put_user(kp->reserved2, &up->reserved2) ||
-               put_user(kp->reserved, &up->reserved))
+               put_user(kp->reserved, &up->reserved) ||
+               put_user(kp->length, &up->length))
                        return -EFAULT;
 
        if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
@@ -536,13 +533,11 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
        } else {
                switch (kp->memory) {
                case V4L2_MEMORY_MMAP:
-                       if (put_user(kp->length, &up->length) ||
-                               put_user(kp->m.offset, &up->m.offset))
+                       if (put_user(kp->m.offset, &up->m.offset))
                                return -EFAULT;
                        break;
                case V4L2_MEMORY_USERPTR:
-                       if (put_user(kp->length, &up->length) ||
-                               put_user(kp->m.userptr, &up->m.userptr))
+                       if (put_user(kp->m.userptr, &up->m.userptr))
                                return -EFAULT;
                        break;
                case V4L2_MEMORY_OVERLAY:
index ec258b73001a26a96dcdb56d8c76e64b5762f1d9..889de0a321529ace36560ddabd682b74f080de8d 100644 (file)
@@ -165,7 +165,8 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
            bt->width > cap->max_width ||
            bt->pixelclock < cap->min_pixelclock ||
            bt->pixelclock > cap->max_pixelclock ||
-           (cap->standards && bt->standards &&
+           (!(caps & V4L2_DV_BT_CAP_CUSTOM) &&
+            cap->standards && bt->standards &&
             !(bt->standards & cap->standards)) ||
            (bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) ||
            (!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE)))
index b27cbb1f5afe734dd3b17b4e64ac40d1b2871276..93b33681776ca427703dee8bbf6616cca95d7938 100644 (file)
@@ -146,7 +146,7 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node,
  * variable without a low fixed limit. Please use
  * v4l2_of_alloc_parse_endpoint() in new drivers instead.
  *
- * Return: 0.
+ * Return: 0 on success or a negative error code on failure.
  */
 int v4l2_of_parse_endpoint(const struct device_node *node,
                           struct v4l2_of_endpoint *endpoint)
index ff8953ae52d142e654f30548d5ddf7bf08c45690..dab94080ec3ae80941b275d2a226dfe777066b86 100644 (file)
@@ -1227,6 +1227,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const void *pb)
                if (planes[plane].length < vb->planes[plane].min_length) {
                        dprintk(1, "invalid dmabuf length for plane %d\n",
                                plane);
+                       dma_buf_put(dbuf);
                        ret = -EINVAL;
                        goto err;
                }
index 7b7e7b26c1e8c525699c04451302586a36bc001a..3cc9be776f8b7a658acc0c1565afed3b39ced7ca 100644 (file)
@@ -538,7 +538,7 @@ struct vpfe_isif_raw_config {
 };
 
 /**********************************************************************
-      IPIPE API Structures
+*      IPIPE API Structures
 **********************************************************************/
 
 /* IPIPE module configurations */
index d009bcb439f0677c977d0af1bc3315797c2bf9fa..68ede6c56e6d2207da0752c38244a70655ed739d 100644 (file)
@@ -193,7 +193,7 @@ static int lirc_claim(void)
                        return 0;
                }
        }
-       out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
+       out(LIRC_LP_CONTROL, LP_PSELECP | LP_PINITP);
        is_claimed = 1;
        return 1;
 }
@@ -264,7 +264,7 @@ static void lirc_lirc_irq_handler(void *blah)
                init = 1;
        }
 
-       timeout = timer/10;     /* timeout after 1/10 sec. */
+       timeout = timer / 10;   /* timeout after 1/10 sec. */
        signal = 1;
        level = lirc_get_timer();
        do {
@@ -286,15 +286,15 @@ static void lirc_lirc_irq_handler(void *blah)
                /* adjust value to usecs */
                __u64 helper;
 
-               helper = ((__u64) signal)*1000000;
+               helper = ((__u64)signal) * 1000000;
                do_div(helper, timer);
-               signal = (long) helper;
+               signal = (long)helper;
 
                if (signal > LIRC_SFH506_DELAY)
                        data = signal - LIRC_SFH506_DELAY;
                else
                        data = 1;
-               rbuf_write(PULSE_BIT|data); /* pulse */
+               rbuf_write(PULSE_BIT | data); /* pulse */
        }
        lastkt = ktime_get();
 #else
@@ -331,7 +331,7 @@ static ssize_t lirc_read(struct file *filep, char __user *buf, size_t n,
        set_current_state(TASK_INTERRUPTIBLE);
        while (count < n) {
                if (rptr != wptr) {
-                       if (copy_to_user(buf+count, &rbuf[rptr],
+                       if (copy_to_user(buf + count, &rbuf[rptr],
                                         sizeof(int))) {
                                result = -EFAULT;
                                break;
@@ -393,9 +393,9 @@ static ssize_t lirc_write(struct file *filep, const char __user *buf, size_t n,
        for (i = 0; i < count; i++) {
                __u64 helper;
 
-               helper = ((__u64) wbuf[i])*timer;
+               helper = ((__u64)wbuf[i]) * timer;
                do_div(helper, 1000000);
-               wbuf[i] = (int) helper;
+               wbuf[i] = (int)helper;
        }
 
        local_irq_save(flags);
@@ -647,7 +647,7 @@ static int __init lirc_parallel_init(void)
                goto exit_device_put;
 
        pport = parport_find_base(io);
-       if (pport == NULL) {
+       if (!pport) {
                pr_notice("no port at %x found\n", io);
                result = -ENXIO;
                goto exit_device_put;
@@ -656,7 +656,7 @@ static int __init lirc_parallel_init(void)
                                           pf, kf, lirc_lirc_irq_handler, 0,
                                           NULL);
        parport_put_port(pport);
-       if (ppdevice == NULL) {
+       if (!ppdevice) {
                pr_notice("parport_register_device() failed\n");
                result = -ENXIO;
                goto exit_device_put;
@@ -664,7 +664,7 @@ static int __init lirc_parallel_init(void)
        if (parport_claim(ppdevice) != 0)
                goto skip_init;
        is_claimed = 1;
-       out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP);
+       out(LIRC_LP_CONTROL, LP_PSELECP | LP_PINITP);
 
 #ifdef LIRC_TIMER
        if (debug)
@@ -730,7 +730,7 @@ module_param(irq, int, S_IRUGO);
 MODULE_PARM_DESC(irq, "Interrupt (7 or 5)");
 
 module_param(tx_mask, int, S_IRUGO);
-MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)");
+MODULE_PARM_DESC(tx_mask, "Transmitter mask (default: 0x01)");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Enable debugging messages");
index e5321fda548935e1bab99fbce565dc7a018d52e9..b3edc14e763f020cf4500d0965d118cc572b3569 100644 (file)
 #ifdef __KERNEL__
 
 #include <linux/videodev2.h>
-
-/* Tuner PADs */
-/* FIXME: is this the right place for it? */
-enum tuner_pad_index {
-       TUNER_PAD_RF_INPUT,
-       TUNER_PAD_IF_OUTPUT,
-       TUNER_NUM_PADS
-};
+#include <media/v4l2-mc.h>
 
 #define ADDR_UNSET (255)
 
diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h
new file mode 100644 (file)
index 0000000..df11519
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * v4l2-mc.h - Media Controller V4L2 types and prototypes
+ *
+ * Copyright (C) 2016 Mauro Carvalho Chehab <mchehab@osg.samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/**
+ * enum tuner_pad_index - tuner pad index for MEDIA_ENT_F_TUNER
+ *
+ * @TUNER_PAD_RF_INPUT:        Radiofrequency (RF) sink pad, usually linked to a
+ *                     RF connector entity.
+ * @TUNER_PAD_OUTPUT:  Tuner video output source pad. Contains the video
+ *                     chrominance and luminance or the hole bandwidth
+ *                     of the signal converted to an Intermediate Frequency
+ *                     (IF) or to baseband (on zero-IF tuners).
+ * @TUNER_PAD_AUD_OUT: Tuner audio output source pad. Tuners used to decode
+ *                     analog TV signals have an extra pad for audio output.
+ *                     Old tuners use an analog stage with a saw filter for
+ *                     the audio IF frequency. The output of the pad is, in
+ *                     this case, the audio IF, with should be decoded either
+ *                     by the bridge chipset (that's the case of cx2388x
+ *                     chipsets) or may require an external IF sound
+ *                     processor, like msp34xx. On modern silicon tuners,
+ *                     the audio IF decoder is usually incorporated at the
+ *                     tuner. On such case, the output of this pad is an
+ *                     audio sampled data.
+ * @TUNER_NUM_PADS:    Number of pads of the tuner.
+ */
+enum tuner_pad_index {
+       TUNER_PAD_RF_INPUT,
+       TUNER_PAD_OUTPUT,
+       TUNER_PAD_AUD_OUT,
+       TUNER_NUM_PADS
+};
+
+/**
+ * enum if_vid_dec_index - video IF-PLL pad index for
+ *                        MEDIA_ENT_F_IF_VID_DECODER
+ *
+ * @IF_VID_DEC_PAD_IF_INPUT:   video Intermediate Frequency (IF) sink pad
+ * @IF_VID_DEC_PAD_OUT:                IF-PLL video output source pad. Contains the
+ *                             video chrominance and luminance IF signals.
+ * @IF_VID_DEC_PAD_NUM_PADS:   Number of pads of the video IF-PLL.
+ */
+enum if_vid_dec_pad_index {
+       IF_VID_DEC_PAD_IF_INPUT,
+       IF_VID_DEC_PAD_OUT,
+       IF_VID_DEC_PAD_NUM_PADS
+};
+
+/**
+ * enum if_aud_dec_index - audio/sound IF-PLL pad index for
+ *                        MEDIA_ENT_F_IF_AUD_DECODER
+ *
+ * @IF_AUD_DEC_PAD_IF_INPUT:   audio Intermediate Frequency (IF) sink pad
+ * @IF_AUD_DEC_PAD_OUT:                IF-PLL audio output source pad. Contains the
+ *                             audio sampled stream data, usually connected
+ *                             to the bridge bus via an Inter-IC Sound (I2S)
+ *                             bus.
+ * @IF_AUD_DEC_PAD_NUM_PADS:   Number of pads of the audio IF-PLL.
+ */
+enum if_aud_dec_pad_index {
+       IF_AUD_DEC_PAD_IF_INPUT,
+       IF_AUD_DEC_PAD_OUT,
+       IF_AUD_DEC_PAD_NUM_PADS
+};
+
+/**
+ * enum demod_pad_index - analog TV pad index for MEDIA_ENT_F_ATV_DECODER
+ *
+ * @DEMOD_PAD_IF_INPUT:        IF input sink pad.
+ * @DEMOD_PAD_VID_OUT: Video output source pad.
+ * @DEMOD_PAD_VBI_OUT: Vertical Blank Interface (VBI) output source pad.
+ * @DEMOD_NUM_PADS:    Maximum number of output pads.
+ */
+enum demod_pad_index {
+       DEMOD_PAD_IF_INPUT,
+       DEMOD_PAD_VID_OUT,
+       DEMOD_PAD_VBI_OUT,
+       DEMOD_NUM_PADS
+};
index 1e3c8cb43bd7ac61650da4b6e31ab854af4a7b89..c9eb42a6c0210fa1f075cc294c70516d18dc17f8 100644 (file)
@@ -88,6 +88,15 @@ struct media_device_info {
 #define MEDIA_ENT_F_IO_VBI             (MEDIA_ENT_F_BASE + 32)
 #define MEDIA_ENT_F_IO_SWRADIO         (MEDIA_ENT_F_BASE + 33)
 
+/*
+ * Analog TV IF-PLL decoders
+ *
+ * It is a responsibility of the master/bridge drivers to create links
+ * for MEDIA_ENT_F_IF_VID_DECODER and MEDIA_ENT_F_IF_AUD_DECODER.
+ */
+#define MEDIA_ENT_F_IF_VID_DECODER     (MEDIA_ENT_F_BASE + 41)
+#define MEDIA_ENT_F_IF_AUD_DECODER     (MEDIA_ENT_F_BASE + 42)
+
 /*
  * Don't touch on those. The ranges MEDIA_ENT_F_OLD_BASE and
  * MEDIA_ENT_F_OLD_SUBDEV_BASE are kept to keep backward compatibility
@@ -107,8 +116,12 @@ struct media_device_info {
 #define MEDIA_ENT_F_LENS               (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3)
 #define MEDIA_ENT_F_ATV_DECODER                (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4)
 /*
- * It is a responsibility of the entity drivers to add connectors and links
- *     for the tuner entities.
+ * It is a responsibility of the master/bridge drivers to add connectors
+ * and links for MEDIA_ENT_F_TUNER. Please notice that some old tuners
+ * may require the usage of separate I2C chips to decode analog TV signals,
+ * when the master/bridge chipset doesn't have its own TV standard decoder.
+ * On such cases, the IF-PLL staging is mapped via one or two entities:
+ * MEDIA_ENT_F_IF_VID_DECODER and/or MEDIA_ENT_F_IF_AUD_DECODER.
  */
 #define MEDIA_ENT_F_TUNER              (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5)
 
@@ -286,7 +299,7 @@ struct media_links_enum {
  *       later, before the adding this API upstream.
  */
 
-#if 0 /* Let's postpone it to Kernel 4.6 */
+
 struct media_v2_entity {
        __u32 id;
        char name[64];          /* FIXME: move to a property? (RFC says so) */
@@ -351,7 +364,6 @@ static inline void __user *media_get_uptr(__u64 arg)
 {
        return (void __user *)(uintptr_t)arg;
 }
-#endif
 
 /* ioctls */
 
@@ -359,9 +371,6 @@ static inline void __user *media_get_uptr(__u64 arg)
 #define MEDIA_IOC_ENUM_ENTITIES                _IOWR('|', 0x01, struct media_entity_desc)
 #define MEDIA_IOC_ENUM_LINKS           _IOWR('|', 0x02, struct media_links_enum)
 #define MEDIA_IOC_SETUP_LINK           _IOWR('|', 0x03, struct media_link_desc)
-
-#if 0 /* Let's postpone it to Kernel 4.6 */
 #define MEDIA_IOC_G_TOPOLOGY           _IOWR('|', 0x04, struct media_v2_topology)
-#endif
 
 #endif /* __LINUX_MEDIA_H */
index 15273987093e41e7823f98a953f088332db066aa..5b3f685a2d50ca2146e579f81580aecb61f19922 100644 (file)
  * Copyright (C) 2012 Nokia Corporation
  * Contact: Sakari Ailus <sakari.ailus@iki.fi>
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
+ *  Alternatively you can redistribute this file under the terms of the
+ *  BSD license as stated below:
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *  3. The names of its contributors may not be used to endorse or promote
+ *     products derived from this software without specific prior written
+ *     permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */