Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Dec 2012 03:22:22 +0000 (19:22 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Dec 2012 03:22:22 +0000 (19:22 -0800)
Pull media updates from Mauro Carvalho Chehab:

 - Missing MAINTAINERS entries were added for several drivers

 - Adds V4L2 support for DMABUF handling, allowing zero-copy buffer
   sharing between V4L2 devices and GPU

 - Got rid of all warnings when compiling with W=1 on x86

 - Add a new driver for Exynos hardware (s3c-camif)

 - Several bug fixes, cleanups and driver improvements

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (243 commits)
  [media] omap3isp: Replace cpu_is_omap3630() with ISP revision check
  [media] omap3isp: Prepare/unprepare clocks before/after enable/disable
  [media] omap3isp: preview: Add support for 8-bit formats at the sink pad
  [media] omap3isp: Replace printk with dev_*
  [media] omap3isp: Find source pad from external entity
  [media] omap3isp: Configure CSI-2 phy based on platform data
  [media] omap3isp: Add PHY routing configuration
  [media] omap3isp: Add CSI configuration registers from control block to ISP resources
  [media] omap3isp: Remove unneeded module memory address definitions
  [media] omap3isp: Use monotonic timestamps for statistics buffers
  [media] uvcvideo: Fix control value clamping for unsigned integer controls
  [media] uvcvideo: Mark first output terminal as default video node
  [media] uvcvideo: Add VIDIOC_[GS]_PRIORITY support
  [media] uvcvideo: Return -ENOTTY for unsupported ioctls
  [media] uvcvideo: Set device_caps in VIDIOC_QUERYCAP
  [media] uvcvideo: Don't fail when an unsupported format is requested
  [media] uvcvideo: Return -EACCES when trying to access a read/write-only control
  [media] uvcvideo: Set error_idx properly for extended controls API failures
  [media] rtl28xxu: add NOXON DAB/DAB+ USB dongle rev 2
  [media] fc2580: write some registers conditionally
  ...

314 files changed:
Documentation/DocBook/media/v4l/compat.xml
Documentation/DocBook/media/v4l/io.xml
Documentation/DocBook/media/v4l/v4l2.xml
Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
Documentation/DocBook/media/v4l/vidioc-expbuf.xml [new file with mode: 0644]
Documentation/DocBook/media/v4l/vidioc-qbuf.xml
Documentation/DocBook/media/v4l/vidioc-reqbufs.xml
MAINTAINERS
arch/arm/mach-omap2/devices.c
arch/arm/mach-pxa/pcm990-baseboard.c
drivers/base/dma-mapping.c
drivers/hid/hid-picolcd_cir.c
drivers/media/common/Kconfig
drivers/media/common/b2c2/Kconfig
drivers/media/common/siano/Kconfig
drivers/media/common/siano/Makefile
drivers/media/common/siano/smscoreapi.c
drivers/media/common/siano/smsir.c
drivers/media/common/siano/smsir.h
drivers/media/dvb-core/dmxdev.c
drivers/media/dvb-core/dmxdev.h
drivers/media/dvb-core/dvb-usb-ids.h
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-frontends/cx22700.c
drivers/media/dvb-frontends/cx24123.c
drivers/media/dvb-frontends/dib9000.h
drivers/media/dvb-frontends/drxd_hard.c
drivers/media/dvb-frontends/drxk_hard.c
drivers/media/dvb-frontends/drxk_hard.h
drivers/media/dvb-frontends/ds3000.c
drivers/media/dvb-frontends/l64781.c
drivers/media/dvb-frontends/mt312.c
drivers/media/dvb-frontends/rtl2830.c
drivers/media/dvb-frontends/rtl2832.c
drivers/media/dvb-frontends/stb0899_drv.c
drivers/media/dvb-frontends/stv0367.c
drivers/media/dvb-frontends/tda10071.c
drivers/media/dvb-frontends/tda18271c2dd.c
drivers/media/firewire/firedtv.h
drivers/media/i2c/adp1653.c
drivers/media/i2c/adv7183.c
drivers/media/i2c/adv7604.c
drivers/media/i2c/cx25840/cx25840-core.c
drivers/media/i2c/ir-kbd-i2c.c
drivers/media/i2c/s5k4ecgx.c
drivers/media/i2c/smiapp-pll.c
drivers/media/i2c/smiapp-pll.h
drivers/media/i2c/smiapp/smiapp-core.c
drivers/media/i2c/smiapp/smiapp-limits.c
drivers/media/i2c/smiapp/smiapp-limits.h
drivers/media/i2c/smiapp/smiapp-quirk.c
drivers/media/i2c/smiapp/smiapp-quirk.h
drivers/media/i2c/smiapp/smiapp-reg-defs.h
drivers/media/i2c/smiapp/smiapp-reg.h
drivers/media/i2c/smiapp/smiapp-regs.c
drivers/media/i2c/smiapp/smiapp-regs.h
drivers/media/i2c/smiapp/smiapp.h
drivers/media/i2c/soc_camera/mt9v022.c
drivers/media/i2c/soc_camera/ov2640.c
drivers/media/i2c/vs6624.c
drivers/media/mmc/siano/Kconfig
drivers/media/pci/bt8xx/bttv-driver.c
drivers/media/pci/cx18/cx18-alsa-main.c
drivers/media/pci/cx18/cx18-alsa-pcm.c
drivers/media/pci/cx18/cx18-i2c.c
drivers/media/pci/cx18/cx18-streams.c
drivers/media/pci/cx23885/altera-ci.c
drivers/media/pci/cx23885/cimax2.c
drivers/media/pci/cx23885/cx23885-alsa.c
drivers/media/pci/cx23885/cx23885-av.c
drivers/media/pci/cx23885/cx23885-cards.c
drivers/media/pci/cx23885/cx23885-core.c
drivers/media/pci/cx23885/cx23885-dvb.c
drivers/media/pci/cx23885/cx23885-f300.c
drivers/media/pci/cx23885/cx23885-input.c
drivers/media/pci/cx23885/cx23885-input.h
drivers/media/pci/cx23885/cx23885-ioctl.c
drivers/media/pci/cx23885/cx23885-ir.c
drivers/media/pci/cx23885/cx23888-ir.c
drivers/media/pci/cx23885/netup-init.c
drivers/media/pci/cx25821/cx25821-audio-upstream.c
drivers/media/pci/cx25821/cx25821-biffuncs.h
drivers/media/pci/cx25821/cx25821-i2c.c
drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c
drivers/media/pci/cx25821/cx25821-video-upstream.c
drivers/media/pci/cx25821/cx25821-video.c
drivers/media/pci/cx88/cx88-alsa.c
drivers/media/pci/cx88/cx88-blackbird.c
drivers/media/pci/cx88/cx88-core.c
drivers/media/pci/cx88/cx88-input.c
drivers/media/pci/cx88/cx88-mpeg.c
drivers/media/pci/cx88/cx88.h
drivers/media/pci/dm1105/dm1105.c
drivers/media/pci/ivtv/ivtv-alsa-main.c
drivers/media/pci/ivtv/ivtv-alsa-pcm.c
drivers/media/pci/ivtv/ivtv-alsa-pcm.h
drivers/media/pci/ivtv/ivtv-firmware.c
drivers/media/pci/ivtv/ivtv-i2c.c
drivers/media/pci/ivtv/ivtv-ioctl.c
drivers/media/pci/mantis/mantis_input.c
drivers/media/pci/mantis/mantis_uart.c
drivers/media/pci/mantis/mantis_vp1033.c
drivers/media/pci/meye/meye.c
drivers/media/pci/ngene/ngene-cards.c
drivers/media/pci/ngene/ngene-core.c
drivers/media/pci/saa7134/saa7134-core.c
drivers/media/pci/saa7134/saa7134-input.c
drivers/media/pci/saa7134/saa7134-video.c
drivers/media/pci/saa7164/saa7164-api.c
drivers/media/pci/saa7164/saa7164-bus.c
drivers/media/pci/saa7164/saa7164-cmd.c
drivers/media/pci/saa7164/saa7164-core.c
drivers/media/pci/saa7164/saa7164-encoder.c
drivers/media/pci/saa7164/saa7164-fw.c
drivers/media/pci/saa7164/saa7164-vbi.c
drivers/media/pci/ttpci/av7110.h
drivers/media/pci/ttpci/budget-av.c
drivers/media/platform/Kconfig
drivers/media/platform/Makefile
drivers/media/platform/blackfin/bfin_capture.c
drivers/media/platform/coda.c
drivers/media/platform/davinci/Kconfig
drivers/media/platform/davinci/dm355_ccdc.c
drivers/media/platform/davinci/dm644x_ccdc.c
drivers/media/platform/davinci/isif.c
drivers/media/platform/davinci/vpbe.c
drivers/media/platform/davinci/vpbe_display.c
drivers/media/platform/davinci/vpbe_osd.c
drivers/media/platform/davinci/vpif.c
drivers/media/platform/davinci/vpif_capture.c
drivers/media/platform/davinci/vpif_display.c
drivers/media/platform/exynos-gsc/gsc-core.c
drivers/media/platform/exynos-gsc/gsc-m2m.c
drivers/media/platform/fsl-viu.c
drivers/media/platform/m2m-deinterlace.c
drivers/media/platform/mem2mem_testdev.c
drivers/media/platform/mx2_emmaprp.c
drivers/media/platform/omap/omap_vout.c
drivers/media/platform/omap3isp/isp.c
drivers/media/platform/omap3isp/isp.h
drivers/media/platform/omap3isp/ispcsi2.c
drivers/media/platform/omap3isp/ispcsiphy.c
drivers/media/platform/omap3isp/ispcsiphy.h
drivers/media/platform/omap3isp/isphist.c
drivers/media/platform/omap3isp/isppreview.c
drivers/media/platform/omap3isp/ispreg.h
drivers/media/platform/omap3isp/ispstat.c
drivers/media/platform/omap3isp/ispstat.h
drivers/media/platform/omap3isp/ispvideo.c
drivers/media/platform/s3c-camif/Makefile [new file with mode: 0644]
drivers/media/platform/s3c-camif/camif-capture.c [new file with mode: 0644]
drivers/media/platform/s3c-camif/camif-core.c [new file with mode: 0644]
drivers/media/platform/s3c-camif/camif-core.h [new file with mode: 0644]
drivers/media/platform/s3c-camif/camif-regs.c [new file with mode: 0644]
drivers/media/platform/s3c-camif/camif-regs.h [new file with mode: 0644]
drivers/media/platform/s5p-fimc/fimc-capture.c
drivers/media/platform/s5p-fimc/fimc-m2m.c
drivers/media/platform/s5p-fimc/fimc-mdevice.c
drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
drivers/media/platform/s5p-tv/mixer_video.c
drivers/media/platform/soc_camera/Kconfig
drivers/media/platform/soc_camera/soc_camera.c
drivers/media/platform/vivi.c
drivers/media/radio/radio-aimslab.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-isa.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/si4713-i2c.c
drivers/media/radio/wl128x/fmdrv.h
drivers/media/radio/wl128x/fmdrv_common.c
drivers/media/radio/wl128x/fmdrv_rx.c
drivers/media/rc/ati_remote.c
drivers/media/rc/ene_ir.c
drivers/media/rc/fintek-cir.c
drivers/media/rc/gpio-ir-recv.c
drivers/media/rc/iguanair.c
drivers/media/rc/imon.c
drivers/media/rc/ir-jvc-decoder.c
drivers/media/rc/ir-lirc-codec.c
drivers/media/rc/ir-mce_kbd-decoder.c
drivers/media/rc/ir-nec-decoder.c
drivers/media/rc/ir-rc5-decoder.c
drivers/media/rc/ir-rc5-sz-decoder.c
drivers/media/rc/ir-rc6-decoder.c
drivers/media/rc/ir-rx51.c
drivers/media/rc/ir-sanyo-decoder.c
drivers/media/rc/ir-sony-decoder.c
drivers/media/rc/ite-cir.c
drivers/media/rc/keymaps/rc-imon-mce.c
drivers/media/rc/keymaps/rc-rc6-mce.c
drivers/media/rc/mceusb.c
drivers/media/rc/nuvoton-cir.c
drivers/media/rc/nuvoton-cir.h
drivers/media/rc/rc-loopback.c
drivers/media/rc/rc-main.c
drivers/media/rc/redrat3.c
drivers/media/rc/streamzap.c
drivers/media/rc/ttusbir.c
drivers/media/rc/winbond-cir.c
drivers/media/tuners/fc2580.c
drivers/media/tuners/max2165.c
drivers/media/tuners/tua9001.c
drivers/media/tuners/xc4000.c
drivers/media/usb/au0828/au0828-cards.c
drivers/media/usb/au0828/au0828-dvb.c
drivers/media/usb/au0828/au0828-video.c
drivers/media/usb/cx231xx/cx231xx-avcore.c
drivers/media/usb/cx231xx/cx231xx-cards.c
drivers/media/usb/cx231xx/cx231xx-i2c.c
drivers/media/usb/cx231xx/cx231xx-input.c
drivers/media/usb/dvb-usb-v2/af9015.c
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/media/usb/dvb-usb-v2/anysee.c
drivers/media/usb/dvb-usb-v2/az6007.c
drivers/media/usb/dvb-usb-v2/dvb_usb.h
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
drivers/media/usb/dvb-usb-v2/it913x.c
drivers/media/usb/dvb-usb-v2/lmedm04.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/usb_urb.c
drivers/media/usb/dvb-usb/az6027.c
drivers/media/usb/dvb-usb/dib0700.h
drivers/media/usb/dvb-usb/dib0700_core.c
drivers/media/usb/dvb-usb/dib0700_devices.c
drivers/media/usb/dvb-usb/dvb-usb.h
drivers/media/usb/dvb-usb/pctv452e.c
drivers/media/usb/dvb-usb/technisat-usb2.c
drivers/media/usb/dvb-usb/ttusb2.c
drivers/media/usb/dvb-usb/vp702x.c
drivers/media/usb/em28xx/em28xx-cards.c
drivers/media/usb/em28xx/em28xx-dvb.c
drivers/media/usb/em28xx/em28xx-input.c
drivers/media/usb/em28xx/em28xx.h
drivers/media/usb/gspca/gspca.c
drivers/media/usb/gspca/gspca.h
drivers/media/usb/gspca/jeilinj.c
drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
drivers/media/usb/gspca/pac7302.c
drivers/media/usb/gspca/sonixb.c
drivers/media/usb/hdpvr/hdpvr-core.c
drivers/media/usb/hdpvr/hdpvr-i2c.c
drivers/media/usb/pvrusb2/pvrusb2-hdw.c
drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
drivers/media/usb/pwc/pwc-ctrl.c
drivers/media/usb/pwc/pwc-if.c
drivers/media/usb/s2255/s2255drv.c
drivers/media/usb/siano/Kconfig
drivers/media/usb/sn9c102/sn9c102_core.c
drivers/media/usb/stk1160/stk1160-i2c.c
drivers/media/usb/stk1160/stk1160-video.c
drivers/media/usb/stk1160/stk1160.h
drivers/media/usb/stkwebcam/stk-webcam.c
drivers/media/usb/tlg2300/pd-dvb.c
drivers/media/usb/tlg2300/pd-video.c
drivers/media/usb/tm6000/tm6000-input.c
drivers/media/usb/tm6000/tm6000-video.c
drivers/media/usb/usbvision/usbvision.h
drivers/media/usb/uvc/uvc_ctrl.c
drivers/media/usb/uvc/uvc_driver.c
drivers/media/usb/uvc/uvc_entity.c
drivers/media/usb/uvc/uvc_queue.c
drivers/media/usb/uvc/uvc_v4l2.c
drivers/media/usb/uvc/uvc_video.c
drivers/media/usb/uvc/uvcvideo.h
drivers/media/usb/zr364xx/zr364xx.c
drivers/media/v4l2-core/Kconfig
drivers/media/v4l2-core/v4l2-common.c
drivers/media/v4l2-core/v4l2-compat-ioctl32.c
drivers/media/v4l2-core/v4l2-dev.c
drivers/media/v4l2-core/v4l2-event.c
drivers/media/v4l2-core/v4l2-fh.c
drivers/media/v4l2-core/v4l2-ioctl.c
drivers/media/v4l2-core/v4l2-mem2mem.c
drivers/media/v4l2-core/v4l2-subdev.c
drivers/media/v4l2-core/videobuf-core.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/media/v4l2-core/videobuf2-dma-contig.c
drivers/media/v4l2-core/videobuf2-memops.c
drivers/media/v4l2-core/videobuf2-vmalloc.c
drivers/staging/media/dt3155v4l/dt3155v4l.c
drivers/staging/media/go7007/go7007-fw.c
drivers/staging/media/go7007/go7007-v4l2.c
drivers/staging/media/go7007/s2250-board.c
drivers/staging/media/go7007/wis-ov7640.c
drivers/staging/media/go7007/wis-saa7113.c
drivers/staging/media/go7007/wis-saa7115.c
drivers/staging/media/go7007/wis-sony-tuner.c
drivers/staging/media/go7007/wis-tw2804.c
drivers/staging/media/go7007/wis-tw9903.c
drivers/staging/media/go7007/wis-uda1342.c
drivers/staging/media/lirc/lirc_serial.c
include/linux/dvb/Kbuild [deleted file]
include/linux/dvb/dmx.h [deleted file]
include/linux/dvb/video.h [deleted file]
include/media/adp1653.h
include/media/davinci/vpbe_display.h
include/media/davinci/vpbe_osd.h
include/media/ir-kbd-i2c.h
include/media/mt9v022.h [new file with mode: 0644]
include/media/rc-core.h
include/media/rc-map.h
include/media/s3c_camif.h [new file with mode: 0644]
include/media/smiapp.h
include/media/v4l2-event.h
include/media/v4l2-fh.h
include/media/v4l2-ioctl.h
include/media/v4l2-mem2mem.h
include/media/videobuf2-core.h
include/media/videobuf2-memops.h
include/uapi/linux/videodev2.h

index 4fdf6b562d1cedb819c258f99820edfa4fafc7b3..3dd9e78815d1bca89576c2817bb050471419cf04 100644 (file)
@@ -2586,6 +2586,13 @@ ioctls.</para>
          <para>Vendor and device specific media bus pixel formats.
            <xref linkend="v4l2-mbus-vendor-spec-fmts" />.</para>
         </listitem>
+        <listitem>
+         <para>Importing DMABUF file descriptors as a new IO method described
+         in <xref linkend="dmabuf" />.</para>
+        </listitem>
+        <listitem>
+         <para>Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl.</para>
+        </listitem>
       </itemizedlist>
     </section>
 
index b5d1cbdc558bdfa5cfbd6e451425dabc5456b0ce..388a3403265380f14128feb10b50543f69bd994c 100644 (file)
@@ -331,7 +331,7 @@ application until one or more buffers can be dequeued. By default
 outgoing queue. When the <constant>O_NONBLOCK</constant> flag was
 given to the &func-open; function, <constant>VIDIOC_DQBUF</constant>
 returns immediately with an &EAGAIN; when no buffer is available. The
-&func-select; or &func-poll; function are always available.</para>
+&func-select; or &func-poll; functions are always available.</para>
 
     <para>To start and stop capturing or output applications call the
 &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
@@ -472,6 +472,165 @@ rest should be evident.</para>
       </footnote></para>
   </section>
 
+  <section id="dmabuf">
+    <title>Streaming I/O (DMA buffer importing)</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental"> experimental </link>
+      interface and may change in the future.</para>
+    </note>
+
+<para>The DMABUF framework provides a generic method for sharing buffers
+between multiple devices. Device drivers that support DMABUF can export a DMA
+buffer to userspace as a file descriptor (known as the exporter role), import a
+DMA buffer from userspace using a file descriptor previously exported for a
+different or the same device (known as the importer role), or both. This
+section describes the DMABUF importer role API in V4L2.</para>
+
+    <para>Refer to <link linked="vidioc-expbuf"> DMABUF exporting </link> for
+details about exporting V4L2 buffers as DMABUF file descriptors.</para>
+
+<para>Input and output devices support the streaming I/O method when the
+<constant>V4L2_CAP_STREAMING</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability; returned by
+the &VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through
+DMABUF file descriptors is supported is determined by calling the
+&VIDIOC-REQBUFS; ioctl with the memory type set to
+<constant>V4L2_MEMORY_DMABUF</constant>.</para>
+
+    <para>This I/O method is dedicated to sharing DMA buffers between different
+devices, which may be V4L devices or other video-related devices (e.g. DRM).
+Buffers (planes) are allocated by a driver on behalf of an application. Next,
+these buffers are exported to the application as file descriptors using an API
+which is specific for an allocator driver.  Only such file descriptor are
+exchanged. The descriptors and meta-information are passed in &v4l2-buffer; (or
+in &v4l2-plane; in the multi-planar API case).  The driver must be switched
+into DMABUF I/O mode by calling the &VIDIOC-REQBUFS; with the desired buffer
+type.</para>
+
+    <example>
+      <title>Initiating streaming I/O with DMABUF file descriptors</title>
+
+      <programlisting>
+&v4l2-requestbuffers; reqbuf;
+
+memset(&amp;reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_DMABUF;
+reqbuf.count = 1;
+
+if (ioctl(fd, &VIDIOC-REQBUFS;, &amp;reqbuf) == -1) {
+       if (errno == EINVAL)
+               printf("Video capturing or DMABUF streaming is not supported\n");
+       else
+               perror("VIDIOC_REQBUFS");
+
+       exit(EXIT_FAILURE);
+}
+      </programlisting>
+    </example>
+
+    <para>The buffer (plane) file descriptor is passed on the fly with the
+&VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be
+associated with a different DMABUF descriptor. Although buffers are commonly
+cycled, applications can pass a different DMABUF descriptor at each
+<constant>VIDIOC_QBUF</constant> call.</para>
+
+    <example>
+      <title>Queueing DMABUF using single plane API</title>
+
+      <programlisting>
+int buffer_queue(int v4lfd, int index, int dmafd)
+{
+       &v4l2-buffer; buf;
+
+       memset(&amp;buf, 0, sizeof buf);
+       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       buf.memory = V4L2_MEMORY_DMABUF;
+       buf.index = index;
+       buf.m.fd = dmafd;
+
+       if (ioctl(v4lfd, &VIDIOC-QBUF;, &amp;buf) == -1) {
+               perror("VIDIOC_QBUF");
+               return -1;
+       }
+
+       return 0;
+}
+      </programlisting>
+    </example>
+
+    <example>
+      <title>Queueing DMABUF using multi plane API</title>
+
+      <programlisting>
+int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
+{
+       &v4l2-buffer; buf;
+       &v4l2-plane; planes[VIDEO_MAX_PLANES];
+       int i;
+
+       memset(&amp;buf, 0, sizeof buf);
+       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+       buf.memory = V4L2_MEMORY_DMABUF;
+       buf.index = index;
+       buf.m.planes = planes;
+       buf.length = n_planes;
+
+       memset(&amp;planes, 0, sizeof planes);
+
+       for (i = 0; i &lt; n_planes; ++i)
+               buf.m.planes[i].m.fd = dmafd[i];
+
+       if (ioctl(v4lfd, &VIDIOC-QBUF;, &amp;buf) == -1) {
+               perror("VIDIOC_QBUF");
+               return -1;
+       }
+
+       return 0;
+}
+      </programlisting>
+    </example>
+
+    <para>Captured or displayed buffers are dequeued with the
+&VIDIOC-DQBUF; ioctl. The driver can unlock the buffer at any
+time between the completion of the DMA and this ioctl. The memory is
+also unlocked when &VIDIOC-STREAMOFF; is called, &VIDIOC-REQBUFS;, or
+when the device is closed.</para>
+
+    <para>For capturing applications it is customary to enqueue a
+number of empty buffers, to start capturing and enter the read loop.
+Here the application waits until a filled buffer can be dequeued, and
+re-enqueues the buffer when the data is no longer needed. Output
+applications fill and enqueue buffers, when enough buffers are stacked
+up output is started. In the write loop, when the application
+runs out of free buffers it must wait until an empty buffer can be
+dequeued and reused. Two methods exist to suspend execution of the
+application until one or more buffers can be dequeued. By default
+<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the
+outgoing queue. When the <constant>O_NONBLOCK</constant> flag was
+given to the &func-open; function, <constant>VIDIOC_DQBUF</constant>
+returns immediately with an &EAGAIN; when no buffer is available. The
+&func-select; and &func-poll; functions are always available.</para>
+
+    <para>To start and stop capturing or displaying applications call the
+&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctls. Note that
+<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both queues and
+unlocks all buffers as a side effect. Since there is no notion of doing
+anything "now" on a multitasking system, if an application needs to synchronize
+with another event it should examine the &v4l2-buffer;
+<structfield>timestamp</structfield> of captured buffers, or set the field
+before enqueuing buffers for output.</para>
+
+    <para>Drivers implementing DMABUF importing I/O must support the
+<constant>VIDIOC_REQBUFS</constant>, <constant>VIDIOC_QBUF</constant>,
+<constant>VIDIOC_DQBUF</constant>, <constant>VIDIOC_STREAMON</constant> and
+<constant>VIDIOC_STREAMOFF</constant> ioctls, and the
+<function>select()</function> and <function>poll()</function> functions.</para>
+
+  </section>
+
   <section id="async">
     <title>Asynchronous I/O</title>
 
@@ -672,6 +831,14 @@ memory, set by the application. See <xref linkend="userp" /> for details.
            in the <structfield>length</structfield> field of this
            <structname>v4l2_buffer</structname> structure.</entry>
          </row>
+         <row>
+           <entry></entry>
+           <entry>int</entry>
+           <entry><structfield>fd</structfield></entry>
+           <entry>For the single-plane API and when
+<structfield>memory</structfield> is <constant>V4L2_MEMORY_DMABUF</constant> this
+is the file descriptor associated with a DMABUF buffer.</entry>
+         </row>
          <row>
            <entry>__u32</entry>
            <entry><structfield>length</structfield></entry>
@@ -743,6 +910,15 @@ should set this to 0.</entry>
              pointer to the memory allocated for this plane by an application.
              </entry>
          </row>
+         <row>
+           <entry></entry>
+           <entry>int</entry>
+           <entry><structfield>fd</structfield></entry>
+           <entry>When the memory type in the containing &v4l2-buffer; is
+               <constant>V4L2_MEMORY_DMABUF</constant>, this is a file
+               descriptor associated with a DMABUF buffer, similar to the
+               <structfield>fd</structfield> field in &v4l2-buffer;.</entry>
+         </row>
          <row>
            <entry>__u32</entry>
            <entry><structfield>data_offset</structfield></entry>
@@ -923,7 +1099,7 @@ application. Drivers set or clear this flag when the
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
-           <entry>0x0400</entry>
+           <entry>0x0800</entry>
            <entry>Caches do not have to be invalidated for this buffer.
 Typically applications shall use this flag if the data captured in the buffer
 is not going to be touched by the CPU, instead the buffer will, probably, be
@@ -932,7 +1108,7 @@ passed on to a DMA-capable hardware unit for further processing or output.
          </row>
          <row>
            <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
-           <entry>0x0800</entry>
+           <entry>0x1000</entry>
            <entry>Caches do not have to be cleaned for this buffer.
 Typically applications shall use this flag for output buffers if the data
 in this buffer has not been created by the CPU but by some DMA-capable unit,
@@ -964,6 +1140,12 @@ pointer</link> I/O.</entry>
            <entry>3</entry>
            <entry>[to do]</entry>
          </row>
+         <row>
+           <entry><constant>V4L2_MEMORY_DMABUF</constant></entry>
+           <entry>4</entry>
+           <entry>The buffer is used for <link linkend="dmabuf">DMA shared
+buffer</link> I/O.</entry>
+         </row>
        </tbody>
       </tgroup>
     </table>
index 10ccde9d16d016d6f141f62479afa8f73753850b..4d110b1ad3e93c6559b094ac5bd832f2e4bf3be0 100644 (file)
@@ -543,6 +543,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-enuminput;
     &sub-enumoutput;
     &sub-enumstd;
+    &sub-expbuf;
     &sub-g-audio;
     &sub-g-audioout;
     &sub-g-crop;
index a8cda1acacd9a129b47d15451bfe054d6fcfd9c8..cd9943672434e29b629bf5a46e5aa42749008171 100644 (file)
@@ -6,7 +6,8 @@
 
   <refnamediv>
     <refname>VIDIOC_CREATE_BUFS</refname>
-    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
+    <refpurpose>Create buffers for Memory Mapped or User Pointer or DMA Buffer
+    I/O</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
     </note>
 
     <para>This ioctl is used to create buffers for <link linkend="mmap">memory
-mapped</link> or <link linkend="userp">user pointer</link>
-I/O. It can be used as an alternative or in addition to the
-<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
-is required. This ioctl can be called multiple times to create buffers of
-different sizes.</para>
+mapped</link> or <link linkend="userp">user pointer</link> or <link
+linkend="dmabuf">DMA buffer</link> I/O. It can be used as an alternative or in
+addition to the <constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter
+control over buffers is required. This ioctl can be called multiple times to
+create buffers of different sizes.</para>
 
     <para>To allocate device buffers applications initialize relevant fields of
 the <structname>v4l2_create_buffers</structname> structure. They set the
@@ -109,7 +110,8 @@ information.</para>
            <entry>__u32</entry>
            <entry><structfield>memory</structfield></entry>
            <entry>Applications set this field to
-<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_MMAP</constant>,
+<constant>V4L2_MEMORY_DMABUF</constant> or
 <constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory"
 /></entry>
          </row>
diff --git a/Documentation/DocBook/media/v4l/vidioc-expbuf.xml b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
new file mode 100644 (file)
index 0000000..72dfbd2
--- /dev/null
@@ -0,0 +1,212 @@
+<refentry id="vidioc-expbuf">
+
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_EXPBUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_EXPBUF</refname>
+    <refpurpose>Export a buffer as a DMABUF file descriptor.</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>struct v4l2_exportbuffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+       <term><parameter>fd</parameter></term>
+       <listitem>
+         <para>&fd;</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>request</parameter></term>
+       <listitem>
+         <para>VIDIOC_EXPBUF</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>argp</parameter></term>
+       <listitem>
+         <para></para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental"> experimental </link>
+      interface and may change in the future.</para>
+    </note>
+
+<para>This ioctl is an extension to the <link linkend="mmap">memory
+mapping</link> I/O method, therefore it is available only for
+<constant>V4L2_MEMORY_MMAP</constant> buffers.  It can be used to export a
+buffer as a DMABUF file at any time after buffers have been allocated with the
+&VIDIOC-REQBUFS; ioctl.</para>
+
+<para> To export a buffer, applications fill &v4l2-exportbuffer;.  The
+<structfield> type </structfield> field is set to the same buffer type as was
+previously used with  &v4l2-requestbuffers;<structfield> type </structfield>.
+Applications must also set the <structfield> index </structfield> field. Valid
+index numbers range from zero to the number of buffers allocated with
+&VIDIOC-REQBUFS; (&v4l2-requestbuffers;<structfield> count </structfield>)
+minus one.  For the multi-planar API, applications set the <structfield> plane
+</structfield> field to the index of the plane to be exported. Valid planes
+range from zero to the maximal number of valid planes for the currently active
+format. For the single-planar API, applications must set <structfield> plane
+</structfield> to zero.  Additional flags may be posted in the <structfield>
+flags </structfield> field.  Refer to a manual for open() for details.
+Currently only O_CLOEXEC is supported.  All other fields must be set to zero.
+In the case of multi-planar API, every plane is exported separately using
+multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>
+
+<para> After calling <constant>VIDIOC_EXPBUF</constant> the <structfield> fd
+</structfield> field will be set by a driver.  This is a DMABUF file
+descriptor. The application may pass it to other DMABUF-aware devices. Refer to
+<link linkend="dmabuf">DMABUF importing</link> for details about importing
+DMABUF files into V4L2 nodes. It is recommended to close a DMABUF file when it
+is no longer used to allow the associated memory to be reclaimed. </para>
+
+  </refsect1>
+  <refsect1>
+   <section>
+      <title>Examples</title>
+
+      <example>
+       <title>Exporting a buffer.</title>
+       <programlisting>
+int buffer_export(int v4lfd, &v4l2-buf-type; bt, int index, int *dmafd)
+{
+       &v4l2-exportbuffer; expbuf;
+
+       memset(&amp;expbuf, 0, sizeof(expbuf));
+       expbuf.type = bt;
+       expbuf.index = index;
+       if (ioctl(v4lfd, &VIDIOC-EXPBUF;, &amp;expbuf) == -1) {
+               perror("VIDIOC_EXPBUF");
+               return -1;
+       }
+
+       *dmafd = expbuf.fd;
+
+       return 0;
+}
+        </programlisting>
+      </example>
+
+      <example>
+       <title>Exporting a buffer using the multi-planar API.</title>
+       <programlisting>
+int buffer_export_mp(int v4lfd, &v4l2-buf-type; bt, int index,
+       int dmafd[], int n_planes)
+{
+       int i;
+
+       for (i = 0; i &lt; n_planes; ++i) {
+               &v4l2-exportbuffer; expbuf;
+
+               memset(&amp;expbuf, 0, sizeof(expbuf));
+               expbuf.type = bt;
+               expbuf.index = index;
+               expbuf.plane = i;
+               if (ioctl(v4lfd, &VIDIOC-EXPBUF;, &amp;expbuf) == -1) {
+                       perror("VIDIOC_EXPBUF");
+                       while (i)
+                               close(dmafd[--i]);
+                       return -1;
+               }
+               dmafd[i] = expbuf.fd;
+       }
+
+       return 0;
+}
+        </programlisting>
+      </example>
+   </section>
+  </refsect1>
+
+  <refsect1>
+    <table pgwide="1" frame="none" id="v4l2-exportbuffer">
+      <title>struct <structname>v4l2_exportbuffer</structname></title>
+      <tgroup cols="3">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>type</structfield></entry>
+           <entry>Type of the buffer, same as &v4l2-format;
+<structfield>type</structfield> or &v4l2-requestbuffers;
+<structfield>type</structfield>, set by the application. See <xref
+linkend="v4l2-buf-type" /></entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>index</structfield></entry>
+           <entry>Number of the buffer, set by the application. This field is
+only used for <link linkend="mmap">memory mapping</link> I/O and can range from
+zero to the number of buffers allocated with the &VIDIOC-REQBUFS; and/or
+&VIDIOC-CREATE-BUFS; ioctls. </entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>plane</structfield></entry>
+           <entry>Index of the plane to be exported when using the
+multi-planar API. Otherwise this value must be set to zero. </entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>flags</structfield></entry>
+           <entry>Flags for the newly created file, currently only <constant>
+O_CLOEXEC </constant> is supported, refer to the manual of open() for more
+details.</entry>
+         </row>
+         <row>
+           <entry>__s32</entry>
+           <entry><structfield>fd</structfield></entry>
+           <entry>The DMABUF file descriptor associated with a buffer. Set by
+               the driver.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>reserved[11]</structfield></entry>
+           <entry>Reserved field for future use. Must be set to zero.</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+    <variablelist>
+      <varlistentry>
+       <term><errorcode>EINVAL</errorcode></term>
+       <listitem>
+         <para>A queue is not in MMAP mode or DMABUF exporting is not
+supported or <structfield> flags </structfield> or <structfield> type
+</structfield> or <structfield> index </structfield> or <structfield> plane
+</structfield> fields are invalid.</para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+</refentry>
index 2d37abefce13e90144941af12cc2baa71f78a700..3504a7f2f382c6f1818cf5a5983405f136e0fe94 100644 (file)
@@ -109,6 +109,23 @@ they cannot be swapped out to disk. Buffers remain locked until
 dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is
 called, or until the device is closed.</para>
 
+    <para>To enqueue a <link linkend="dmabuf">DMABUF</link> buffer applications
+set the <structfield>memory</structfield> field to
+<constant>V4L2_MEMORY_DMABUF</constant> and the <structfield>m.fd</structfield>
+field to a file descriptor associated with a DMABUF buffer. When the
+multi-planar API is used the <structfield>m.fd</structfield> fields of the
+passed array of &v4l2-plane; have to be used instead. When
+<constant>VIDIOC_QBUF</constant> is called with a pointer to this structure the
+driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant> flag and clears the
+<constant>V4L2_BUF_FLAG_MAPPED</constant> and
+<constant>V4L2_BUF_FLAG_DONE</constant> flags in the
+<structfield>flags</structfield> field, or it returns an error code.  This
+ioctl locks the buffer. Locking a buffer means passing it to a driver for a
+hardware access (usually DMA).  If an application accesses (reads/writes) a
+locked buffer then the result is undefined.  Buffers remain locked until
+dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is called, or
+until the device is closed.</para>
+
     <para>Applications call the <constant>VIDIOC_DQBUF</constant>
 ioctl to dequeue a filled (capturing) or displayed (output) buffer
 from the driver's outgoing queue. They just set the
index 2b50ef2007f3cc96dc363176e2c173af96c3e2a8..78a06a9a5ece18c3cfe6967f8c18822e89ace6fa 100644 (file)
   <refsect1>
     <title>Description</title>
 
-    <para>This ioctl is used to initiate <link linkend="mmap">memory
-mapped</link> or <link linkend="userp">user pointer</link>
-I/O. Memory mapped buffers are located in device memory and must be
-allocated with this ioctl before they can be mapped into the
-application's address space. User buffers are allocated by
-applications themselves, and this ioctl is merely used to switch the
-driver into user pointer I/O mode and to setup some internal structures.</para>
+<para>This ioctl is used to initiate <link linkend="mmap">memory mapped</link>,
+<link linkend="userp">user pointer</link> or <link
+linkend="dmabuf">DMABUF</link> based I/O.  Memory mapped buffers are located in
+device memory and must be allocated with this ioctl before they can be mapped
+into the application's address space. User buffers are allocated by
+applications themselves, and this ioctl is merely used to switch the driver
+into user pointer I/O mode and to setup some internal structures.
+Similarly, DMABUF buffers are allocated by applications through a device
+driver, and this ioctl only configures the driver into DMABUF I/O mode without
+performing any direct allocation.</para>
 
-    <para>To allocate device buffers applications initialize all
-fields of the <structname>v4l2_requestbuffers</structname> structure.
-They set the <structfield>type</structfield> field to the respective
-stream or buffer type, the <structfield>count</structfield> field to
-the desired number of buffers, <structfield>memory</structfield>
-must be set to the requested I/O method and the <structfield>reserved</structfield> array
-must be zeroed. When the ioctl
-is called with a pointer to this structure the driver will attempt to allocate
-the requested number of buffers and it stores the actual number
-allocated in the <structfield>count</structfield> field. It can be
-smaller than the number requested, even zero, when the driver runs out
-of free memory. A larger number is also possible when the driver requires
-more buffers to function correctly. For example video output requires at least two buffers,
-one displayed and one filled by the application.</para>
+    <para>To allocate device buffers applications initialize all fields of the
+<structname>v4l2_requestbuffers</structname> structure.  They set the
+<structfield>type</structfield> field to the respective stream or buffer type,
+the <structfield>count</structfield> field to the desired number of buffers,
+<structfield>memory</structfield> must be set to the requested I/O method and
+the <structfield>reserved</structfield> array must be zeroed. When the ioctl is
+called with a pointer to this structure the driver will attempt to allocate the
+requested number of buffers and it stores the actual number allocated in the
+<structfield>count</structfield> field. It can be smaller than the number
+requested, even zero, when the driver runs out of free memory. A larger number
+is also possible when the driver requires more buffers to function correctly.
+For example video output requires at least two buffers, one displayed and one
+filled by the application.</para>
     <para>When the I/O method is not supported the ioctl
 returns an &EINVAL;.</para>
 
@@ -102,7 +104,8 @@ as the &v4l2-format; <structfield>type</structfield> field. See <xref
            <entry>__u32</entry>
            <entry><structfield>memory</structfield></entry>
            <entry>Applications set this field to
-<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_MMAP</constant>,
+<constant>V4L2_MEMORY_DMABUF</constant> or
 <constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory"
 />.</entry>
          </row>
index 63b140583e293b191a9801cbdf9ae0b6961ae9ee..a6be3e864b530562feb49083a09028284d0bf4f8 100644 (file)
@@ -337,6 +337,13 @@ W: http://wireless.kernel.org/
 S:     Orphan
 F:     drivers/net/wireless/adm8211.*
 
+ADP1653 FLASH CONTROLLER DRIVER
+M:     Sakari Ailus <sakari.ailus@iki.fi>
+L:     linux-media@vger.kernel.org
+S:     Maintained
+F:     drivers/media/i2c/adp1653.c
+F:     include/media/adp1653.h
+
 ADP5520 BACKLIGHT DRIVER WITH IO EXPANDER (ADP5520/ADP5501)
 M:     Michael Hennerich <michael.hennerich@analog.com>
 L:     device-drivers-devel@blackfin.uclinux.org
@@ -1494,6 +1501,14 @@ F:       include/linux/ax25.h
 F:     include/net/ax25.h
 F:     net/ax25/
 
+AZ6007 DVB DRIVER
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/usb/dvb-usb-v2/az6007.c
+
 B43 WIRELESS DRIVER
 M:     Stefano Brivio <stefano.brivio@polimi.it>
 L:     linux-wireless@vger.kernel.org
@@ -1745,11 +1760,11 @@ F:      Documentation/filesystems/btrfs.txt
 F:     fs/btrfs/
 
 BTTV VIDEO4LINUX DRIVER
-M:     Mauro Carvalho Chehab <mchehab@infradead.org>
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
 L:     linux-media@vger.kernel.org
 W:     http://linuxtv.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
-S:     Maintained
+T:     git git://linuxtv.org/media_tree.git
+S:     Odd fixes
 F:     Documentation/video4linux/bttv/
 F:     drivers/media/pci/bt8xx/bttv*
 
@@ -1778,7 +1793,7 @@ F:        fs/cachefiles/
 CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
 M:     Jonathan Corbet <corbet@lwn.net>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     Documentation/video4linux/cafe_ccic
 F:     drivers/media/platform/marvell-ccic/
@@ -2164,12 +2179,22 @@ CX18 VIDEO4LINUX DRIVER
 M:     Andy Walls <awalls@md.metrocast.net>
 L:     ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 W:     http://linuxtv.org
 W:     http://www.ivtvdriver.org/index.php/Cx18
 S:     Maintained
 F:     Documentation/video4linux/cx18.txt
 F:     drivers/media/pci/cx18/
+F:     include/uapi/linux/ivtv*
+
+CX88 VIDEO4LINUX DRIVER
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Odd fixes
+F:     Documentation/video4linux/cx88/
+F:     drivers/media/pci/cx88/
 
 CXD2820R MEDIA DRIVER
 M:     Antti Palosaari <crope@iki.fi>
@@ -2856,6 +2881,14 @@ L:       netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/ibm/ehea/
 
+EM28XX VIDEO4LINUX DRIVER
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/usb/em28xx/
+
 EMBEDDED LINUX
 M:     Paul Gortmaker <paul.gortmaker@windriver.com>
 M:     Matt Mackall <mpm@selenic.com>
@@ -3054,6 +3087,14 @@ T:       git git://git.alsa-project.org/alsa-kernel.git
 S:     Maintained
 F:     sound/firewire/
 
+FIREWIRE MEDIA DRIVERS (firedtv)
+M:     Stefan Richter <stefanr@s5r6.in-berlin.de>
+L:     linux-media@vger.kernel.org
+L:     linux1394-devel@lists.sourceforge.net
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+S:     Maintained
+F:     drivers/media/firewire/
+
 FIREWIRE SBP-2 TARGET
 M:     Chris Boot <bootc@bootc.net>
 L:     linux-scsi@vger.kernel.org
@@ -3340,56 +3381,56 @@ F:      drivers/net/ethernet/aeroflex/
 GSPCA FINEPIX SUBDRIVER
 M:     Frank Zago <frank@zago.net>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/gspca/finepix.c
 
 GSPCA GL860 SUBDRIVER
 M:     Olivier Lorin <o.lorin@laposte.net>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/gspca/gl860/
 
 GSPCA M5602 SUBDRIVER
 M:     Erik Andren <erik.andren@gmail.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/gspca/m5602/
 
 GSPCA PAC207 SONIXB SUBDRIVER
 M:     Hans de Goede <hdegoede@redhat.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/gspca/pac207.c
 
 GSPCA SN9C20X SUBDRIVER
 M:     Brian Johnson <brijohn@gmail.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/gspca/sn9c20x.c
 
 GSPCA T613 SUBDRIVER
 M:     Leandro Costantino <lcostantino@gmail.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/gspca/t613.c
 
 GSPCA USB WEBCAM DRIVER
 M:     Hans de Goede <hdegoede@redhat.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/gspca/
 
 STK1160 USB VIDEO CAPTURE DRIVER
 M:     Ezequiel Garcia <elezegarcia@gmail.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/usb/stk1160/
 
@@ -3787,6 +3828,12 @@ F:       net/ieee802154/
 F:     net/mac802154/
 F:     drivers/ieee802154/
 
+IGUANAWORKS USB IR TRANSCEIVER
+M:     Sean Young <sean@mess.org>
+L:     linux-media@vger.kernel.org
+S:     Maintained
+F:     drivers/media/rc/iguanair.c
+
 IIO SUBSYSTEM AND DRIVERS
 M:     Jonathan Cameron <jic23@cam.ac.uk>
 L:     linux-iio@vger.kernel.org
@@ -4172,17 +4219,41 @@ S:      Maintained
 F:     Documentation/hwmon/it87
 F:     drivers/hwmon/it87.c
 
+IT913X MEDIA DRIVER
+M:     Malcolm Priestley <tvboxspy@gmail.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/usb/dvb-usb-v2/it913x*
+
+IT913X FE MEDIA DRIVER
+M:     Malcolm Priestley <tvboxspy@gmail.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/dvb-frontends/it913x-fe*
+
 IVTV VIDEO4LINUX DRIVER
 M:     Andy Walls <awalls@md.metrocast.net>
 L:     ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 W:     http://www.ivtvdriver.org
 S:     Maintained
 F:     Documentation/video4linux/*.ivtv
 F:     drivers/media/pci/ivtv/
 F:     include/linux/ivtv*
 
+IX2505V MEDIA DRIVER
+M:     Malcolm Priestley <tvboxspy@gmail.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/dvb-frontends/ix2505v*
+
 JC42.4 TEMPERATURE SENSOR DRIVER
 M:     Guenter Roeck <linux@roeck-us.net>
 L:     lm-sensors@lm-sensors.org
@@ -4628,6 +4699,14 @@ S:       Maintained
 F:     Documentation/hwmon/lm90
 F:     drivers/hwmon/lm90.c
 
+LME2510 MEDIA DRIVER
+M:     Malcolm Priestley <tvboxspy@gmail.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/usb/dvb-usb-v2/lmedm04*
+
 LOCKDEP AND LOCKSTAT
 M:     Peter Zijlstra <peterz@infradead.org>
 M:     Ingo Molnar <mingo@redhat.com>
@@ -4721,6 +4800,14 @@ W:       http://www.tazenda.demon.co.uk/phil/linux-hp
 S:     Maintained
 F:     arch/m68k/hp300/
 
+M88RS2000 MEDIA DRIVER
+M:     Malcolm Priestley <tvboxspy@gmail.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/dvb-frontends/m88rs2000*
+
 MAC80211
 M:     Johannes Berg <johannes@sipsolutions.net>
 L:     linux-wireless@vger.kernel.org
@@ -4813,12 +4900,12 @@ F:      Documentation/hwmon/max6650
 F:     drivers/hwmon/max6650.c
 
 MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
-M:     Mauro Carvalho Chehab <mchehab@infradead.org>
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
 P:     LinuxTV.org Project
 L:     linux-media@vger.kernel.org
 W:     http://linuxtv.org
 Q:     http://patchwork.kernel.org/project/linux-media/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     Documentation/dvb/
 F:     Documentation/video4linux/
@@ -4826,8 +4913,13 @@ F:       Documentation/DocBook/media/
 F:     drivers/media/
 F:     drivers/staging/media/
 F:     include/media/
-F:     include/linux/dvb/
-F:     include/linux/videodev*.h
+F:     include/uapi/linux/dvb/
+F:     include/uapi/linux/videodev2.h
+F:     include/uapi/linux/media.h
+F:     include/uapi/linux/v4l2-*
+F:     include/uapi/linux/meye.h
+F:     include/uapi/linux/ivtv*
+F:     include/uapi/linux/uvcvideo.h
 
 MEGARAID SCSI DRIVERS
 M:     Neela Syam Kolli <megaraidlinux@lsi.com>
@@ -4909,7 +5001,7 @@ W:        http://popies.net/meye/
 S:     Orphan
 F:     Documentation/video4linux/meye.txt
 F:     drivers/media/pci/meye/
-F:     include/linux/meye.h
+F:     include/uapi/linux/meye.h
 
 MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER
 M:     Pavel Pisa <ppisa@pikron.com>
@@ -4923,6 +5015,13 @@ S:       Maintained
 F:     Documentation/serial/moxa-smartio
 F:     drivers/tty/mxser.*
 
+MR800 AVERMEDIA USB FM RADIO DRIVER
+M:     Alexey Klimov <klimov.linux@gmail.com>
+L:     linux-media@vger.kernel.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/radio/radio-mr800.c
+
 MSI LAPTOP SUPPORT
 M:     "Lee, Chun-Yi" <jlee@novell.com>
 L:     platform-driver-x86@vger.kernel.org
@@ -5385,7 +5484,7 @@ F:        drivers/char/pcmcia/cm4040_cs.*
 OMNIVISION OV7670 SENSOR DRIVER
 M:     Jonathan Corbet <corbet@lwn.net>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/i2c/ov7670.c
 
@@ -5934,11 +6033,18 @@ M:      Mike Isely <isely@pobox.com>
 L:     pvrusb2@isely.net       (subscribers-only)
 L:     linux-media@vger.kernel.org
 W:     http://www.isely.net/pvrusb2/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     Documentation/video4linux/README.pvrusb2
 F:     drivers/media/usb/pvrusb2/
 
+PWC WEBCAM DRIVER
+M:     Hans de Goede <hdegoede@redhat.com>
+L:     linux-media@vger.kernel.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/usb/pwc/*
+
 PWM SUBSYSTEM
 M:     Thierry Reding <thierry.reding@avionic-design.de>
 L:     linux-kernel@vger.kernel.org
@@ -6081,6 +6187,21 @@ S:       Maintained
 F:     drivers/video/aty/radeon*
 F:     include/linux/radeonfb.h
 
+RADIOSHARK RADIO DRIVER
+M:     Hans de Goede <hdegoede@redhat.com>
+L:     linux-media@vger.kernel.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/radio/radio-shark.c
+
+RADIOSHARK2 RADIO DRIVER
+M:     Hans de Goede <hdegoede@redhat.com>
+L:     linux-media@vger.kernel.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/radio/radio-shark2.c
+F:     drivers/media/radio/radio-tea5777.c
+
 RAGE128 FRAMEBUFFER DISPLAY DRIVER
 M:     Paul Mackerras <paulus@samba.org>
 L:     linux-fbdev@vger.kernel.org
@@ -6321,10 +6442,19 @@ L:      linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 F:     drivers/mmc/host/s3cmci.*
 
+SAA7134 VIDEO4LINUX DRIVER
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Odd fixes
+F:     Documentation/video4linux/saa7134/
+F:     drivers/media/pci/saa7134/
+
 SAA7146 VIDEO4LINUX-2 DRIVER
 M:     Michael Hunold <michael@mihu.de>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 W:     http://www.mihu.de/linux/saa7146
 S:     Maintained
 F:     drivers/media/common/saa7146/
@@ -6359,6 +6489,14 @@ F:       drivers/regulator/s5m*.c
 F:     drivers/rtc/rtc-sec.c
 F:     include/linux/mfd/samsung/
 
+SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER
+M:     Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+L:     linux-media@vger.kernel.org
+L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
+S:     Maintained
+F:     drivers/media/platform/s3c-camif/
+F:     include/media/s3c_camif.h
+
 SERIAL DRIVERS
 M:     Alan Cox <alan@linux.intel.com>
 L:     linux-serial@vger.kernel.org
@@ -6653,6 +6791,18 @@ S:       Supported
 F:     arch/arm/mach-davinci
 F:     drivers/i2c/busses/i2c-davinci.c
 
+TI DAVINCI SERIES MEDIA DRIVER
+M:     Manjunath Hadli <manjunath.hadli@ti.com>
+M:     Prabhakar Lad <prabhakar.lad@ti.com>
+L:     linux-media@vger.kernel.org
+L:     davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers)
+W:     http://linuxtv.org/
+Q:     http://patchwork.linuxtv.org/project/linux-media/list/
+T:     git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
+S:     Supported
+F:     drivers/media/platform/davinci/
+F:     include/media/davinci/
+
 SIS 190 ETHERNET DRIVER
 M:     Francois Romieu <romieu@fr.zoreil.com>
 L:     netdev@vger.kernel.org
@@ -6719,6 +6869,15 @@ M:       Nicolas Pitre <nico@fluxnic.net>
 S:     Odd Fixes
 F:     drivers/net/ethernet/smsc/smc91x.*
 
+SMIA AND SMIA++ IMAGE SENSOR DRIVER
+M:     Sakari Ailus <sakari.ailus@iki.fi>
+L:     linux-media@vger.kernel.org
+S:     Maintained
+F:     drivers/media/i2c/smiapp
+F:     include/media/smiapp.h
+F:     drivers/media/i2c/smiapp-pll.c
+F:     drivers/media/i2c/smiapp-pll.h
+
 SMM665 HARDWARE MONITOR DRIVER
 M:     Guenter Roeck <linux@roeck-us.net>
 L:     lm-sensors@lm-sensors.org
@@ -6777,7 +6936,7 @@ F:        arch/ia64/sn/
 SOC-CAMERA V4L2 SUBSYSTEM
 M:     Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     include/media/soc*
 F:     drivers/media/i2c/soc_camera/
@@ -7267,6 +7426,22 @@ T:       git git://linuxtv.org/mkrufky/tuners.git
 S:     Maintained
 F:     drivers/media/tuners/tda8290.*
 
+TEA5761 TUNER DRIVER
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Odd fixes
+F:     drivers/media/tuners/tea5761.*
+
+TEA5767 TUNER DRIVER
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/tuners/tea5767.*
+
 TEAM DRIVER
 M:     Jiri Pirko <jpirko@redhat.com>
 L:     netdev@vger.kernel.org
@@ -7274,6 +7449,12 @@ S:       Supported
 F:     drivers/net/team/
 F:     include/linux/if_team.h
 
+TECHNOTREND USB IR RECEIVER
+M:     Sean Young <sean@mess.org>
+L:     linux-media@vger.kernel.org
+S:     Maintained
+F:     drivers/media/rc/ttusbir.c
+
 TEGRA SUPPORT
 M:     Stephen Warren <swarren@wwwdotorg.org>
 L:     linux-tegra@vger.kernel.org
@@ -7426,6 +7607,14 @@ S:       Maintained
 F:     include/linux/shmem_fs.h
 F:     mm/shmem.c
 
+TM6000 VIDEO4LINUX DRIVER
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Odd fixes
+F:     drivers/media/usb/tm6000/
+
 TPM DEVICE DRIVER
 M:     Kent Yoder <key@linux.vnet.ibm.com>
 M:     Rajiv Andrade <mail@srajiv.net>
@@ -7820,7 +8009,7 @@ USB SN9C1xx DRIVER
 M:     Luca Risolia <luca.risolia@studio.unibo.it>
 L:     linux-usb@vger.kernel.org
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 W:     http://www.linux-projects.org
 S:     Maintained
 F:     Documentation/video4linux/sn9c102.txt
@@ -7856,10 +8045,11 @@ USB VIDEO CLASS
 M:     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 L:     linux-uvc-devel@lists.sourceforge.net (subscribers-only)
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 W:     http://www.ideasonboard.org/uvc/
 S:     Maintained
 F:     drivers/media/usb/uvc/
+F:     include/uapi/linux/uvcvideo.h
 
 USB WEBCAM GADGET
 M:     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
@@ -7891,7 +8081,7 @@ USB ZR364XX DRIVER
 M:     Antoine Jacquet <royale@zerezo.com>
 L:     linux-usb@vger.kernel.org
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
+T:     git git://linuxtv.org/media_tree.git
 W:     http://royale.zerezo.com/zr364xx/
 S:     Maintained
 F:     Documentation/video4linux/zr364xx.txt
@@ -8246,6 +8436,14 @@ L:       linux-edac@vger.kernel.org
 S:     Maintained
 F:     arch/x86/kernel/cpu/mcheck/*
 
+XC2028/3028 TUNER DRIVER
+M:     Mauro Carvalho Chehab <mchehab@redhat.com>
+L:     linux-media@vger.kernel.org
+W:     http://linuxtv.org
+T:     git git://linuxtv.org/media_tree.git
+S:     Maintained
+F:     drivers/media/tuners/tuner-xc2028.*
+
 XEN HYPERVISOR INTERFACE
 M:     Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 M:     Jeremy Fitzhardinge <jeremy@goop.org>
index c67a731cfbb708f9e36d5d8f843d3ffb6119fb31..4abb8b5e9bc09f8b514a3ad2958ef8a8dead7041 100644 (file)
@@ -202,6 +202,16 @@ static struct resource omap3isp_resources[] = {
                .end            = OMAP3630_ISP_CSI2C_REGS2_END,
                .flags          = IORESOURCE_MEM,
        },
+       {
+               .start          = OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE,
+               .end            = OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE + 3,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL,
+               .end            = OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL + 3,
+               .flags          = IORESOURCE_MEM,
+       },
        {
                .start          = 24 + OMAP_INTC_START,
                .flags          = IORESOURCE_IRQ,
index 113c57a035653aeb5215b1fcfefff7e12450e427..fb7f1d1627dc1d11863ae4bcaeeabb0bccda4524 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/pwm_backlight.h>
 
+#include <media/mt9v022.h>
 #include <media/soc_camera.h>
 
 #include <linux/platform_data/camera-pxa.h>
@@ -468,6 +469,10 @@ static struct i2c_board_info __initdata pcm990_i2c_devices[] = {
        },
 };
 
+static struct mt9v022_platform_data mt9v022_pdata = {
+       .y_skip_top = 1,
+};
+
 static struct i2c_board_info pcm990_camera_i2c[] = {
        {
                I2C_BOARD_INFO("mt9v022", 0x48),
@@ -480,6 +485,7 @@ static struct soc_camera_link iclink[] = {
        {
                .bus_id                 = 0, /* Must match with the camera ID */
                .board_info             = &pcm990_camera_i2c[0],
+               .priv                   = &mt9v022_pdata,
                .i2c_adapter_id         = 0,
                .query_bus_param        = pcm990_camera_query_bus_param,
                .set_bus_param          = pcm990_camera_set_bus_param,
index 3fbedc75e7c56219d1f0eafeabdebe9e058edc27..0ce39a33b3c2c2faf23746f662d609f22c7cf46b 100644 (file)
@@ -218,6 +218,8 @@ void dmam_release_declared_memory(struct device *dev)
 }
 EXPORT_SYMBOL(dmam_release_declared_memory);
 
+#endif
+
 /*
  * Create scatter-list for the already allocated DMA buffer.
  */
@@ -236,8 +238,6 @@ int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
 }
 EXPORT_SYMBOL(dma_common_get_sgtable);
 
-#endif
-
 /*
  * Create userspace mapping for the DMA-coherent memory.
  */
index 13ca9191b6309a9ff388dbd32dd2f584cb2fffa9..a79e95bb9fb69db2803a9f5c4ee8abccfbfc7f4b 100644 (file)
@@ -116,7 +116,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
 
        rdev->priv             = data;
        rdev->driver_type      = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos   = RC_TYPE_ALL;
+       rdev->allowed_protos   = RC_BIT_ALL;
        rdev->open             = picolcd_cir_open;
        rdev->close            = picolcd_cir_close;
        rdev->input_name       = data->hdev->name;
index 121b0110af3c525055e426bb7e206c02f2389c04..d2a436ce77f8c6098ceff2ce4f4d3c974f41b35b 100644 (file)
@@ -1,3 +1,10 @@
+# Used by common drivers, when they need to ask questions
+config MEDIA_COMMON_OPTIONS
+       bool
+
+comment "common driver options"
+       depends on MEDIA_COMMON_OPTIONS
+
 source "drivers/media/common/b2c2/Kconfig"
 source "drivers/media/common/saa7146/Kconfig"
 source "drivers/media/common/siano/Kconfig"
index 1df9e578daa5c5309fa5ee3db19df3de6da83857..a8c6cdfaa2f5b7dac8b204b1b37d29cfd34cd615 100644 (file)
@@ -17,11 +17,6 @@ config DVB_B2C2_FLEXCOP
        select DVB_CX24123 if MEDIA_SUBDRV_AUTOSELECT
        select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
        select DVB_TUNER_CX24113 if MEDIA_SUBDRV_AUTOSELECT
-       help
-         Support for the digital TV receiver chip made by B2C2 Inc. included in
-         Technisats PCI cards and USB boxes.
-
-         Say Y if you own such a device and want to use it.
 
 # Selected via the PCI or USB flexcop drivers
 config DVB_B2C2_FLEXCOP_DEBUG
index 425aeadfb49dea3f3727bfb5f4c27abf7212cba5..68f0f604678ecd33e197539001c0097b6156fd43 100644 (file)
@@ -4,14 +4,16 @@
 
 config SMS_SIANO_MDTV
        tristate
-       depends on DVB_CORE && RC_CORE && HAS_DMA
+       depends on DVB_CORE && HAS_DMA
+       depends on !RC_CORE || RC_CORE
        depends on SMS_USB_DRV || SMS_SDIO_DRV
        default y
-       ---help---
-         Choose Y or M here if you have MDTV receiver with a Siano chipset.
-
-         To compile this driver as a module, choose M here
-         (The module will be called smsmdtv).
 
-         Further documentation on this driver can be found on the WWW
-         at http://www.siano-ms.com/
+config SMS_SIANO_RC
+       bool "Enable Remote Controller support for Siano devices"
+       depends on SMS_SIANO_MDTV && RC_CORE
+       depends on SMS_USB_DRV || SMS_SDIO_DRV
+       depends on MEDIA_COMMON_OPTIONS
+       default y
+       ---help---
+         Choose Y to select Remote Controller support for Siano driver.
index 2a09279e0648edd912897140084e001820cbbbb0..81b1e985bea526d843ad233ee406ddd390811cf4 100644 (file)
@@ -1,7 +1,11 @@
-smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
+smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o
 
 obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
 
+ifeq ($(CONFIG_SMS_SIANO_RC),y)
+  smsmdtv-objs += smsir.o
+endif
+
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
 
index 9cc55546cc30b138660ddc5cdcb4f857003caf5d..1842e64e63383c0a87bb0b557d3a0fd7fad0250e 100644 (file)
@@ -1092,7 +1092,7 @@ EXPORT_SYMBOL_GPL(smscore_onresponse);
  * @return pointer to descriptor on success, NULL on error.
  */
 
-struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
+static struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
 {
        struct smscore_buffer_t *cb = NULL;
        unsigned long flags;
index 37bc5c4b8ad87541e568a3c968635d0b8a289318..b8c5cad78537209b2409e687a4a5eb23b4c51b93 100644 (file)
@@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
 
        dev->priv = coredev;
        dev->driver_type = RC_DRIVER_IR_RAW;
-       dev->allowed_protos = RC_TYPE_ALL;
+       dev->allowed_protos = RC_BIT_ALL;
        dev->map_name = sms_get_board(board_id)->rc_codes;
        dev->driver_name = MODULE_NAME;
 
index ae92b3a8587e5d4a32e7d5f2a8b35b047f71f2d8..69b59b9eee28efc5b79237ac751ddd37da2ee566 100644 (file)
@@ -46,10 +46,19 @@ struct ir_t {
        u32 controller;
 };
 
+#ifdef CONFIG_SMS_SIANO_RC
 int sms_ir_init(struct smscore_device_t *coredev);
 void sms_ir_exit(struct smscore_device_t *coredev);
 void sms_ir_event(struct smscore_device_t *coredev,
                        const char *buf, int len);
+#else
+inline static int sms_ir_init(struct smscore_device_t *coredev) {
+       return 0;
+}
+inline static void sms_ir_exit(struct smscore_device_t *coredev) {};
+inline static void sms_ir_event(struct smscore_device_t *coredev,
+                       const char *buf, int len) {};
+#endif
 
 #endif /* __SMS_IR_H__ */
 
index 889c9c16c6df81ec7e2175a3d4c1f858ef4f61c2..d81dbb22aa814fd0b92f8e9c089a9c2f2550ce16 100644 (file)
@@ -877,7 +877,7 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
        dvb_dmxdev_filter_stop(dmxdevfilter);
        dvb_dmxdev_filter_reset(dmxdevfilter);
 
-       if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
+       if ((unsigned)params->pes_type > DMX_PES_OTHER)
                return -EINVAL;
 
        dmxdevfilter->type = DMXDEV_TYPE_PES;
index 02ebe28f830d811b9ea7079ad450cc626a6b3863..48c6cf92ab994c896d9e0f2d155e532c0aa5c500 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
+#include <linux/time.h>
 #include <linux/timer.h>
 #include <linux/wait.h>
 #include <linux/fs.h>
index 58e0220447c012a5b9fc7bee807bda26468fb087..388c2eb4d7476b208f7c24c84d9aad96e6bbaa3b 100644 (file)
 #define USB_PID_TERRATEC_T3                            0x10a0
 #define USB_PID_TERRATEC_T5                            0x10a1
 #define USB_PID_NOXON_DAB_STICK                                0x00b3
+#define USB_PID_NOXON_DAB_STICK_REV2                   0x00e0
 #define USB_PID_PINNACLE_EXPRESSCARD_320CX             0x022e
 #define USB_PID_PINNACLE_PCTV2000E                     0x022c
 #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH              0x0228
index 7e92793260f0deffbf6bdb0a3024a95f3bf59ff5..49d95040096a42589627d7e3446df5f470c2f919 100644 (file)
@@ -1029,12 +1029,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
        /* Get */
        _DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
        _DTV_CMD(DTV_API_VERSION, 0, 0),
-       _DTV_CMD(DTV_CODE_RATE_HP, 0, 0),
-       _DTV_CMD(DTV_CODE_RATE_LP, 0, 0),
-       _DTV_CMD(DTV_GUARD_INTERVAL, 0, 0),
-       _DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0),
-       _DTV_CMD(DTV_HIERARCHY, 0, 0),
-       _DTV_CMD(DTV_INTERLEAVING, 0, 0),
 
        _DTV_CMD(DTV_ENUM_DELSYS, 0, 0),
 
@@ -1042,13 +1036,11 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
        _DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 1, 0),
 
        _DTV_CMD(DTV_ATSCMH_FIC_VER, 0, 0),
-       _DTV_CMD(DTV_ATSCMH_PARADE_ID, 0, 0),
        _DTV_CMD(DTV_ATSCMH_NOG, 0, 0),
        _DTV_CMD(DTV_ATSCMH_TNOG, 0, 0),
        _DTV_CMD(DTV_ATSCMH_SGN, 0, 0),
        _DTV_CMD(DTV_ATSCMH_PRC, 0, 0),
        _DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE, 0, 0),
-       _DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 0, 0),
        _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI, 0, 0),
        _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC, 0, 0),
        _DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE, 0, 0),
@@ -1056,8 +1048,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
        _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0),
        _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0),
        _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0),
-
-       _DTV_CMD(DTV_LNA, 0, 0),
 };
 
 static void dtv_property_dump(struct dvb_frontend *fe, struct dtv_property *tvp)
index f2a90f990ce330548079b7e5ce8e9b74f1a034c9..3d399d9a6343cb0d841d026ad27ca77dee96880b 100644 (file)
@@ -139,7 +139,7 @@ static int cx22700_set_tps(struct cx22700_state *state,
        if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
                return -EINVAL;
 
-       if (p->guard_interval < GUARD_INTERVAL_1_32 ||
+       if ((int)p->guard_interval < GUARD_INTERVAL_1_32 ||
            p->guard_interval > GUARD_INTERVAL_1_4)
                return -EINVAL;
 
@@ -152,7 +152,7 @@ static int cx22700_set_tps(struct cx22700_state *state,
            p->modulation != QAM_64)
                return -EINVAL;
 
-       if (p->hierarchy < HIERARCHY_NONE ||
+       if ((int)p->hierarchy < HIERARCHY_NONE ||
            p->hierarchy > HIERARCHY_4)
                return -EINVAL;
 
index 7e28b4ee7d4febb9f815ea569fbfc14f38764b6a..68c88ab58e712a342d482dc7016bd984216090bb 100644 (file)
@@ -338,7 +338,7 @@ static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec)
 {
        u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
 
-       if ((fec < FEC_NONE) || (fec > FEC_AUTO))
+       if (((int)fec < FEC_NONE) || (fec > FEC_AUTO))
                fec = FEC_AUTO;
 
        /* Set the soft decision threshold */
index b5781a48034c0979bf65ee0ae188200747dfa863..de1cc91fd83317252d2b06ab0b5f9ae6e9b6c461 100644 (file)
@@ -97,7 +97,7 @@ static inline int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb
        return -ENODEV;
 }
 
-int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
+static inline int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
 {
        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
        return -ENODEV;
index 6d9853750d2b6dd96080dc68fb0dc1496626ddf4..e71cc60851e7ad1391bb4f5e13695bfbf27640c6 100644 (file)
@@ -1748,7 +1748,8 @@ static int DRX_Stop(struct drxd_state *state)
        return status;
 }
 
-int SetOperationMode(struct drxd_state *state, int oMode)
+#if 0  /* Currently unused */
+static int SetOperationMode(struct drxd_state *state, int oMode)
 {
        int status;
 
@@ -1788,6 +1789,7 @@ int SetOperationMode(struct drxd_state *state, int oMode)
                state->operation_mode = oMode;
        return status;
 }
+#endif
 
 static int StartDiversity(struct drxd_state *state)
 {
@@ -2612,7 +2614,7 @@ static int CDRXD(struct drxd_state *state, u32 IntermediateFrequency)
        return 0;
 }
 
-int DRXD_init(struct drxd_state *state, const u8 * fw, u32 fw_size)
+static int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
 {
        int status = 0;
        u32 driverVersion;
@@ -2774,7 +2776,7 @@ int DRXD_init(struct drxd_state *state, const u8 * fw, u32 fw_size)
        return status;
 }
 
-int DRXD_status(struct drxd_state *state, u32 * pLockStatus)
+static int DRXD_status(struct drxd_state *state, u32 *pLockStatus)
 {
        DRX_GetLockStatus(state, pLockStatus);
 
index df9abe83f8773efe38eda6d6f349399ec107df4d..c2fc7da0d6bf9de76ac14e0cf128e3c89cd091af 100644 (file)
@@ -65,16 +65,6 @@ static bool IsQAM(struct drxk_state *state)
            state->m_OperationMode == OM_QAM_ITU_C;
 }
 
-bool IsA1WithPatchCode(struct drxk_state *state)
-{
-       return state->m_DRXK_A1_PATCH_CODE;
-}
-
-bool IsA1WithRomCode(struct drxk_state *state)
-{
-       return state->m_DRXK_A1_ROM_CODE;
-}
-
 #define NOA1ROM 0
 
 #define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
@@ -189,7 +179,7 @@ static inline u32 MulDiv32(u32 a, u32 b, u32 c)
        return (u32) tmp64;
 }
 
-inline u32 Frac28a(u32 a, u32 c)
+static inline u32 Frac28a(u32 a, u32 c)
 {
        int i = 0;
        u32 Q1 = 0;
@@ -587,7 +577,7 @@ static int write_block(struct drxk_state *state, u32 Address,
 #define DRXK_MAX_RETRIES_POWERUP 20
 #endif
 
-int PowerUpDevice(struct drxk_state *state)
+static int PowerUpDevice(struct drxk_state *state)
 {
        int status;
        u8 data = 0;
@@ -720,11 +710,6 @@ static int init_state(struct drxk_state *state)
 
        state->m_bPowerDown = (ulPowerDown != 0);
 
-       state->m_DRXK_A1_PATCH_CODE = false;
-       state->m_DRXK_A1_ROM_CODE = false;
-       state->m_DRXK_A2_ROM_CODE = false;
-       state->m_DRXK_A3_ROM_CODE = false;
-       state->m_DRXK_A2_PATCH_CODE = false;
        state->m_DRXK_A3_PATCH_CODE = false;
 
        /* Init AGC and PGA parameters */
@@ -921,7 +906,7 @@ static int GetDeviceCapabilities(struct drxk_state *state)
        status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
        if (status < 0)
                goto error;
-       status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
+       status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
        if (status < 0)
                goto error;
        status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
@@ -1217,7 +1202,7 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
                goto error;
 
        /*  MPEG TS pad configuration */
-       status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
+       status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
        if (status < 0)
                goto error;
 
@@ -5461,6 +5446,7 @@ static int QAMDemodulatorCommand(struct drxk_state *state,
        } else {
                printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
                        "count %d\n", numberOfParameters);
+               status = -EINVAL;
        }
 
 error:
index 6bb9fc4a7b96cbeeb6a082503499fbff18feb4d2..d18a896a983542f13dccc4269db3478c4b5ea61e 100644 (file)
@@ -320,11 +320,7 @@ struct drxk_state {
 
        u8               *m_microcode;
        int               m_microcode_length;
-       bool              m_DRXK_A1_PATCH_CODE;
-       bool              m_DRXK_A1_ROM_CODE;
-       bool              m_DRXK_A2_ROM_CODE;
-       bool              m_DRXK_A3_ROM_CODE;
-       bool              m_DRXK_A2_PATCH_CODE;
+       bool              m_DRXK_A3_ROM_CODE;
        bool              m_DRXK_A3_PATCH_CODE;
 
        bool              m_rfmirror;
index 5b639087ce45623f7a2f1be7e1b6216c1bc686a8..60a529e3833fdbba325da8bd035d18ca67231331 100644 (file)
@@ -30,7 +30,6 @@
 #include "ds3000.h"
 
 static int debug;
-static int force_fw_upload;
 
 #define dprintk(args...) \
        do { \
@@ -234,7 +233,6 @@ struct ds3000_state {
        struct i2c_adapter *i2c;
        const struct ds3000_config *config;
        struct dvb_frontend frontend;
-       u8 skip_fw_load;
        /* previous uncorrected block counter for DVB-S2 */
        u16 prevUCBS2;
 };
@@ -397,9 +395,6 @@ static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
        if (ret < 0)
                return ret;
 
-       if (state->skip_fw_load || !force_fw_upload)
-               return 0;       /* Firmware already uploaded, skipping */
-
        /* Load firmware */
        /* request the firmware, this will block until someone uploads it */
        printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
@@ -413,9 +408,6 @@ static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
                return ret;
        }
 
-       /* Make sure we don't recurse back through here during loading */
-       state->skip_fw_load = 1;
-
        ret = ds3000_load_firmware(fe, fw);
        if (ret)
                printk("%s: Writing firmware to device failed\n", __func__);
@@ -425,9 +417,6 @@ static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
        dprintk("%s: Firmware upload %s\n", __func__,
                        ret == 0 ? "complete" : "failed");
 
-       /* Ensure firmware is always loaded if required */
-       state->skip_fw_load = 0;
-
        return ret;
 }
 
@@ -1309,10 +1298,8 @@ static struct dvb_frontend_ops ds3000_ops = {
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
 
-module_param(force_fw_upload, int, 0644);
-MODULE_PARM_DESC(force_fw_upload, "Force firmware upload (default:0)");
-
 MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
                        "DS3000/TS2020 hardware");
 MODULE_AUTHOR("Konstantin Dimitrov");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(DS3000_DEFAULT_FIRMWARE);
index 36fcf559e3619147da5dde357aba6267213357fa..ddf866c46f8b170c066352dc39aeb9112adf52bb 100644 (file)
@@ -180,11 +180,11 @@ static int apply_frontend_param(struct dvb_frontend *fe)
            p->transmission_mode != TRANSMISSION_MODE_8K)
                return -EINVAL;
 
-       if (p->guard_interval < GUARD_INTERVAL_1_32 ||
+       if ((int)p->guard_interval < GUARD_INTERVAL_1_32 ||
            p->guard_interval > GUARD_INTERVAL_1_4)
                return -EINVAL;
 
-       if (p->hierarchy < HIERARCHY_NONE ||
+       if ((int)p->hierarchy < HIERARCHY_NONE ||
            p->hierarchy > HIERARCHY_4)
                return -EINVAL;
 
index e20bf13aa860bb03f2d07945bf04497c6981eb2f..ec388c1d6913c73c9458d43695793ff833fcbd67 100644 (file)
@@ -549,7 +549,7 @@ static int mt312_set_frontend(struct dvb_frontend *fe)
            || (p->frequency > fe->ops.info.frequency_max))
                return -EINVAL;
 
-       if ((p->inversion < INVERSION_OFF)
+       if (((int)p->inversion < INVERSION_OFF)
            || (p->inversion > INVERSION_ON))
                return -EINVAL;
 
@@ -557,7 +557,7 @@ static int mt312_set_frontend(struct dvb_frontend *fe)
            || (p->symbol_rate > fe->ops.info.symbol_rate_max))
                return -EINVAL;
 
-       if ((p->fec_inner < FEC_NONE)
+       if (((int)p->fec_inner < FEC_NONE)
            || (p->fec_inner > FEC_AUTO))
                return -EINVAL;
 
index b0f6ec03d1eb0e4b1e10444e63b482ca945d5a6c..362d26d11e82a4d1f975db097679c7d4bb7ddb97 100644 (file)
@@ -130,7 +130,7 @@ static int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val)
 }
 
 /* write single register with mask */
-int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask)
+static int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask)
 {
        int ret;
        u8 tmp;
@@ -150,7 +150,7 @@ int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask)
 }
 
 /* read single register with mask */
-int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask)
+static int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask)
 {
        int ret, i;
        u8 tmp;
@@ -256,7 +256,7 @@ static int rtl2830_sleep(struct dvb_frontend *fe)
        return 0;
 }
 
-int rtl2830_get_tune_settings(struct dvb_frontend *fe,
+static int rtl2830_get_tune_settings(struct dvb_frontend *fe,
        struct dvb_frontend_tune_settings *s)
 {
        s->min_delay_ms = 500;
index 80c8e5f1182fdc377a7e6ac83ff3e2efc8e523c8..73887690b0464b2f046c92028873ebc18341d041 100644 (file)
@@ -265,7 +265,7 @@ static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
        return rtl2832_rd_regs(priv, reg, page, val, 1);
 }
 
-int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
+static int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
 {
        int ret;
 
@@ -305,7 +305,7 @@ err:
 
 }
 
-int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
+static int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
 {
        int ret, i;
        u8 len;
@@ -510,7 +510,7 @@ static int rtl2832_sleep(struct dvb_frontend *fe)
        return 0;
 }
 
-int rtl2832_get_tune_settings(struct dvb_frontend *fe,
+static int rtl2832_get_tune_settings(struct dvb_frontend *fe,
        struct dvb_frontend_tune_settings *s)
 {
        struct rtl2832_priv *priv = fe->demodulator_priv;
index 79e29de87fb7b50feb4f2fd65bed5e00c6b6ac8d..cc278b3d6d5a4338e7c97685f4e59c94f8e351cb 100644 (file)
@@ -1260,7 +1260,7 @@ static inline void CONVERT32(u32 x, char *str)
        *str    = '\0';
 }
 
-int stb0899_get_dev_id(struct stb0899_state *state)
+static int stb0899_get_dev_id(struct stb0899_state *state)
 {
        u8 chip_id, release;
        u16 id;
index 2a8aaeb1112dc10ef1267531c36eb14bbd1c8989..0c8e45949b11f018b9850ce387a6ddb2b2b4aeaf 100644 (file)
@@ -879,7 +879,8 @@ static u8 stv0367_readbits(struct stv0367_state *state, u32 label)
        return val;
 }
 
-u8 stv0367_getbits(u8 reg, u32 label)
+#if 0 /* Currently, unused */
+static u8 stv0367_getbits(u8 reg, u32 label)
 {
        u8 mask, pos;
 
@@ -887,7 +888,7 @@ u8 stv0367_getbits(u8 reg, u32 label)
 
        return (reg & mask) >> pos;
 }
-
+#endif
 static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
        struct stv0367_state *state = fe->demodulator_priv;
@@ -1263,8 +1264,8 @@ stv0367_ter_signal_type stv0367ter_check_cpamp(struct stv0367_state *state,
        return CPAMPStatus;
 }
 
-enum
-stv0367_ter_signal_type stv0367ter_lock_algo(struct stv0367_state *state)
+static enum stv0367_ter_signal_type
+stv0367ter_lock_algo(struct stv0367_state *state)
 {
        enum stv0367_ter_signal_type ret_flag;
        short int wd, tempo;
@@ -1528,7 +1529,7 @@ static int stv0367ter_sleep(struct dvb_frontend *fe)
        return stv0367ter_standby(fe, 1);
 }
 
-int stv0367ter_init(struct dvb_frontend *fe)
+static int stv0367ter_init(struct dvb_frontend *fe)
 {
        struct stv0367_state *state = fe->demodulator_priv;
        struct stv0367ter_state *ter_state = state->ter_state;
@@ -2378,9 +2379,9 @@ static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz)
        return ADCClk_Hz;
 }
 
-enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
-                                       u32 SymbolRate,
-                                       enum stv0367cab_mod QAMSize)
+static enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
+                                                u32 SymbolRate,
+                                                enum stv0367cab_mod QAMSize)
 {
        /* Set QAM size */
        stv0367_writebits(state, F367CAB_QAM_MODE, QAMSize);
@@ -2762,7 +2763,7 @@ static int stv0367cab_sleep(struct dvb_frontend *fe)
        return stv0367cab_standby(fe, 1);
 }
 
-int stv0367cab_init(struct dvb_frontend *fe)
+static int stv0367cab_init(struct dvb_frontend *fe)
 {
        struct stv0367_state *state = fe->demodulator_priv;
        struct stv0367cab_state *cab_state = state->cab_state;
index a83bf680234529a8504b6e3439e6b5f21fa3824b..16a4bc54dbe79acefc0c63789c05c6f21d0d977b 100644 (file)
@@ -96,7 +96,8 @@ static int tda10071_rd_reg(struct tda10071_priv *priv, u8 reg, u8 *val)
 }
 
 /* write single register with mask */
-int tda10071_wr_reg_mask(struct tda10071_priv *priv, u8 reg, u8 val, u8 mask)
+static int tda10071_wr_reg_mask(struct tda10071_priv *priv,
+                               u8 reg, u8 val, u8 mask)
 {
        int ret;
        u8 tmp;
@@ -116,7 +117,8 @@ int tda10071_wr_reg_mask(struct tda10071_priv *priv, u8 reg, u8 val, u8 mask)
 }
 
 /* read single register with mask */
-int tda10071_rd_reg_mask(struct tda10071_priv *priv, u8 reg, u8 *val, u8 mask)
+static int tda10071_rd_reg_mask(struct tda10071_priv *priv,
+                               u8 reg, u8 *val, u8 mask)
 {
        int ret, i;
        u8 tmp;
index ad7c72e8f517728539f93adde89f63ddf980d137..d281f77d5c2898e7d5da365afea9ca5e7bba8a7e 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/div64.h>
 
 #include "dvb_frontend.h"
+#include "tda18271c2dd.h"
 
 struct SStandardParam {
        s32   m_IFFrequency;
index 4fdcd8cb753010416bbbf1d7c271208541b4b157..c2ba085e0d20d10717adb63c362028b320d25007 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef _FIREDTV_H
 #define _FIREDTV_H
 
+#include <linux/time.h>
 #include <linux/dvb/dmx.h>
 #include <linux/dvb/frontend.h>
 #include <linux/list.h>
index 18a38b38fcb8c9796b16549b2707c8551b6f86fa..df163800c8e1e5ec7f7ffe035e8888552da8cc1f 100644 (file)
@@ -3,10 +3,10 @@
  *
  * Copyright (C) 2008--2011 Nokia Corporation
  *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
  *
  * Contributors:
- *     Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ *     Sakari Ailus <sakari.ailus@iki.fi>
  *     Tuukka Toivonen <tuukkat76@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
index e1d4c89d7140ec6360a823116b15f49b776424e3..10c3c1db4cdd1a473232027c602de8b3513ecb58 100644 (file)
@@ -681,18 +681,7 @@ static struct i2c_driver adv7183_driver = {
        .id_table       = adv7183_id,
 };
 
-static __init int adv7183_init(void)
-{
-       return i2c_add_driver(&adv7183_driver);
-}
-
-static __exit void adv7183_exit(void)
-{
-       i2c_del_driver(&adv7183_driver);
-}
-
-module_init(adv7183_init);
-module_exit(adv7183_exit);
+module_i2c_driver(adv7183_driver);
 
 MODULE_DESCRIPTION("Analog Devices ADV7183 video decoder driver");
 MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
index 05f8950f6f91b54cbad5f195fcfecd3cc6a784c1..f47555b1000aa13238e07b94a8116f080ca90f79 100644 (file)
@@ -486,9 +486,19 @@ static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val)
        struct i2c_client *client = state->i2c_edid;
        u8 msgbuf0[1] = { 0 };
        u8 msgbuf1[256];
-       struct i2c_msg msg[2] = { { client->addr, 0, 1, msgbuf0 },
-                                 { client->addr, 0 | I2C_M_RD, len, msgbuf1 }
-                               };
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = client->addr,
+                       .len = 1,
+                       .buf = msgbuf0
+               },
+               {
+                       .addr = client->addr,
+                       .flags = I2C_M_RD,
+                       .len = len,
+                       .buf = msgbuf1
+               },
+       };
 
        if (i2c_transfer(client->adapter, msg, 2) < 0)
                return -EIO;
index 2cee69e34184304b7824752aadfd14d4b1d205b8..f4149eb4d7b4f545e647321f79344786d743a17a 100644 (file)
@@ -2065,7 +2065,7 @@ static int cx25840_irq_handler(struct v4l2_subdev *sd, u32 status,
 #define DIF_BPF_COEFF3435      (0x38c)
 #define DIF_BPF_COEFF36                (0x390)
 
-void cx23885_dif_setup(struct i2c_client *client, u32 ifHz)
+static void cx23885_dif_setup(struct i2c_client *client, u32 ifHz)
 {
        u64 pll_freq;
        u32 pll_freq_word;
index 04f192a0398a2d025faa504fd890deeac84473c6..08ae067b2b6f19f503e46bf186105dbea61a9194 100644 (file)
@@ -284,7 +284,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
        char *ir_codes = NULL;
        const char *name = NULL;
-       u64 rc_type = RC_TYPE_UNKNOWN;
+       u64 rc_type = RC_BIT_UNKNOWN;
        struct IR_i2c *ir;
        struct rc_dev *rc = NULL;
        struct i2c_adapter *adap = client->adapter;
@@ -303,7 +303,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
        case 0x64:
                name        = "Pixelview";
                ir->get_key = get_key_pixelview;
-               rc_type     = RC_TYPE_OTHER;
+               rc_type     = RC_BIT_OTHER;
                ir_codes    = RC_MAP_EMPTY;
                break;
        case 0x18:
@@ -311,31 +311,31 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
        case 0x1a:
                name        = "Hauppauge";
                ir->get_key = get_key_haup;
-               rc_type     = RC_TYPE_RC5;
+               rc_type     = RC_BIT_RC5;
                ir_codes    = RC_MAP_HAUPPAUGE;
                break;
        case 0x30:
                name        = "KNC One";
                ir->get_key = get_key_knc1;
-               rc_type     = RC_TYPE_OTHER;
+               rc_type     = RC_BIT_OTHER;
                ir_codes    = RC_MAP_EMPTY;
                break;
        case 0x6b:
                name        = "FusionHDTV";
                ir->get_key = get_key_fusionhdtv;
-               rc_type     = RC_TYPE_RC5;
+               rc_type     = RC_BIT_RC5;
                ir_codes    = RC_MAP_FUSIONHDTV_MCE;
                break;
        case 0x40:
                name        = "AVerMedia Cardbus remote";
                ir->get_key = get_key_avermedia_cardbus;
-               rc_type     = RC_TYPE_OTHER;
+               rc_type     = RC_BIT_OTHER;
                ir_codes    = RC_MAP_AVERMEDIA_CARDBUS;
                break;
        case 0x71:
                name        = "Hauppauge/Zilog Z8";
                ir->get_key = get_key_haup_xvr;
-               rc_type     = RC_TYPE_RC5;
+               rc_type     = RC_BIT_RC5;
                ir_codes    = RC_MAP_HAUPPAUGE;
                break;
        }
index 49c1b3abb4252c33fc8635f215ba080b640a73d1..2750de63427059ce3d286d1bc27905abeed95542 100644 (file)
@@ -343,7 +343,7 @@ static int s5k4ecgx_load_firmware(struct v4l2_subdev *sd)
        }
        regs_num = le32_to_cpu(get_unaligned_le32(fw->data));
 
-       v4l2_dbg(3, debug, sd, "FW: %s size %d register sets %d\n",
+       v4l2_dbg(3, debug, sd, "FW: %s size %zu register sets %d\n",
                 S5K4ECGX_FIRMWARE, fw->size, regs_num);
 
        regs_num++; /* Add header */
index a577614bd84f53113470c085e4e1cd221d761a14..d8d5da7c52dbb50759915ea7c76ca9c56c41a923 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
@@ -58,7 +58,7 @@ static int bounds_check(struct device *dev, uint32_t val,
        if (val >= min && val <= max)
                return 0;
 
-       dev_warn(dev, "%s out of bounds: %d (%d--%d)\n", str, val, min, max);
+       dev_dbg(dev, "%s out of bounds: %d (%d--%d)\n", str, val, min, max);
 
        return -EINVAL;
 }
@@ -87,14 +87,14 @@ static void print_pll(struct device *dev, struct smiapp_pll *pll)
        dev_dbg(dev, "vt_pix_clk_freq_hz \t%d\n", pll->vt_pix_clk_freq_hz);
 }
 
-int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
-                        struct smiapp_pll *pll)
+static int __smiapp_pll_calculate(struct device *dev,
+                                 const struct smiapp_pll_limits *limits,
+                                 struct smiapp_pll *pll, uint32_t mul,
+                                 uint32_t div, uint32_t lane_op_clock_ratio)
 {
        uint32_t sys_div;
        uint32_t best_pix_div = INT_MAX >> 1;
        uint32_t vt_op_binning_div;
-       uint32_t lane_op_clock_ratio;
-       uint32_t mul, div;
        uint32_t more_mul_min, more_mul_max;
        uint32_t more_mul_factor;
        uint32_t min_vt_div, max_vt_div, vt_div;
@@ -102,54 +102,6 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
        unsigned int i;
        int rval;
 
-       if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE)
-               lane_op_clock_ratio = pll->lanes;
-       else
-               lane_op_clock_ratio = 1;
-       dev_dbg(dev, "lane_op_clock_ratio: %d\n", lane_op_clock_ratio);
-
-       dev_dbg(dev, "binning: %dx%d\n", pll->binning_horizontal,
-               pll->binning_vertical);
-
-       /* CSI transfers 2 bits per clock per lane; thus times 2 */
-       pll->pll_op_clk_freq_hz = pll->link_freq * 2
-               * (pll->lanes / lane_op_clock_ratio);
-
-       /* Figure out limits for pre-pll divider based on extclk */
-       dev_dbg(dev, "min / max pre_pll_clk_div: %d / %d\n",
-               limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
-       limits->max_pre_pll_clk_div =
-               min_t(uint16_t, limits->max_pre_pll_clk_div,
-                     clk_div_even(pll->ext_clk_freq_hz /
-                                  limits->min_pll_ip_freq_hz));
-       limits->min_pre_pll_clk_div =
-               max_t(uint16_t, limits->min_pre_pll_clk_div,
-                     clk_div_even_up(
-                             DIV_ROUND_UP(pll->ext_clk_freq_hz,
-                                          limits->max_pll_ip_freq_hz)));
-       dev_dbg(dev, "pre-pll check: min / max pre_pll_clk_div: %d / %d\n",
-               limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
-
-       i = gcd(pll->pll_op_clk_freq_hz, pll->ext_clk_freq_hz);
-       mul = div_u64(pll->pll_op_clk_freq_hz, i);
-       div = pll->ext_clk_freq_hz / i;
-       dev_dbg(dev, "mul %d / div %d\n", mul, div);
-
-       limits->min_pre_pll_clk_div =
-               max_t(uint16_t, limits->min_pre_pll_clk_div,
-                     clk_div_even_up(
-                             DIV_ROUND_UP(mul * pll->ext_clk_freq_hz,
-                                          limits->max_pll_op_freq_hz)));
-       dev_dbg(dev, "pll_op check: min / max pre_pll_clk_div: %d / %d\n",
-               limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
-
-       if (limits->min_pre_pll_clk_div > limits->max_pre_pll_clk_div) {
-               dev_err(dev, "unable to compute pre_pll divisor\n");
-               return -EINVAL;
-       }
-
-       pll->pre_pll_clk_div = limits->min_pre_pll_clk_div;
-
        /*
         * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be
         * too high.
@@ -162,7 +114,7 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
                more_mul_max);
        /* Don't go above max pll op frequency. */
        more_mul_max =
-               min_t(int,
+               min_t(uint32_t,
                      more_mul_max,
                      limits->max_pll_op_freq_hz
                      / (pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul));
@@ -170,7 +122,7 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
                more_mul_max);
        /* Don't go above the division capability of op sys clock divider. */
        more_mul_max = min(more_mul_max,
-                          limits->max_op_sys_clk_div * pll->pre_pll_clk_div
+                          limits->op.max_sys_clk_div * pll->pre_pll_clk_div
                           / div);
        dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %d\n",
                more_mul_max);
@@ -193,14 +145,14 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
                more_mul_min);
 
        if (more_mul_min > more_mul_max) {
-               dev_warn(dev,
-                        "unable to compute more_mul_min and more_mul_max");
+               dev_dbg(dev,
+                       "unable to compute more_mul_min and more_mul_max\n");
                return -EINVAL;
        }
 
        more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div;
        dev_dbg(dev, "more_mul_factor: %d\n", more_mul_factor);
-       more_mul_factor = lcm(more_mul_factor, limits->min_op_sys_clk_div);
+       more_mul_factor = lcm(more_mul_factor, limits->op.min_sys_clk_div);
        dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n",
                more_mul_factor);
        i = roundup(more_mul_min, more_mul_factor);
@@ -209,7 +161,7 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
 
        dev_dbg(dev, "final more_mul: %d\n", i);
        if (i > more_mul_max) {
-               dev_warn(dev, "final more_mul is bad, max %d", more_mul_max);
+               dev_dbg(dev, "final more_mul is bad, max %d\n", more_mul_max);
                return -EINVAL;
        }
 
@@ -268,19 +220,19 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
        dev_dbg(dev, "min_vt_div: %d\n", min_vt_div);
        min_vt_div = max(min_vt_div,
                         DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
-                                     limits->max_vt_pix_clk_freq_hz));
+                                     limits->vt.max_pix_clk_freq_hz));
        dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %d\n",
                min_vt_div);
        min_vt_div = max_t(uint32_t, min_vt_div,
-                          limits->min_vt_pix_clk_div
-                          * limits->min_vt_sys_clk_div);
+                          limits->vt.min_pix_clk_div
+                          * limits->vt.min_sys_clk_div);
        dev_dbg(dev, "min_vt_div: min_vt_clk_div: %d\n", min_vt_div);
 
-       max_vt_div = limits->max_vt_sys_clk_div * limits->max_vt_pix_clk_div;
+       max_vt_div = limits->vt.max_sys_clk_div * limits->vt.max_pix_clk_div;
        dev_dbg(dev, "max_vt_div: %d\n", max_vt_div);
        max_vt_div = min(max_vt_div,
                         DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
-                                     limits->min_vt_pix_clk_freq_hz));
+                                     limits->vt.min_pix_clk_freq_hz));
        dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %d\n",
                max_vt_div);
 
@@ -288,28 +240,28 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
         * Find limitsits for sys_clk_div. Not all values are possible
         * with all values of pix_clk_div.
         */
-       min_sys_div = limits->min_vt_sys_clk_div;
+       min_sys_div = limits->vt.min_sys_clk_div;
        dev_dbg(dev, "min_sys_div: %d\n", min_sys_div);
        min_sys_div = max(min_sys_div,
                          DIV_ROUND_UP(min_vt_div,
-                                      limits->max_vt_pix_clk_div));
+                                      limits->vt.max_pix_clk_div));
        dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %d\n", min_sys_div);
        min_sys_div = max(min_sys_div,
                          pll->pll_op_clk_freq_hz
-                         / limits->max_vt_sys_clk_freq_hz);
+                         / limits->vt.max_sys_clk_freq_hz);
        dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %d\n", min_sys_div);
        min_sys_div = clk_div_even_up(min_sys_div);
        dev_dbg(dev, "min_sys_div: one or even: %d\n", min_sys_div);
 
-       max_sys_div = limits->max_vt_sys_clk_div;
+       max_sys_div = limits->vt.max_sys_clk_div;
        dev_dbg(dev, "max_sys_div: %d\n", max_sys_div);
        max_sys_div = min(max_sys_div,
                          DIV_ROUND_UP(max_vt_div,
-                                      limits->min_vt_pix_clk_div));
+                                      limits->vt.min_pix_clk_div));
        dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %d\n", max_sys_div);
        max_sys_div = min(max_sys_div,
                          DIV_ROUND_UP(pll->pll_op_clk_freq_hz,
-                                      limits->min_vt_pix_clk_freq_hz));
+                                      limits->vt.min_pix_clk_freq_hz));
        dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %d\n", max_sys_div);
 
        /*
@@ -322,15 +274,15 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
                for (sys_div = min_sys_div;
                     sys_div <= max_sys_div;
                     sys_div += 2 - (sys_div & 1)) {
-                       int pix_div = DIV_ROUND_UP(vt_div, sys_div);
+                       uint16_t pix_div = DIV_ROUND_UP(vt_div, sys_div);
 
-                       if (pix_div < limits->min_vt_pix_clk_div
-                           || pix_div > limits->max_vt_pix_clk_div) {
+                       if (pix_div < limits->vt.min_pix_clk_div
+                           || pix_div > limits->vt.max_pix_clk_div) {
                                dev_dbg(dev,
                                        "pix_div %d too small or too big (%d--%d)\n",
                                        pix_div,
-                                       limits->min_vt_pix_clk_div,
-                                       limits->max_vt_pix_clk_div);
+                                       limits->vt.min_pix_clk_div,
+                                       limits->vt.max_pix_clk_div);
                                continue;
                        }
 
@@ -354,16 +306,10 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
        pll->pixel_rate_csi =
                pll->op_pix_clk_freq_hz * lane_op_clock_ratio;
 
-       print_pll(dev, pll);
-
-       rval = bounds_check(dev, pll->pre_pll_clk_div,
-                           limits->min_pre_pll_clk_div,
-                           limits->max_pre_pll_clk_div, "pre_pll_clk_div");
-       if (!rval)
-               rval = bounds_check(
-                       dev, pll->pll_ip_clk_freq_hz,
-                       limits->min_pll_ip_freq_hz, limits->max_pll_ip_freq_hz,
-                       "pll_ip_clk_freq_hz");
+       rval = bounds_check(dev, pll->pll_ip_clk_freq_hz,
+                           limits->min_pll_ip_freq_hz,
+                           limits->max_pll_ip_freq_hz,
+                           "pll_ip_clk_freq_hz");
        if (!rval)
                rval = bounds_check(
                        dev, pll->pll_multiplier,
@@ -377,42 +323,121 @@ int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
        if (!rval)
                rval = bounds_check(
                        dev, pll->op_sys_clk_div,
-                       limits->min_op_sys_clk_div, limits->max_op_sys_clk_div,
+                       limits->op.min_sys_clk_div, limits->op.max_sys_clk_div,
                        "op_sys_clk_div");
        if (!rval)
                rval = bounds_check(
                        dev, pll->op_pix_clk_div,
-                       limits->min_op_pix_clk_div, limits->max_op_pix_clk_div,
+                       limits->op.min_pix_clk_div, limits->op.max_pix_clk_div,
                        "op_pix_clk_div");
        if (!rval)
                rval = bounds_check(
                        dev, pll->op_sys_clk_freq_hz,
-                       limits->min_op_sys_clk_freq_hz,
-                       limits->max_op_sys_clk_freq_hz,
+                       limits->op.min_sys_clk_freq_hz,
+                       limits->op.max_sys_clk_freq_hz,
                        "op_sys_clk_freq_hz");
        if (!rval)
                rval = bounds_check(
                        dev, pll->op_pix_clk_freq_hz,
-                       limits->min_op_pix_clk_freq_hz,
-                       limits->max_op_pix_clk_freq_hz,
+                       limits->op.min_pix_clk_freq_hz,
+                       limits->op.max_pix_clk_freq_hz,
                        "op_pix_clk_freq_hz");
        if (!rval)
                rval = bounds_check(
                        dev, pll->vt_sys_clk_freq_hz,
-                       limits->min_vt_sys_clk_freq_hz,
-                       limits->max_vt_sys_clk_freq_hz,
+                       limits->vt.min_sys_clk_freq_hz,
+                       limits->vt.max_sys_clk_freq_hz,
                        "vt_sys_clk_freq_hz");
        if (!rval)
                rval = bounds_check(
                        dev, pll->vt_pix_clk_freq_hz,
-                       limits->min_vt_pix_clk_freq_hz,
-                       limits->max_vt_pix_clk_freq_hz,
+                       limits->vt.min_pix_clk_freq_hz,
+                       limits->vt.max_pix_clk_freq_hz,
                        "vt_pix_clk_freq_hz");
 
        return rval;
 }
+
+int smiapp_pll_calculate(struct device *dev,
+                        const struct smiapp_pll_limits *limits,
+                        struct smiapp_pll *pll)
+{
+       uint16_t min_pre_pll_clk_div;
+       uint16_t max_pre_pll_clk_div;
+       uint32_t lane_op_clock_ratio;
+       uint32_t mul, div;
+       unsigned int i;
+       int rval = -EINVAL;
+
+       if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE)
+               lane_op_clock_ratio = pll->csi2.lanes;
+       else
+               lane_op_clock_ratio = 1;
+       dev_dbg(dev, "lane_op_clock_ratio: %d\n", lane_op_clock_ratio);
+
+       dev_dbg(dev, "binning: %dx%d\n", pll->binning_horizontal,
+               pll->binning_vertical);
+
+       switch (pll->bus_type) {
+       case SMIAPP_PLL_BUS_TYPE_CSI2:
+               /* CSI transfers 2 bits per clock per lane; thus times 2 */
+               pll->pll_op_clk_freq_hz = pll->link_freq * 2
+                       * (pll->csi2.lanes / lane_op_clock_ratio);
+               break;
+       case SMIAPP_PLL_BUS_TYPE_PARALLEL:
+               pll->pll_op_clk_freq_hz = pll->link_freq * pll->bits_per_pixel
+                       / DIV_ROUND_UP(pll->bits_per_pixel,
+                                      pll->parallel.bus_width);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Figure out limits for pre-pll divider based on extclk */
+       dev_dbg(dev, "min / max pre_pll_clk_div: %d / %d\n",
+               limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div);
+       max_pre_pll_clk_div =
+               min_t(uint16_t, limits->max_pre_pll_clk_div,
+                     clk_div_even(pll->ext_clk_freq_hz /
+                                  limits->min_pll_ip_freq_hz));
+       min_pre_pll_clk_div =
+               max_t(uint16_t, limits->min_pre_pll_clk_div,
+                     clk_div_even_up(
+                             DIV_ROUND_UP(pll->ext_clk_freq_hz,
+                                          limits->max_pll_ip_freq_hz)));
+       dev_dbg(dev, "pre-pll check: min / max pre_pll_clk_div: %d / %d\n",
+               min_pre_pll_clk_div, max_pre_pll_clk_div);
+
+       i = gcd(pll->pll_op_clk_freq_hz, pll->ext_clk_freq_hz);
+       mul = div_u64(pll->pll_op_clk_freq_hz, i);
+       div = pll->ext_clk_freq_hz / i;
+       dev_dbg(dev, "mul %d / div %d\n", mul, div);
+
+       min_pre_pll_clk_div =
+               max_t(uint16_t, min_pre_pll_clk_div,
+                     clk_div_even_up(
+                             DIV_ROUND_UP(mul * pll->ext_clk_freq_hz,
+                                          limits->max_pll_op_freq_hz)));
+       dev_dbg(dev, "pll_op check: min / max pre_pll_clk_div: %d / %d\n",
+               min_pre_pll_clk_div, max_pre_pll_clk_div);
+
+       for (pll->pre_pll_clk_div = min_pre_pll_clk_div;
+            pll->pre_pll_clk_div <= max_pre_pll_clk_div;
+            pll->pre_pll_clk_div += 2 - (pll->pre_pll_clk_div & 1)) {
+               rval = __smiapp_pll_calculate(dev, limits, pll, mul, div,
+                                             lane_op_clock_ratio);
+               if (rval)
+                       continue;
+
+               print_pll(dev, pll);
+               return 0;
+       }
+
+       dev_info(dev, "unable to compute pre_pll divisor\n");
+       return rval;
+}
 EXPORT_SYMBOL_GPL(smiapp_pll_calculate);
 
-MODULE_AUTHOR("Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>");
+MODULE_AUTHOR("Sakari Ailus <sakari.ailus@iki.fi>");
 MODULE_DESCRIPTION("Generic SMIA/SMIA++ PLL calculator");
 MODULE_LICENSE("GPL");
index cb2d2db5d02def416e10e3d638df33079655500f..a4a649834a18a685ff0902c54cfb224870dc4bee 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
 
 #include <linux/device.h>
 
+/* CSI-2 or CCP-2 */
+#define SMIAPP_PLL_BUS_TYPE_CSI2                               0x00
+#define SMIAPP_PLL_BUS_TYPE_PARALLEL                           0x01
+
+/* op pix clock is for all lanes in total normally */
+#define SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE                  (1 << 0)
+#define SMIAPP_PLL_FLAG_NO_OP_CLOCKS                           (1 << 1)
+
 struct smiapp_pll {
-       uint8_t lanes;
+       /* input values */
+       uint8_t bus_type;
+       union {
+               struct {
+                       uint8_t lanes;
+               } csi2;
+               struct {
+                       uint8_t bus_width;
+               } parallel;
+       };
+       uint8_t flags;
        uint8_t binning_horizontal;
        uint8_t binning_vertical;
        uint8_t scale_m;
        uint8_t scale_n;
        uint8_t bits_per_pixel;
-       uint16_t flags;
        uint32_t link_freq;
 
+       /* output values */
        uint16_t pre_pll_clk_div;
        uint16_t pll_multiplier;
        uint16_t op_sys_clk_div;
@@ -55,6 +73,17 @@ struct smiapp_pll {
        uint32_t pixel_rate_csi;
 };
 
+struct smiapp_pll_branch_limits {
+       uint16_t min_sys_clk_div;
+       uint16_t max_sys_clk_div;
+       uint32_t min_sys_clk_freq_hz;
+       uint32_t max_sys_clk_freq_hz;
+       uint16_t min_pix_clk_div;
+       uint16_t max_pix_clk_div;
+       uint32_t min_pix_clk_freq_hz;
+       uint32_t max_pix_clk_freq_hz;
+};
+
 struct smiapp_pll_limits {
        /* Strict PLL limits */
        uint32_t min_ext_clk_freq_hz;
@@ -68,36 +97,18 @@ struct smiapp_pll_limits {
        uint32_t min_pll_op_freq_hz;
        uint32_t max_pll_op_freq_hz;
 
-       uint16_t min_vt_sys_clk_div;
-       uint16_t max_vt_sys_clk_div;
-       uint32_t min_vt_sys_clk_freq_hz;
-       uint32_t max_vt_sys_clk_freq_hz;
-       uint16_t min_vt_pix_clk_div;
-       uint16_t max_vt_pix_clk_div;
-       uint32_t min_vt_pix_clk_freq_hz;
-       uint32_t max_vt_pix_clk_freq_hz;
-
-       uint16_t min_op_sys_clk_div;
-       uint16_t max_op_sys_clk_div;
-       uint32_t min_op_sys_clk_freq_hz;
-       uint32_t max_op_sys_clk_freq_hz;
-       uint16_t min_op_pix_clk_div;
-       uint16_t max_op_pix_clk_div;
-       uint32_t min_op_pix_clk_freq_hz;
-       uint32_t max_op_pix_clk_freq_hz;
+       struct smiapp_pll_branch_limits vt;
+       struct smiapp_pll_branch_limits op;
 
        /* Other relevant limits */
        uint32_t min_line_length_pck_bin;
        uint32_t min_line_length_pck;
 };
 
-/* op pix clock is for all lanes in total normally */
-#define SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE                  (1 << 0)
-#define SMIAPP_PLL_FLAG_NO_OP_CLOCKS                           (1 << 1)
-
 struct device;
 
-int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,
+int smiapp_pll_calculate(struct device *dev,
+                        const struct smiapp_pll_limits *limits,
                         struct smiapp_pll *pll);
 
 #endif /* SMIAPP_PLL_H */
index e08e588ad24b5f90808279629bf9c80a2c22aecc..83c7ed7ffcc2c7b7b8d94d82e42a84879410b10a 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2010--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
  *
  * Based on smiapp driver by Vimarsh Zutshi
  * Based on jt8ev1.c by Vimarsh Zutshi
@@ -252,23 +252,23 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor)
                .min_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_PLL_OP_FREQ_HZ],
                .max_pll_op_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_PLL_OP_FREQ_HZ],
 
-               .min_op_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV],
-               .max_op_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV],
-               .min_op_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV],
-               .max_op_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV],
-               .min_op_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_FREQ_HZ],
-               .max_op_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_FREQ_HZ],
-               .min_op_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_FREQ_HZ],
-               .max_op_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_FREQ_HZ],
-
-               .min_vt_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_DIV],
-               .max_vt_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_DIV],
-               .min_vt_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_DIV],
-               .max_vt_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_DIV],
-               .min_vt_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_FREQ_HZ],
-               .max_vt_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_FREQ_HZ],
-               .min_vt_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_FREQ_HZ],
-               .max_vt_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_FREQ_HZ],
+               .op.min_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV],
+               .op.max_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV],
+               .op.min_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV],
+               .op.max_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV],
+               .op.min_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_FREQ_HZ],
+               .op.max_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_FREQ_HZ],
+               .op.min_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_FREQ_HZ],
+               .op.max_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_FREQ_HZ],
+
+               .vt.min_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_DIV],
+               .vt.max_sys_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_DIV],
+               .vt.min_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_DIV],
+               .vt.max_pix_clk_div = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_DIV],
+               .vt.min_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_SYS_CLK_FREQ_HZ],
+               .vt.max_sys_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_SYS_CLK_FREQ_HZ],
+               .vt.min_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MIN_VT_PIX_CLK_FREQ_HZ],
+               .vt.max_pix_clk_freq_hz = sensor->limits[SMIAPP_LIMIT_MAX_VT_PIX_CLK_FREQ_HZ],
 
                .min_line_length_pck_bin = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN],
                .min_line_length_pck = sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK],
@@ -276,11 +276,6 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor)
        struct smiapp_pll *pll = &sensor->pll;
        int rval;
 
-       memset(&sensor->pll, 0, sizeof(sensor->pll));
-
-       pll->lanes = sensor->platform_data->lanes;
-       pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
-
        if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) {
                /*
                 * Fill in operational clock divisors limits from the
@@ -288,28 +283,14 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor)
                 * requirements regarding them are essentially the
                 * same as on VT ones.
                 */
-               lim.min_op_sys_clk_div = lim.min_vt_sys_clk_div;
-               lim.max_op_sys_clk_div = lim.max_vt_sys_clk_div;
-               lim.min_op_pix_clk_div = lim.min_vt_pix_clk_div;
-               lim.max_op_pix_clk_div = lim.max_vt_pix_clk_div;
-               lim.min_op_sys_clk_freq_hz = lim.min_vt_sys_clk_freq_hz;
-               lim.max_op_sys_clk_freq_hz = lim.max_vt_sys_clk_freq_hz;
-               lim.min_op_pix_clk_freq_hz = lim.min_vt_pix_clk_freq_hz;
-               lim.max_op_pix_clk_freq_hz = lim.max_vt_pix_clk_freq_hz;
-               /* Profile 0 sensors have no separate OP clock branch. */
-               pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
+               lim.op = lim.vt;
        }
 
-       if (smiapp_needs_quirk(sensor,
-                              SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE))
-               pll->flags |= SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE;
-
        pll->binning_horizontal = sensor->binning_horizontal;
        pll->binning_vertical = sensor->binning_vertical;
        pll->link_freq =
                sensor->link_freq->qmenu_int[sensor->link_freq->val];
        pll->scale_m = sensor->scale_m;
-       pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
        pll->bits_per_pixel = sensor->csi_format->compressed;
 
        rval = smiapp_pll_calculate(&client->dev, &lim, pll);
@@ -1010,7 +991,7 @@ static int smiapp_setup_flash_strobe(struct smiapp_sensor *sensor)
         * do not change, or if you do at least know what you're
         * doing. :-)
         *
-        * Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> 2010-10-25
+        * Sakari Ailus <sakari.ailus@iki.fi> 2010-10-25
         *
         * flash_strobe_length [us] / 10^6 = (tFlash_strobe_width_ctrl
         *      / EXTCLK freq [Hz]) * flash_strobe_adjustment
@@ -2369,6 +2350,7 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
 {
        struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
        struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       struct smiapp_pll *pll = &sensor->pll;
        struct smiapp_subdev *last = NULL;
        u32 tmp;
        unsigned int i;
@@ -2635,6 +2617,18 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
        if (rval < 0)
                goto out_nvm_release;
 
+       /* prepare PLL configuration input values */
+       pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
+       pll->csi2.lanes = sensor->platform_data->lanes;
+       pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
+       /* Profile 0 sensors have no separate OP clock branch. */
+       if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
+               pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
+       if (smiapp_needs_quirk(sensor,
+                              SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE))
+               pll->flags |= SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE;
+       pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
+
        rval = smiapp_update_mode(sensor);
        if (rval) {
                dev_err(&client->dev, "update mode failed\n");
@@ -2893,6 +2887,6 @@ static struct i2c_driver smiapp_i2c_driver = {
 
 module_i2c_driver(smiapp_i2c_driver);
 
-MODULE_AUTHOR("Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>");
+MODULE_AUTHOR("Sakari Ailus <sakari.ailus@iki.fi>");
 MODULE_DESCRIPTION("Generic SMIA/SMIA++ camera module driver");
 MODULE_LICENSE("GPL");
index fb2f81ad8c3b39f56d7507e740f5cd9dc9fd4da2..847cb235e198dae31b31f29a578534823e6f154a 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 9ae765e23ea53b20ca3176ce1070205821a4b1f0..343e9c3827fc022bcf51a341d2b38bcf1f2eb066 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 725cf62836c632f4bbf2c536b97f6d0384497cf4..bb8c506e0e3d94fc6116065c3581ed930d839774 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 86fd3e8bfb0fe0e3e78a116ad93100b6c4ff0013..504a6d80ced5da6833c66a4836751e8cfcb3a39e 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index defa7c5adebf0e07fbd51d4f5d4963baf87d52e0..3aa0ca948d87bcdf5d4ae6d4f6340aa914ad346a 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 54568ca2fe6d987c79c477c4262988ff6dcfbf4d..b0dcbb8fa5e2d62983705ad9d9be3db5b84da3dc 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 70e0d8db01301d56388ab452c318db728151e35b..4fac32cfcb3f1ef67ca893083b02babe2bb1da67 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 7f9013b47971586155ccce3fe8c26e88e7805cc7..eefc6c84d5fefca42b77dfd54f79c719e3f66f38 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 4182a695ab53913e540cf230f2a5abdb0b810a38..7cc5aae662fda5e0ef1ed6ba0b3534fafb4378c4 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2010--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 333ef178d6fbfe1d5622fd161c01856182b01871..d40a8858be01919ba5c85374a3ea6d61ffae10ae 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/log2.h>
 #include <linux/module.h>
 
+#include <media/mt9v022.h>
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
 #include <media/v4l2-subdev.h>
@@ -50,6 +51,7 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
 #define MT9V022_PIXEL_OPERATION_MODE   0x0f
 #define MT9V022_LED_OUT_CONTROL                0x1b
 #define MT9V022_ADC_MODE_CONTROL       0x1c
+#define MT9V022_REG32                  0x20
 #define MT9V022_ANALOG_GAIN            0x35
 #define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
 #define MT9V022_PIXCLK_FV_LV           0x74
@@ -71,7 +73,15 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
 #define MT9V022_COLUMN_SKIP            1
 #define MT9V022_ROW_SKIP               4
 
-#define is_mt9v024(id) (id == 0x1324)
+#define MT9V022_HORIZONTAL_BLANKING_MIN        43
+#define MT9V022_HORIZONTAL_BLANKING_MAX        1023
+#define MT9V022_HORIZONTAL_BLANKING_DEF        94
+#define MT9V022_VERTICAL_BLANKING_MIN  2
+#define MT9V022_VERTICAL_BLANKING_MAX  3000
+#define MT9V022_VERTICAL_BLANKING_DEF  45
+
+#define is_mt9v022_rev3(id)    (id == 0x1313)
+#define is_mt9v024(id)         (id == 0x1324)
 
 /* MT9V022 has only one fixed colorspace per pixelcode */
 struct mt9v022_datafmt {
@@ -136,6 +146,8 @@ struct mt9v022 {
                struct v4l2_ctrl *autogain;
                struct v4l2_ctrl *gain;
        };
+       struct v4l2_ctrl *hblank;
+       struct v4l2_ctrl *vblank;
        struct v4l2_rect rect;  /* Sensor window */
        const struct mt9v022_datafmt *fmt;
        const struct mt9v022_datafmt *fmts;
@@ -143,6 +155,7 @@ struct mt9v022 {
        int num_fmts;
        int model;      /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
        u16 chip_control;
+       u16 chip_version;
        unsigned short y_skip_top;      /* Lines to skip at the top */
 };
 
@@ -225,12 +238,32 @@ static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct mt9v022 *mt9v022 = to_mt9v022(client);
 
-       if (enable)
+       if (enable) {
                /* Switch to master "normal" mode */
                mt9v022->chip_control &= ~0x10;
-       else
+               if (is_mt9v022_rev3(mt9v022->chip_version) ||
+                   is_mt9v024(mt9v022->chip_version)) {
+                       /*
+                        * Unset snapshot mode specific settings: clear bit 9
+                        * and bit 2 in reg. 0x20 when in normal mode.
+                        */
+                       if (reg_clear(client, MT9V022_REG32, 0x204))
+                               return -EIO;
+               }
+       } else {
                /* Switch to snapshot mode */
                mt9v022->chip_control |= 0x10;
+               if (is_mt9v022_rev3(mt9v022->chip_version) ||
+                   is_mt9v024(mt9v022->chip_version)) {
+                       /*
+                        * Required settings for snapshot mode: set bit 9
+                        * (RST enable) and bit 2 (CR enable) in reg. 0x20
+                        * See TechNote TN0960 or TN-09-225.
+                        */
+                       if (reg_set(client, MT9V022_REG32, 0x204))
+                               return -EIO;
+               }
+       }
 
        if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
                return -EIO;
@@ -282,11 +315,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
                 * Default 94, Phytec driver says:
                 * "width + horizontal blank >= 660"
                 */
-               ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
-                               rect.width > 660 - 43 ? 43 :
-                               660 - rect.width);
+               ret = v4l2_ctrl_s_ctrl(mt9v022->hblank,
+                               rect.width > 660 - 43 ? 43 : 660 - rect.width);
        if (!ret)
-               ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
+               ret = v4l2_ctrl_s_ctrl(mt9v022->vblank, 45);
        if (!ret)
                ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
        if (!ret)
@@ -509,6 +541,18 @@ static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
                range = exp->maximum - exp->minimum;
                exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
                return 0;
+       case V4L2_CID_HBLANK:
+               data = reg_read(client, MT9V022_HORIZONTAL_BLANKING);
+               if (data < 0)
+                       return -EIO;
+               ctrl->val = data;
+               return 0;
+       case V4L2_CID_VBLANK:
+               data = reg_read(client, MT9V022_VERTICAL_BLANKING);
+               if (data < 0)
+                       return -EIO;
+               ctrl->val = data;
+               return 0;
        }
        return -EINVAL;
 }
@@ -590,6 +634,16 @@ static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
                                return -EIO;
                }
                return 0;
+       case V4L2_CID_HBLANK:
+               if (reg_write(client, MT9V022_HORIZONTAL_BLANKING,
+                               ctrl->val) < 0)
+                       return -EIO;
+               return 0;
+       case V4L2_CID_VBLANK:
+               if (reg_write(client, MT9V022_VERTICAL_BLANKING,
+                               ctrl->val) < 0)
+                       return -EIO;
+               return 0;
        }
        return -EINVAL;
 }
@@ -621,6 +675,8 @@ static int mt9v022_video_probe(struct i2c_client *client)
                goto ei2c;
        }
 
+       mt9v022->chip_version = data;
+
        mt9v022->reg = is_mt9v024(data) ? &mt9v024_register :
                        &mt9v022_register;
 
@@ -819,6 +875,7 @@ static int mt9v022_probe(struct i2c_client *client,
        struct mt9v022 *mt9v022;
        struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+       struct mt9v022_platform_data *pdata = icl->priv;
        int ret;
 
        if (!icl) {
@@ -857,10 +914,21 @@ static int mt9v022_probe(struct i2c_client *client,
        mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
                        V4L2_CID_EXPOSURE, 1, 255, 1, 255);
 
+       mt9v022->hblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_HBLANK, MT9V022_HORIZONTAL_BLANKING_MIN,
+                       MT9V022_HORIZONTAL_BLANKING_MAX, 1,
+                       MT9V022_HORIZONTAL_BLANKING_DEF);
+
+       mt9v022->vblank = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_VBLANK, MT9V022_VERTICAL_BLANKING_MIN,
+                       MT9V022_VERTICAL_BLANKING_MAX, 1,
+                       MT9V022_VERTICAL_BLANKING_DEF);
+
        mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
        if (mt9v022->hdl.error) {
                int err = mt9v022->hdl.error;
 
+               dev_err(&client->dev, "control initialisation err %d\n", err);
                kfree(mt9v022);
                return err;
        }
@@ -871,10 +939,10 @@ static int mt9v022_probe(struct i2c_client *client,
        mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
 
        /*
-        * MT9V022 _really_ corrupts the first read out line.
-        * TODO: verify on i.MX31
+        * On some platforms the first read out line is corrupted.
+        * Workaround it by skipping if indicated by platform data.
         */
-       mt9v022->y_skip_top     = 1;
+       mt9v022->y_skip_top     = pdata ? pdata->y_skip_top : 0;
        mt9v022->rect.left      = MT9V022_COLUMN_SKIP;
        mt9v022->rect.top       = MT9V022_ROW_SKIP;
        mt9v022->rect.width     = MT9V022_MAX_WIDTH;
index d2d298b6354e8038d95076fdc6a9bd8a68f256d4..66698a83bda2453cdd8c5de7480b94f5ca540a1c 100644 (file)
@@ -586,9 +586,20 @@ static const struct regval_list ov2640_format_change_preamble_regs[] = {
        ENDMARKER,
 };
 
-static const struct regval_list ov2640_yuv422_regs[] = {
+static const struct regval_list ov2640_yuyv_regs[] = {
+       { IMAGE_MODE, IMAGE_MODE_YUV422 },
+       { 0xd7, 0x03 },
+       { 0x33, 0xa0 },
+       { 0xe5, 0x1f },
+       { 0xe1, 0x67 },
+       { RESET,  0x00 },
+       { R_BYPASS, R_BYPASS_USE_DSP },
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_uyvy_regs[] = {
        { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_YUV422 },
-       { 0xD7, 0x01 },
+       { 0xd7, 0x01 },
        { 0x33, 0xa0 },
        { 0xe1, 0x67 },
        { RESET,  0x00 },
@@ -596,7 +607,15 @@ static const struct regval_list ov2640_yuv422_regs[] = {
        ENDMARKER,
 };
 
-static const struct regval_list ov2640_rgb565_regs[] = {
+static const struct regval_list ov2640_rgb565_be_regs[] = {
+       { IMAGE_MODE, IMAGE_MODE_RGB565 },
+       { 0xd7, 0x03 },
+       { RESET,  0x00 },
+       { R_BYPASS, R_BYPASS_USE_DSP },
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_rgb565_le_regs[] = {
        { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_RGB565 },
        { 0xd7, 0x03 },
        { RESET,  0x00 },
@@ -605,7 +624,9 @@ static const struct regval_list ov2640_rgb565_regs[] = {
 };
 
 static enum v4l2_mbus_pixelcode ov2640_codes[] = {
+       V4L2_MBUS_FMT_YUYV8_2X8,
        V4L2_MBUS_FMT_UYVY8_2X8,
+       V4L2_MBUS_FMT_RGB565_2X8_BE,
        V4L2_MBUS_FMT_RGB565_2X8_LE,
 };
 
@@ -787,14 +808,22 @@ static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
        /* select format */
        priv->cfmt_code = 0;
        switch (code) {
+       case V4L2_MBUS_FMT_RGB565_2X8_BE:
+               dev_dbg(&client->dev, "%s: Selected cfmt RGB565 BE", __func__);
+               selected_cfmt_regs = ov2640_rgb565_be_regs;
+               break;
        case V4L2_MBUS_FMT_RGB565_2X8_LE:
-               dev_dbg(&client->dev, "%s: Selected cfmt RGB565", __func__);
-               selected_cfmt_regs = ov2640_rgb565_regs;
+               dev_dbg(&client->dev, "%s: Selected cfmt RGB565 LE", __func__);
+               selected_cfmt_regs = ov2640_rgb565_le_regs;
+               break;
+       case V4L2_MBUS_FMT_YUYV8_2X8:
+               dev_dbg(&client->dev, "%s: Selected cfmt YUYV (YUV422)", __func__);
+               selected_cfmt_regs = ov2640_yuyv_regs;
                break;
        default:
        case V4L2_MBUS_FMT_UYVY8_2X8:
-               dev_dbg(&client->dev, "%s: Selected cfmt YUV422", __func__);
-               selected_cfmt_regs = ov2640_yuv422_regs;
+               dev_dbg(&client->dev, "%s: Selected cfmt UYVY", __func__);
+               selected_cfmt_regs = ov2640_uyvy_regs;
        }
 
        /* reset hardware */
@@ -859,10 +888,12 @@ static int ov2640_g_fmt(struct v4l2_subdev *sd,
        mf->code        = priv->cfmt_code;
 
        switch (mf->code) {
+       case V4L2_MBUS_FMT_RGB565_2X8_BE:
        case V4L2_MBUS_FMT_RGB565_2X8_LE:
                mf->colorspace = V4L2_COLORSPACE_SRGB;
                break;
        default:
+       case V4L2_MBUS_FMT_YUYV8_2X8:
        case V4L2_MBUS_FMT_UYVY8_2X8:
                mf->colorspace = V4L2_COLORSPACE_JPEG;
        }
@@ -879,11 +910,13 @@ static int ov2640_s_fmt(struct v4l2_subdev *sd,
 
 
        switch (mf->code) {
+       case V4L2_MBUS_FMT_RGB565_2X8_BE:
        case V4L2_MBUS_FMT_RGB565_2X8_LE:
                mf->colorspace = V4L2_COLORSPACE_SRGB;
                break;
        default:
                mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
+       case V4L2_MBUS_FMT_YUYV8_2X8:
        case V4L2_MBUS_FMT_UYVY8_2X8:
                mf->colorspace = V4L2_COLORSPACE_JPEG;
        }
@@ -896,21 +929,21 @@ static int ov2640_s_fmt(struct v4l2_subdev *sd,
 static int ov2640_try_fmt(struct v4l2_subdev *sd,
                          struct v4l2_mbus_framefmt *mf)
 {
-       const struct ov2640_win_size *win;
-
        /*
-        * select suitable win
+        * select suitable win, but don't store it
         */
-       win = ov2640_select_win(&mf->width, &mf->height);
+       ov2640_select_win(&mf->width, &mf->height);
 
        mf->field       = V4L2_FIELD_NONE;
 
        switch (mf->code) {
+       case V4L2_MBUS_FMT_RGB565_2X8_BE:
        case V4L2_MBUS_FMT_RGB565_2X8_LE:
                mf->colorspace = V4L2_COLORSPACE_SRGB;
                break;
        default:
                mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
+       case V4L2_MBUS_FMT_YUYV8_2X8:
        case V4L2_MBUS_FMT_UYVY8_2X8:
                mf->colorspace = V4L2_COLORSPACE_JPEG;
        }
index 42ae9dc9c574e3c11a97d137a2ce779d25899a7d..f434a19b9bcbb43fcbdb4d9e48f240fe9d2ae372 100644 (file)
@@ -910,18 +910,7 @@ static struct i2c_driver vs6624_driver = {
        .id_table       = vs6624_id,
 };
 
-static __init int vs6624_init(void)
-{
-       return i2c_add_driver(&vs6624_driver);
-}
-
-static __exit void vs6624_exit(void)
-{
-       i2c_del_driver(&vs6624_driver);
-}
-
-module_init(vs6624_init);
-module_exit(vs6624_exit);
+module_i2c_driver(vs6624_driver);
 
 MODULE_DESCRIPTION("VS6624 sensor driver");
 MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
index fa62475be3bf865f730f47e7eef5761ffe6e9522..aa05ad3c1ccbedee60bcbece92e4acda8322ee17 100644 (file)
@@ -4,7 +4,8 @@
 
 config SMS_SDIO_DRV
        tristate "Siano SMS1xxx based MDTV via SDIO interface"
-       depends on DVB_CORE && RC_CORE && HAS_DMA
+       depends on DVB_CORE && HAS_DMA
        depends on MMC
+       select MEDIA_COMMON_OPTIONS
        ---help---
          Choose if you would like to have Siano's support for SDIO interface
index 56c6c77793d726f48c50eefbe6cb399a46b19ffe..de6f41f19187dd584be669baadc0398910e71b2b 100644 (file)
@@ -200,7 +200,7 @@ static void flush_request_modules(struct bttv *dev)
 }
 #else
 #define request_modules(dev)
-#define flush_request_modules(dev)
+#define flush_request_modules(dev) do {} while(0)
 #endif /* CONFIG_MODULES */
 
 
@@ -301,11 +301,10 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* totalwidth */ 1135,
                        /* sqwidth */ 944,
                        /* vdelay */ 0x20,
-                       /* sheight */ 576,
-                       /* videostart0 */ 23)
                /* bt878 (and bt848?) can capture another
                   line below active video. */
-               .cropcap.bounds.height = (576 + 2) + 0x20 - 2,
+                       /* sheight */ (576 + 2) + 0x20 - 2,
+                       /* videostart0 */ 23)
        },{
                .v4l2_id        = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
                .name           = "NTSC",
index 6d2a98246b6d3b30c0896c533f9e332d40c708db..8e971ff605884b45184aae191c90bbeb40027021 100644 (file)
@@ -197,7 +197,7 @@ err_exit:
        return ret;
 }
 
-int cx18_alsa_load(struct cx18 *cx)
+static int __init cx18_alsa_load(struct cx18 *cx)
 {
        struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
        struct cx18_stream *s;
index 7a5b84a86bb39e931d2400d81dfdecaee3e4a5ee..180077c49123fe11159ec3cd8480995586cf7fbf 100644 (file)
@@ -37,6 +37,7 @@
 #include "cx18-streams.h"
 #include "cx18-fileops.h"
 #include "cx18-alsa.h"
+#include "cx18-alsa-pcm.h"
 
 static unsigned int pcm_debug;
 module_param(pcm_debug, int, 0644);
index 51609d5c88ce7962d765f0e5a3ea66e74bd69946..4908eb7bcf6c2396df57838c7351822afae14a34 100644 (file)
@@ -98,7 +98,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
        case CX18_HW_Z8F0811_IR_RX_HAUP:
                init_data->ir_codes = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-               init_data->type = RC_TYPE_RC5;
+               init_data->type = RC_BIT_RC5;
                init_data->name = cx->card_name;
                info.platform_data = init_data;
                break;
index 72af9b5c2d7dd2fcc2f37c27d568f4292a7b30ec..843c62b2f482fdd905909dfb6cf4e382433bcbc9 100644 (file)
@@ -97,7 +97,7 @@ static struct {
 };
 
 
-void cx18_dma_free(struct videobuf_queue *q,
+static void cx18_dma_free(struct videobuf_queue *q,
        struct cx18_stream *s, struct cx18_videobuf_buffer *buf)
 {
        videobuf_waiton(q, &buf->vb, 0, 0);
index 495781ee47113e88e792199d2ce4181e8bf1b953..2926f7fadccdcdeba7ca6b3a5cd5e99ba84e4bb7 100644 (file)
@@ -263,7 +263,7 @@ static int netup_fpga_op_rw(struct fpga_internal *inter, int addr,
 }
 
 /* flag - mem/io, read - read/write */
-int altera_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
+static int altera_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
                                u8 flag, u8 read, int addr, u8 val)
 {
 
@@ -298,31 +298,32 @@ int altera_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
        return mem;
 }
 
-int altera_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
-                                               int slot, int addr)
+static int altera_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+                                       int slot, int addr)
 {
        return altera_ci_op_cam(en50221, slot, 0, NETUP_CI_FLG_RD, addr, 0);
 }
 
-int altera_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
-                                               int slot, int addr, u8 data)
+static int altera_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+                                        int slot, int addr, u8 data)
 {
        return altera_ci_op_cam(en50221, slot, 0, 0, addr, data);
 }
 
-int altera_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
+static int altera_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221,
+                                 int slot, u8 addr)
 {
        return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL,
                                                NETUP_CI_FLG_RD, addr, 0);
 }
 
-int altera_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
-                                               u8 addr, u8 data)
+static int altera_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
+                                  u8 addr, u8 data)
 {
        return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL, 0, addr, data);
 }
 
-int altera_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
+static int altera_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
 {
        struct altera_ci_state *state = en50221->data;
        struct fpga_internal *inter = state->internal;
@@ -365,13 +366,13 @@ int altera_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
        return 0;
 }
 
-int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
+static int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
 {
        /* not implemented */
        return 0;
 }
 
-int altera_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
+static int altera_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
 {
        struct altera_ci_state *state = en50221->data;
        struct fpga_internal *inter = state->internal;
@@ -448,8 +449,8 @@ int altera_ci_irq(void *dev)
 }
 EXPORT_SYMBOL(altera_ci_irq);
 
-int altera_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot,
-                                                               int open)
+static int altera_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
+                                     int slot, int open)
 {
        struct altera_ci_state *state = en50221->data;
 
@@ -459,7 +460,7 @@ int altera_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot,
        return state->status;
 }
 
-void altera_hw_filt_release(void *main_dev, int filt_nr)
+static void altera_hw_filt_release(void *main_dev, int filt_nr)
 {
        struct fpga_inode *temp_int = find_inode(main_dev);
        struct netup_hw_pid_filter *pid_filt = NULL;
@@ -581,7 +582,7 @@ static void altera_toggle_fullts_streaming(struct netup_hw_pid_filter *pid_filt,
        mutex_unlock(&inter->fpga_mutex);
 }
 
-int altera_pid_feed_control(void *demux_dev, int filt_nr,
+static int altera_pid_feed_control(void *demux_dev, int filt_nr,
                struct dvb_demux_feed *feed, int onoff)
 {
        struct fpga_inode *temp_int = find_dinode(demux_dev);
@@ -603,41 +604,41 @@ int altera_pid_feed_control(void *demux_dev, int filt_nr,
 }
 EXPORT_SYMBOL(altera_pid_feed_control);
 
-int altera_ci_start_feed(struct dvb_demux_feed *feed, int num)
+static int altera_ci_start_feed(struct dvb_demux_feed *feed, int num)
 {
        altera_pid_feed_control(feed->demux, num, feed, 1);
 
        return 0;
 }
 
-int altera_ci_stop_feed(struct dvb_demux_feed *feed, int num)
+static int altera_ci_stop_feed(struct dvb_demux_feed *feed, int num)
 {
        altera_pid_feed_control(feed->demux, num, feed, 0);
 
        return 0;
 }
 
-int altera_ci_start_feed_1(struct dvb_demux_feed *feed)
+static int altera_ci_start_feed_1(struct dvb_demux_feed *feed)
 {
        return altera_ci_start_feed(feed, 1);
 }
 
-int altera_ci_stop_feed_1(struct dvb_demux_feed *feed)
+static int altera_ci_stop_feed_1(struct dvb_demux_feed *feed)
 {
        return altera_ci_stop_feed(feed, 1);
 }
 
-int altera_ci_start_feed_2(struct dvb_demux_feed *feed)
+static int altera_ci_start_feed_2(struct dvb_demux_feed *feed)
 {
        return altera_ci_start_feed(feed, 2);
 }
 
-int altera_ci_stop_feed_2(struct dvb_demux_feed *feed)
+static int altera_ci_stop_feed_2(struct dvb_demux_feed *feed)
 {
        return altera_ci_stop_feed(feed, 2);
 }
 
-int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr)
+static int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr)
 {
        struct netup_hw_pid_filter *pid_filt = NULL;
        struct fpga_inode *temp_int = find_inode(config->dev);
index 6617774a326a38f98bd611816003a4907e596aff..7344849183a77bc51e3a072dc31875dcba8fee90 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include "cx23885.h"
+#include "cimax2.h"
 #include "dvb_ca_en50221.h"
 /**** Bit definitions for MC417_RWD and MC417_OEN registers  ***
   bits 31-16
@@ -87,7 +88,7 @@ struct netup_ci_state {
 };
 
 
-int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
+static int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
                                                u8 *buf, int len)
 {
        int ret;
@@ -120,7 +121,7 @@ int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
        return 0;
 }
 
-int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
+static int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
                                                u8 *buf, int len)
 {
        int ret;
@@ -147,7 +148,7 @@ int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
        return 0;
 }
 
-int netup_ci_get_mem(struct cx23885_dev *dev)
+static int netup_ci_get_mem(struct cx23885_dev *dev)
 {
        int mem;
        unsigned long timeout = jiffies + msecs_to_jiffies(1);
@@ -166,7 +167,7 @@ int netup_ci_get_mem(struct cx23885_dev *dev)
        return mem & 0xff;
 }
 
-int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
+static int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
                                u8 flag, u8 read, int addr, u8 data)
 {
        struct netup_ci_state *state = en50221->data;
@@ -248,7 +249,8 @@ int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
        return netup_ci_op_cam(en50221, slot, 0, 0, addr, data);
 }
 
-int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
+int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
+                                u8 addr)
 {
        return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL,
                                                        NETUP_CI_RD, addr, 0);
@@ -295,7 +297,7 @@ int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
        return 0;
 }
 
-int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode)
+static int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode)
 {
        struct netup_ci_state *state = en50221->data;
        int ret;
@@ -399,7 +401,8 @@ int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status)
        return 1;
 }
 
-int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
+int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
+                                    int slot, int open)
 {
        struct netup_ci_state *state = en50221->data;
 
index 795169237e70aa3298763c34d393ae7c75b463d1..c6c9bd58f8be87426ed63200cfc729428e7b417b 100644 (file)
 
 #define AUDIO_SRAM_CHANNEL     SRAM_CH07
 
-#define dprintk(level, fmt, arg...)    if (audio_debug >= level) \
-       printk(KERN_INFO "%s: " fmt, chip->dev->name , ## arg)
+#define dprintk(level, fmt, arg...) do {                               \
+       if (audio_debug + 1 > level)                                    \
+               printk(KERN_INFO "%s: " fmt, chip->dev->name , ## arg); \
+} while(0)
 
 #define dprintk_core(level, fmt, arg...)       if (audio_debug >= level) \
        printk(KERN_DEBUG "%s: " fmt, chip->dev->name , ## arg)
index 134ebddd860fef8e6fae5196b8f79a464680518e..e958a01fd554c27ec8b8be330bffbc0749ebb044 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "cx23885.h"
+#include "cx23885-av.h"
 
 void cx23885_av_work_handler(struct work_struct *work)
 {
index 5acdf954ff6bcdadec1c1dfe248012f5a3bf7f84..6277e145f0b831809367019d3ae2886d6440dcc1 100644 (file)
@@ -1427,7 +1427,7 @@ void cx23885_ir_fini(struct cx23885_dev *dev)
        }
 }
 
-int netup_jtag_io(void *device, int tms, int tdi, int read_tdo)
+static int netup_jtag_io(void *device, int tms, int tdi, int read_tdo)
 {
        int data;
        int tdo = 0;
index 697728f0943037d2aed76a6a0eba841083b63c17..065ecd54bda3d6127b4ff0ab8e846c41924b3d96 100644 (file)
@@ -303,7 +303,7 @@ static struct sram_channel cx23887_sram_channels[] = {
        },
 };
 
-void cx23885_irq_add(struct cx23885_dev *dev, u32 mask)
+static void cx23885_irq_add(struct cx23885_dev *dev, u32 mask)
 {
        unsigned long flags;
        spin_lock_irqsave(&dev->pci_irqmask_lock, flags);
@@ -1516,8 +1516,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port,
                        buf = list_entry(q->queued.next, struct cx23885_buffer,
                                         vb.queue);
                        if (NULL == prev) {
-                               list_del(&buf->vb.queue);
-                               list_add_tail(&buf->vb.queue, &q->active);
+                               list_move_tail(&buf->vb.queue, &q->active);
                                cx23885_start_dma(port, q, buf);
                                buf->vb.state = VIDEOBUF_ACTIVE;
                                buf->count    = q->count++;
@@ -1528,8 +1527,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port,
                        } else if (prev->vb.width  == buf->vb.width  &&
                                   prev->vb.height == buf->vb.height &&
                                   prev->fmt       == buf->fmt) {
-                               list_del(&buf->vb.queue);
-                               list_add_tail(&buf->vb.queue, &q->active);
+                               list_move_tail(&buf->vb.queue, &q->active);
                                buf->vb.state = VIDEOBUF_ACTIVE;
                                buf->count    = q->count++;
                                prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
index 4379d8a6dad5f6d4f8376f7d3d1f4dc68bc97b59..2f5b902e63ae07f71847e89bbbc70a2907ed24fa 100644 (file)
@@ -659,7 +659,7 @@ static struct mt2063_config terratec_mt2063_config[] = {
        },
 };
 
-int netup_altera_fpga_rw(void *device, int flag, int data, int read)
+static int netup_altera_fpga_rw(void *device, int flag, int data, int read)
 {
        struct cx23885_dev *dev = (struct cx23885_dev *)device;
        unsigned long timeout = jiffies + msecs_to_jiffies(1);
index 93998f2209865e8dc5affaaef86758606e3df91c..5444cc526008706d1a6b7a4c87e4aa0da923a22f 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include "cx23885.h"
+#include "cx23885-f300.h"
 
 #define F300_DATA      GPIO_0
 #define F300_RESET     GPIO_1
index 2c925f77cf2aa4baeb8288efba0b660448747cb8..4f1055a194b51d9446747d52361f7334eef8a51c 100644 (file)
@@ -40,6 +40,7 @@
 #include <media/v4l2-subdev.h>
 
 #include "cx23885.h"
+#include "cx23885-input.h"
 
 #define MODULE_NAME "cx23885"
 
@@ -270,21 +271,21 @@ int cx23885_input_init(struct cx23885_dev *dev)
        case CX23885_BOARD_HAUPPAUGE_HVR1250:
                /* Integrated CX2388[58] IR controller */
                driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_TYPE_ALL;
+               allowed_protos = RC_BIT_ALL;
                /* The grey Hauppauge RC-5 remote */
                rc_map = RC_MAP_HAUPPAUGE;
                break;
        case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
                /* Integrated CX23885 IR controller */
                driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_TYPE_NEC;
+               allowed_protos = RC_BIT_NEC;
                /* The grey Terratec remote with orange buttons */
                rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS;
                break;
        case CX23885_BOARD_TEVII_S470:
                /* Integrated CX23885 IR controller */
                driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_TYPE_ALL;
+               allowed_protos = RC_BIT_ALL;
                /* A guess at the remote */
                rc_map = RC_MAP_TEVII_NEC;
                break;
index 75ef15d3f5235209365ae49d02fc68b2c24323e1..87dc44e69977e2d38fb9c168711a0bf04c54f671 100644 (file)
@@ -23,7 +23,7 @@
 
 #ifndef _CX23885_INPUT_H_
 #define _CX23885_INPUT_H_
-int cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events);
+void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events);
 
 int cx23885_input_init(struct cx23885_dev *dev);
 void cx23885_input_fini(struct cx23885_dev *dev);
index 44812ca788992d6a511e12354464df0d85eb64e1..ea9a614f3bbf713c9b485043991e75656e2b9fdb 100644 (file)
@@ -22,6 +22,8 @@
  */
 
 #include "cx23885.h"
+#include "cx23885-ioctl.h"
+
 #include <media/v4l2-chip-ident.h>
 
 int cx23885_g_chip_ident(struct file *file, void *fh,
index 7125247dd25558678c823ee3262675570c9aa630..bfef193592916dd46ed734dac478ac03e1eab653 100644 (file)
@@ -24,6 +24,7 @@
 #include <media/v4l2-device.h>
 
 #include "cx23885.h"
+#include "cx23885-ir.h"
 #include "cx23885-input.h"
 
 #define CX23885_IR_RX_FIFO_SERVICE_REQ         0
index c2bc39c58f82e8fef59a500d1ce9c8746bcf8ad9..c4bd1e95d33fb950da950821a5e5c5f06ba0efee 100644 (file)
@@ -29,6 +29,7 @@
 #include <media/rc-core.h>
 
 #include "cx23885.h"
+#include "cx23888-ir.h"
 
 static unsigned int ir_888_debug;
 module_param(ir_888_debug, int, 0644);
index f4893e69cd895aa3fb6b6e59d860f5ab3cb0208b..0044fef7ca24e2adac4d08f55f6d32bc9b08ed5d 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include "cx23885.h"
+#include "netup-init.h"
 
 static void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val)
 {
index 8b2a99975c23f0a4deabdc6e69f46b402c95776e..87491ca05ee556fc9b7b4fc4c2112684fc997604 100644 (file)
@@ -44,7 +44,7 @@ MODULE_LICENSE("GPL");
 static int _intr_msk = FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF |
                        FLD_AUD_SRC_SYNC | FLD_AUD_SRC_OPC_ERR;
 
-int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
+static int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
                                              struct sram_channel *ch,
                                              unsigned int bpl, u32 risc)
 {
@@ -133,7 +133,7 @@ static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
        return rp;
 }
 
-int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
+static int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
                                       struct pci_dev *pci,
                                       unsigned int bpl, unsigned int lines)
 {
@@ -197,7 +197,7 @@ int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
        return 0;
 }
 
-void cx25821_free_memory_audio(struct cx25821_dev *dev)
+static void cx25821_free_memory_audio(struct cx25821_dev *dev)
 {
        if (dev->_risc_virt_addr) {
                pci_free_consistent(dev->pci, dev->_audiorisc_size,
@@ -256,7 +256,7 @@ void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
        cx25821_free_memory_audio(dev);
 }
 
-int cx25821_get_audio_data(struct cx25821_dev *dev,
+static int cx25821_get_audio_data(struct cx25821_dev *dev,
                           struct sram_channel *sram_ch)
 {
        struct file *myfile;
@@ -351,7 +351,7 @@ static void cx25821_audioups_handler(struct work_struct *work)
                        sram_channels);
 }
 
-int cx25821_openfile_audio(struct cx25821_dev *dev,
+static int cx25821_openfile_audio(struct cx25821_dev *dev,
                           struct sram_channel *sram_ch)
 {
        struct file *myfile;
@@ -490,7 +490,7 @@ error:
        return ret;
 }
 
-int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
+static int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
                               u32 status)
 {
        int i = 0;
@@ -634,8 +634,8 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
 
 }
 
-int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
-                                    struct sram_channel *sram_ch)
+static int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
+                                           struct sram_channel *sram_ch)
 {
        u32 tmp = 0;
        int err = 0;
@@ -700,9 +700,7 @@ fail_irq:
 int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
 {
        struct sram_channel *sram_ch;
-       int retval = 0;
        int err = 0;
-       int str_length = 0;
 
        if (dev->_audio_is_running) {
                pr_warn("Audio Channel is still running so return!\n");
@@ -731,27 +729,29 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
        _line_size = AUDIO_LINE_SIZE;
 
        if (dev->input_audiofilename) {
-               str_length = strlen(dev->input_audiofilename);
-               dev->_audiofilename = kmemdup(dev->input_audiofilename,
-                                             str_length + 1, GFP_KERNEL);
+               dev->_audiofilename = kstrdup(dev->input_audiofilename,
+                                             GFP_KERNEL);
 
-               if (!dev->_audiofilename)
+               if (!dev->_audiofilename) {
+                       err = -ENOMEM;
                        goto error;
+               }
 
                /* Default if filename is empty string */
                if (strcmp(dev->input_audiofilename, "") == 0)
                        dev->_audiofilename = "/root/audioGOOD.wav";
        } else {
-               str_length = strlen(_defaultAudioName);
-               dev->_audiofilename = kmemdup(_defaultAudioName,
-                                             str_length + 1, GFP_KERNEL);
+               dev->_audiofilename = kstrdup(_defaultAudioName,
+                                             GFP_KERNEL);
 
-               if (!dev->_audiofilename)
+               if (!dev->_audiofilename) {
+                       err = -ENOMEM;
                        goto error;
+               }
        }
 
-       retval = cx25821_sram_channel_setup_upstream_audio(dev, sram_ch,
-                                                       _line_size, 0);
+       cx25821_sram_channel_setup_upstream_audio(dev, sram_ch,
+                                                 _line_size, 0);
 
        dev->audio_upstream_riscbuf_size =
                AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
@@ -759,9 +759,9 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
        dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
 
        /* Allocating buffers and prepare RISC program */
-       retval = cx25821_audio_upstream_buffer_prepare(dev, sram_ch,
+       err = cx25821_audio_upstream_buffer_prepare(dev, sram_ch,
                                                        _line_size);
-       if (retval < 0) {
+       if (err < 0) {
                pr_err("%s: Failed to set up Audio upstream buffers!\n",
                        dev->name);
                goto error;
index 9326a7c729ec3e0713e741a577c35da2df99d1fc..937f5a70fb7a8d8d032759a937ca889a45f11f64 100644 (file)
 
 #define SetBit(Bit)  (1 << Bit)
 
-inline u8 getBit(u32 sample, u8 index)
+static inline u8 getBit(u32 sample, u8 index)
 {
        return (u8) ((sample >> index) & 1);
 }
 
-inline u32 clearBitAtPos(u32 value, u8 bit)
+static inline u32 clearBitAtPos(u32 value, u8 bit)
 {
        return value & ~(1 << bit);
 }
 
-inline u32 setBitAtPos(u32 sample, u8 bit)
+static inline u32 setBitAtPos(u32 sample, u8 bit)
 {
        sample |= (1 << bit);
        return sample;
index 9844549764c96a8c10e288513149baf60908c2c7..a8dc945bbe1797f015a25e505719a5c34b8fba5b 100644 (file)
@@ -329,7 +329,8 @@ int cx25821_i2c_unregister(struct cx25821_i2c *bus)
        return 0;
 }
 
-void cx25821_av_clk(struct cx25821_dev *dev, int enable)
+#if 0 /* Currently unused */
+static void cx25821_av_clk(struct cx25821_dev *dev, int enable)
 {
        /* write 0 to bus 2 addr 0x144 via i2x_xfer() */
        char buffer[3];
@@ -351,6 +352,7 @@ void cx25821_av_clk(struct cx25821_dev *dev, int enable)
 
        i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1);
 }
+#endif
 
 int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
 {
index d33fc1a2303087ccb416ed158708c31c9ddec4d3..cf2723c7197f1071b49ad9a9b148216e022f4b02 100644 (file)
@@ -123,10 +123,11 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev,
        return rp;
 }
 
-int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
-                                    struct pci_dev *pci,
-                                    unsigned int top_offset, unsigned int bpl,
-                                    unsigned int lines)
+static int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
+                                           struct pci_dev *pci,
+                                           unsigned int top_offset,
+                                           unsigned int bpl,
+                                           unsigned int lines)
 {
        __le32 *rp;
        int fifo_enable = 0;
@@ -255,7 +256,8 @@ void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev)
        }
 }
 
-int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
+static int cx25821_get_frame_ch2(struct cx25821_dev *dev,
+                                struct sram_channel *sram_ch)
 {
        struct file *myfile;
        int frame_index_temp = dev->_frame_index_ch2;
@@ -360,7 +362,8 @@ static void cx25821_vidups_handler_ch2(struct work_struct *work)
                        _channel2_upstream_select].sram_channels);
 }
 
-int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
+static int cx25821_openfile_ch2(struct cx25821_dev *dev,
+                               struct sram_channel *sram_ch)
 {
        struct file *myfile;
        int i = 0, j = 0;
@@ -507,8 +510,9 @@ error:
        return ret;
 }
 
-int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
-                                  u32 status)
+static int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev,
+                                         int chan_num,
+                                         u32 status)
 {
        u32 int_msk_tmp;
        struct sram_channel *channel = dev->channels[chan_num].sram_channels;
@@ -647,8 +651,8 @@ static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
        cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
 }
 
-int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
-                                        struct sram_channel *sram_ch)
+static int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
+                                               struct sram_channel *sram_ch)
 {
        u32 tmp = 0;
        int err = 0;
@@ -704,11 +708,9 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
 {
        struct sram_channel *sram_ch;
        u32 tmp;
-       int retval = 0;
        int err = 0;
        int data_frame_size = 0;
        int risc_buffer_size = 0;
-       int str_length = 0;
 
        if (dev->_is_running_ch2) {
                pr_info("Video Channel is still running so return!\n");
@@ -744,20 +746,16 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
        risc_buffer_size = dev->_isNTSC_ch2 ?
                NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
 
-       if (dev->input_filename_ch2) {
-               str_length = strlen(dev->input_filename_ch2);
-               dev->_filename_ch2 = kmemdup(dev->input_filename_ch2,
-                                            str_length + 1, GFP_KERNEL);
-
-               if (!dev->_filename_ch2)
-                       goto error;
-       } else {
-               str_length = strlen(dev->_defaultname_ch2);
-               dev->_filename_ch2 = kmemdup(dev->_defaultname_ch2,
-                                            str_length + 1, GFP_KERNEL);
+       if (dev->input_filename_ch2)
+               dev->_filename_ch2 = kstrdup(dev->input_filename_ch2,
+                                                               GFP_KERNEL);
+       else
+               dev->_filename_ch2 = kstrdup(dev->_defaultname_ch2,
+                                                               GFP_KERNEL);
 
-               if (!dev->_filename_ch2)
-                       goto error;
+       if (!dev->_filename_ch2) {
+               err = -ENOENT;
+               goto error;
        }
 
        /* Default if filename is empty string */
@@ -773,7 +771,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
                }
        }
 
-       retval = cx25821_sram_channel_setup_upstream(dev, sram_ch,
+       err = cx25821_sram_channel_setup_upstream(dev, sram_ch,
                                                dev->_line_size_ch2, 0);
 
        /* setup fifo + format */
@@ -783,9 +781,9 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
        dev->upstream_databuf_size_ch2 = data_frame_size * 2;
 
        /* Allocating buffers and prepare RISC program */
-       retval = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
+       err = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
                                                dev->_line_size_ch2);
-       if (retval < 0) {
+       if (err < 0) {
                pr_err("%s: Failed to set up Video upstream buffers!\n",
                       dev->name);
                goto error;
index 6759fff8eb640b57b4b9048bb48f3ef0dfa777c8..7fc97110d973eabee2e70b1132810f892f799106 100644 (file)
@@ -173,10 +173,10 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
        return rp;
 }
 
-int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
-                                struct pci_dev *pci,
-                                unsigned int top_offset,
-                                unsigned int bpl, unsigned int lines)
+static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
+                                       struct pci_dev *pci,
+                                       unsigned int top_offset,
+                                       unsigned int bpl, unsigned int lines)
 {
        __le32 *rp;
        int fifo_enable = 0;
@@ -300,7 +300,8 @@ void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
        }
 }
 
-int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
+static int cx25821_get_frame(struct cx25821_dev *dev,
+                            struct sram_channel *sram_ch)
 {
        struct file *myfile;
        int frame_index_temp = dev->_frame_index;
@@ -405,7 +406,8 @@ static void cx25821_vidups_handler(struct work_struct *work)
                        sram_channels);
 }
 
-int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
+static int cx25821_openfile(struct cx25821_dev *dev,
+                           struct sram_channel *sram_ch)
 {
        struct file *myfile;
        int i = 0, j = 0;
@@ -486,8 +488,9 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
        return 0;
 }
 
-int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
-                                   struct sram_channel *sram_ch, int bpl)
+static int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
+                                          struct sram_channel *sram_ch,
+                                          int bpl)
 {
        int ret = 0;
        dma_addr_t dma_addr;
@@ -548,8 +551,8 @@ error:
        return ret;
 }
 
-int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
-                              u32 status)
+static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
+                                     u32 status)
 {
        u32 int_msk_tmp;
        struct sram_channel *channel = dev->channels[chan_num].sram_channels;
@@ -664,8 +667,9 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
        return IRQ_RETVAL(handled);
 }
 
-void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
-                            int pix_format)
+static void cx25821_set_pixelengine(struct cx25821_dev *dev,
+                                   struct sram_channel *ch,
+                                   int pix_format)
 {
        int width = WIDTH_D1;
        int height = dev->_lines_count;
@@ -696,8 +700,8 @@ void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
        cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
 }
 
-int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
-                                    struct sram_channel *sram_ch)
+static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
+                                           struct sram_channel *sram_ch)
 {
        u32 tmp = 0;
        int err = 0;
@@ -753,7 +757,6 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
 {
        struct sram_channel *sram_ch;
        u32 tmp;
-       int retval = 0;
        int err = 0;
        int data_frame_size = 0;
        int risc_buffer_size = 0;
@@ -796,15 +799,19 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
                dev->_filename = kmemdup(dev->input_filename, str_length + 1,
                                         GFP_KERNEL);
 
-               if (!dev->_filename)
+               if (!dev->_filename) {
+                       err = -ENOENT;
                        goto error;
+               }
        } else {
                str_length = strlen(dev->_defaultname);
                dev->_filename = kmemdup(dev->_defaultname, str_length + 1,
                                         GFP_KERNEL);
 
-               if (!dev->_filename)
+               if (!dev->_filename) {
+                       err = -ENOENT;
                        goto error;
+               }
        }
 
        /* Default if filename is empty string */
@@ -828,7 +835,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
        dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ?
                (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
 
-       retval = cx25821_sram_channel_setup_upstream(dev, sram_ch,
+       err = cx25821_sram_channel_setup_upstream(dev, sram_ch,
                        dev->_line_size, 0);
 
        /* setup fifo + format */
@@ -838,8 +845,8 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
        dev->upstream_databuf_size = data_frame_size * 2;
 
        /* Allocating buffers and prepare RISC program */
-       retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
-       if (retval < 0) {
+       err = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
+       if (err < 0) {
                pr_err("%s: Failed to set up Video upstream buffers!\n",
                       dev->name);
                goto error;
index 0a80245165d0d8d6e51f876494c1f886893dd43f..53b16dd7032054a0afce16de3037350e012214c6 100644 (file)
@@ -291,9 +291,9 @@ int cx25821_start_video_dma(struct cx25821_dev *dev,
        return 0;
 }
 
-int cx25821_restart_video_queue(struct cx25821_dev *dev,
-                               struct cx25821_dmaqueue *q,
-                               struct sram_channel *channel)
+static int cx25821_restart_video_queue(struct cx25821_dev *dev,
+                                      struct cx25821_dmaqueue *q,
+                                      struct sram_channel *channel)
 {
        struct cx25821_buffer *buf, *prev;
        struct list_head *item;
@@ -342,7 +342,7 @@ int cx25821_restart_video_queue(struct cx25821_dev *dev,
        }
 }
 
-void cx25821_vid_timeout(unsigned long data)
+static void cx25821_vid_timeout(unsigned long data)
 {
        struct cx25821_data *timeout_data = (struct cx25821_data *)data;
        struct cx25821_dev *dev = timeout_data->dev;
index 3aa6856ead3b2f13f71db61ee9ea329808c01be4..d2de1a913e1978343937682689f2096320169f41 100644 (file)
 #include "cx88.h"
 #include "cx88-reg.h"
 
-#define dprintk(level,fmt, arg...)     if (debug >= level) \
-       printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg)
-
-#define dprintk_core(level,fmt, arg...)        if (debug >= level) \
-       printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg)
+#define dprintk(level, fmt, arg...) do {                               \
+       if (debug + 1 > level)                                          \
+               printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg);\
+} while(0)
+
+#define dprintk_core(level, fmt, arg...) do {                          \
+       if (debug + 1 > level)                                          \
+               printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg);\
+} while(0)
 
 /****************************************************************************
        Data type declarations - Can be moded to a header file later
index 62184eb919e5d7563ab0c8d4a9c286c45131c92b..a6ff8a6f4fc09f90e1ffce5027839e575d41515a 100644 (file)
@@ -53,9 +53,10 @@ static unsigned int debug;
 module_param(debug,int,0644);
 MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");
 
-#define dprintk(level,fmt, arg...)     if (debug >= level) \
-       printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg)
-
+#define dprintk(level, fmt, arg...) do {                                     \
+       if (debug + 1 > level)                                                \
+               printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg); \
+} while(0)
 
 /* ------------------------------------------------------------------ */
 
index c97b174be3ab6313e9810c0c27b13b97ce2f3384..19a58754c6e14ee3d91152738464382edf16ab30 100644 (file)
@@ -646,22 +646,22 @@ int cx88_reset(struct cx88_core *core)
 
 /* ------------------------------------------------------------------ */
 
-static unsigned int inline norm_swidth(v4l2_std_id norm)
+static inline unsigned int norm_swidth(v4l2_std_id norm)
 {
        return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
 }
 
-static unsigned int inline norm_hdelay(v4l2_std_id norm)
+static inline unsigned int norm_hdelay(v4l2_std_id norm)
 {
        return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186;
 }
 
-static unsigned int inline norm_vdelay(v4l2_std_id norm)
+static inline unsigned int norm_vdelay(v4l2_std_id norm)
 {
        return (norm & V4L2_STD_625_50) ? 0x24 : 0x18;
 }
 
-static unsigned int inline norm_fsc8(v4l2_std_id norm)
+static inline unsigned int norm_fsc8(v4l2_std_id norm)
 {
        if (norm & V4L2_STD_PAL_M)
                return 28604892;      // 3.575611 MHz
@@ -681,7 +681,7 @@ static unsigned int inline norm_fsc8(v4l2_std_id norm)
        return 35468950;      // 4.43361875 MHz +/- 5 Hz
 }
 
-static unsigned int inline norm_htotal(v4l2_std_id norm)
+static inline unsigned int norm_htotal(v4l2_std_id norm)
 {
 
        unsigned int fsc4=norm_fsc8(norm)/2;
@@ -692,7 +692,7 @@ static unsigned int inline norm_htotal(v4l2_std_id norm)
                                ((fsc4+262)/525*1001+15000)/30000;
 }
 
-static unsigned int inline norm_vbipack(v4l2_std_id norm)
+static inline unsigned int norm_vbipack(v4l2_std_id norm)
 {
        return (norm & V4L2_STD_625_50) ? 511 : 400;
 }
index ebf448c48ca3335ce6cdb0a0091270fcdb96bd57..f29e18c72f44ffa6462c09ae870445a67326431b 100644 (file)
@@ -248,7 +248,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        struct cx88_IR *ir;
        struct rc_dev *dev;
        char *ir_codes = NULL;
-       u64 rc_type = RC_TYPE_OTHER;
+       u64 rc_type = RC_BIT_OTHER;
        int err = -ENOMEM;
        u32 hardware_mask = 0;  /* For devices with a hardware mask, when
                                 * used with a full-code IR table
@@ -416,7 +416,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
                break;
        case CX88_BOARD_TWINHAN_VP1027_DVBS:
                ir_codes         = RC_MAP_TWINHAN_VP1027_DVBS;
-               rc_type          = RC_TYPE_NEC;
+               rc_type          = RC_BIT_NEC;
                ir->sampling     = 0xff00; /* address */
                break;
        }
@@ -592,7 +592,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
        case CX88_BOARD_LEADTEK_PVR2000:
                addr_list = pvr2000_addr_list;
                core->init_data.name = "cx88 Leadtek PVR 2000 remote";
-               core->init_data.type = RC_TYPE_UNKNOWN;
+               core->init_data.type = RC_BIT_UNKNOWN;
                core->init_data.get_key = get_key_pvr2000;
                core->init_data.ir_codes = RC_MAP_EMPTY;
                break;
@@ -613,7 +613,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
                        /* Hauppauge XVR */
                        core->init_data.name = "cx88 Hauppauge XVR remote";
                        core->init_data.ir_codes = RC_MAP_HAUPPAUGE;
-                       core->init_data.type = RC_TYPE_RC5;
+                       core->init_data.type = RC_BIT_RC5;
                        core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
 
                        info.platform_data = &core->init_data;
index d154bc19735688de10c35e47e65b719d71dbfecd..d46b008a46b86f4d2e2684cba33b650d2b12ff44 100644 (file)
@@ -45,11 +45,15 @@ static unsigned int debug;
 module_param(debug,int,0644);
 MODULE_PARM_DESC(debug,"enable debug messages [mpeg]");
 
-#define dprintk(level,fmt, arg...)     if (debug >= level) \
-       printk(KERN_DEBUG "%s/2-mpeg: " fmt, dev->core->name, ## arg)
+#define dprintk(level, fmt, arg...) do {                                      \
+       if (debug + 1 > level)                                                 \
+               printk(KERN_DEBUG "%s/2-mpeg: " fmt, dev->core->name, ## arg); \
+} while(0)
 
-#define mpeg_dbg(level,fmt, arg...)    if (debug >= level) \
-       printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg)
+#define mpeg_dbg(level, fmt, arg...) do {                                \
+       if (debug + 1 > level)                                            \
+               printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg); \
+} while(0)
 
 #if defined(CONFIG_MODULES) && defined(MODULE)
 static void request_module_async(struct work_struct *work)
@@ -217,8 +221,7 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
                                return 0;
                        buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
                        if (NULL == prev) {
-                               list_del(&buf->vb.queue);
-                               list_add_tail(&buf->vb.queue,&q->active);
+                               list_move_tail(&buf->vb.queue, &q->active);
                                cx8802_start_dma(dev, q, buf);
                                buf->vb.state = VIDEOBUF_ACTIVE;
                                buf->count    = q->count++;
@@ -229,8 +232,7 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
                        } else if (prev->vb.width  == buf->vb.width  &&
                                   prev->vb.height == buf->vb.height &&
                                   prev->fmt       == buf->fmt) {
-                               list_del(&buf->vb.queue);
-                               list_add_tail(&buf->vb.queue,&q->active);
+                               list_move_tail(&buf->vb.queue, &q->active);
                                buf->vb.state = VIDEOBUF_ACTIVE;
                                buf->count    = q->count++;
                                prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
index 44ffc8b3d45f9f7a586404a0b37e8520ae804fa0..ba0dba4a4d224881fb8f953fcba75aa21e620afb 100644 (file)
@@ -94,13 +94,13 @@ enum cx8802_board_access {
 /* ----------------------------------------------------------- */
 /* tv norms                                                    */
 
-static unsigned int inline norm_maxw(v4l2_std_id norm)
+static inline unsigned int norm_maxw(v4l2_std_id norm)
 {
        return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
 }
 
 
-static unsigned int inline norm_maxh(v4l2_std_id norm)
+static inline unsigned int norm_maxh(v4l2_std_id norm)
 {
        return (norm & V4L2_STD_625_50) ? 576 : 480;
 }
index a609b3a9b14695bfff2a3e53a387c241e4b38107..f288ffcc4b6bb9004941d75830c2b90e393d2565 100644 (file)
@@ -736,7 +736,7 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
+static int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
 {
        struct rc_dev *dev;
        int err = -ENOMEM;
@@ -776,7 +776,7 @@ int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
        return 0;
 }
 
-void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
+static void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
 {
        rc_unregister_device(dm1105->ir.dev);
 }
@@ -1128,8 +1128,10 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
        INIT_WORK(&dev->work, dm1105_dmx_buffer);
        sprintf(dev->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num);
        dev->wq = create_singlethread_workqueue(dev->wqn);
-       if (!dev->wq)
+       if (!dev->wq) {
+               ret = -ENOMEM;
                goto err_dvb_net;
+       }
 
        ret = request_irq(pdev->irq, dm1105_irq, IRQF_SHARED,
                                                DRIVER_NAME, dev);
index 8deab1629b3baca0d7b5999c43ef0f6869beaca7..4a221c693995e858b1d08cdcbc47fed6b0ec7e57 100644 (file)
@@ -205,7 +205,7 @@ err_exit:
        return ret;
 }
 
-int ivtv_alsa_load(struct ivtv *itv)
+static int __init ivtv_alsa_load(struct ivtv *itv)
 {
        struct v4l2_device *v4l2_dev = &itv->v4l2_dev;
        struct ivtv_stream *s;
index f7022bd58ffddcc5ffe3c137bf834b9b0437d66a..e1863dbf4edcaca3376321b116d58b2606e2252c 100644 (file)
@@ -37,6 +37,7 @@
 #include "ivtv-streams.h"
 #include "ivtv-fileops.h"
 #include "ivtv-alsa.h"
+#include "ivtv-alsa-pcm.h"
 
 static unsigned int pcm_debug;
 module_param(pcm_debug, int, 0644);
@@ -69,8 +70,9 @@ static struct snd_pcm_hardware snd_ivtv_hw_capture = {
        .periods_max = 98,              /* 12544, */
 };
 
-void ivtv_alsa_announce_pcm_data(struct snd_ivtv_card *itvsc, u8 *pcm_data,
-                                size_t num_bytes)
+static void ivtv_alsa_announce_pcm_data(struct snd_ivtv_card *itvsc,
+                                       u8 *pcm_data,
+                                       size_t num_bytes)
 {
        struct snd_pcm_substream *substream;
        struct snd_pcm_runtime *runtime;
index 5ab18319ea4db5ab3d6df28a8e634994e0068c10..23dfe0d124004c1c6bf693caedb967b7991c5c7a 100644 (file)
@@ -21,7 +21,3 @@
  */
 
 int __init snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
-
-/* Used by ivtv driver to announce the PCM data to the module */
-void ivtv_alsa_announce_pcm_data(struct snd_ivtv_card *card, u8 *pcm_data,
-                                size_t num_bytes);
index 6ec7705af55592015ed8ca07fc8e311866077d69..68387d4369d66f5260f9582db11f0f76dc8b6ccc 100644 (file)
@@ -276,7 +276,7 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv)
 }
 
 /* Try to restart the card & restore previous settings */
-int ivtv_firmware_restart(struct ivtv *itv)
+static int ivtv_firmware_restart(struct ivtv *itv)
 {
        int rc = 0;
        v4l2_std_id std;
index d47f41a0ef66482dde6eec7437120b8ec462862e..46e262becb6728615fad39494aea4bf48b978f2c 100644 (file)
@@ -200,21 +200,21 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
                init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
                init_data->internal_get_key_func =
                                        IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
-               init_data->type = RC_TYPE_OTHER;
+               init_data->type = RC_BIT_OTHER;
                init_data->name = "AVerMedia AVerTV card";
                break;
        case IVTV_HW_I2C_IR_RX_HAUP_EXT:
        case IVTV_HW_I2C_IR_RX_HAUP_INT:
                init_data->ir_codes = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
-               init_data->type = RC_TYPE_RC5;
+               init_data->type = RC_BIT_RC5;
                init_data->name = itv->card_name;
                break;
        case IVTV_HW_Z8F0811_IR_RX_HAUP:
                /* Default to grey remote */
                init_data->ir_codes = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-               init_data->type = RC_TYPE_RC5;
+               init_data->type = RC_BIT_RC5;
                init_data->name = itv->card_name;
                break;
        case IVTV_HW_I2C_IR_RX_ADAPTEC:
@@ -222,7 +222,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
                init_data->name = itv->card_name;
                /* FIXME: The protocol and RC_MAP needs to be corrected */
                init_data->ir_codes = RC_MAP_EMPTY;
-               init_data->type = RC_TYPE_UNKNOWN;
+               init_data->type = RC_BIT_UNKNOWN;
                break;
        }
 
index 949ae230e119b80caae93490186613d51bd5e151..7a8b0d0b6127aefbc1281e30108c2ef1050e9e79 100644 (file)
@@ -993,7 +993,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
        v4l2_std_id std;
        int i;
 
-       if (inp < 0 || inp >= itv->nof_inputs)
+       if (inp >= itv->nof_inputs)
                return -EINVAL;
 
        if (inp == itv->active_input) {
@@ -1168,7 +1168,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
        }
 }
 
-int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
+static int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
 {
        struct ivtv *itv = fh2id(fh)->itv;
 
index db6d54d3fec0497ddaf61cfda0d092bf1ffc2e02..0e5252e5c0ef86e1a0ce4af1d25ee9d52dc7aa42 100644 (file)
@@ -18,6 +18,8 @@
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#if 0 /* Currently unused */
+
 #include <media/rc-core.h>
 #include <linux/pci.h>
 
@@ -150,10 +152,11 @@ out:
        return err;
 }
 
-int mantis_exit(struct mantis_pci *mantis)
+int mantis_init_exit(struct mantis_pci *mantis)
 {
        rc_unregister_device(mantis->rc);
        rc_map_unregister(&ir_mantis_map);
        return 0;
 }
 
+#endif
index 85e977861b4a68a8bbb44d76c9b6a010ec250c3f..a7071921863194d07b5542c5564c4f26c4af6cda 100644 (file)
@@ -61,7 +61,7 @@ static struct {
 
 #define UART_MAX_BUF                   16
 
-int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
+static int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
 {
        struct mantis_hwconfig *config = mantis->hwconfig;
        u32 stat = 0, i;
index ad013e93ed11d7bd05638ebf7eb5a398c4631244..115003e8d19d453f30a2db59664d3a561c614116 100644 (file)
@@ -83,7 +83,7 @@ u8 lgtdqcs001f_inittab[] = {
 #define MANTIS_MODEL_NAME      "VP-1033"
 #define MANTIS_DEV_TYPE                "DVB-S/DSS"
 
-int lgtdqcs001f_tuner_set(struct dvb_frontend *fe)
+static int lgtdqcs001f_tuner_set(struct dvb_frontend *fe)
 {
        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
        struct mantis_pci *mantis       = fe->dvb->priv;
@@ -115,8 +115,8 @@ int lgtdqcs001f_tuner_set(struct dvb_frontend *fe)
        return 0;
 }
 
-int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe,
-                               u32 srate, u32 ratio)
+static int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe,
+                                      u32 srate, u32 ratio)
 {
        u8 aclk = 0;
        u8 bclk = 0;
index e5a76da860816897ff7740b905f16015d71aadc0..ae7d32027bf726e0e73499880a61a07187fa6744 100644 (file)
@@ -1945,7 +1945,7 @@ static struct pci_driver meye_driver = {
 static int __init meye_init(void)
 {
        gbuffers = max(2, min((int)gbuffers, MEYE_MAX_BUFNBRS));
-       if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)
+       if (gbufsize > MEYE_MAX_BUFSIZE)
                gbufsize = MEYE_MAX_BUFSIZE;
        gbufsize = PAGE_ALIGN(gbufsize);
        printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) "
index 96a13ed197d0856389a1bd9f7cbde4ca895dfbd8..b38bce529566cdaa02b87b2855674ba5a03dd90e 100644 (file)
@@ -425,8 +425,10 @@ static int ReadEEProm(struct i2c_adapter *adapter,
                status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length);
                if (!status) {
                        *pLength = EETag[2];
+#if 0
                        if (Length < EETag[2])
-                               ; /*status=STATUS_BUFFER_OVERFLOW; */
+                               status = STATUS_BUFFER_OVERFLOW;
+#endif
                }
        }
        return status;
index c8e0d5b99d4c0d106bd02078ab1b678176d57b0d..8eeec4f50ccb4103d2db272b3c1bc6d7b2608f18 100644 (file)
@@ -752,8 +752,8 @@ void set_transfer(struct ngene_channel *chan, int state)
                if (chan->mode & NGENE_IO_TSIN)
                        chan->pBufferExchange = tsin_exchange;
                spin_unlock_irq(&chan->state_lock);
-       } else
-               ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
+       }
+               /* else printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
                           ngreadl(0x9310)); */
 
        ret = ngene_command_stream_control(dev, chan->number,
@@ -1691,7 +1691,8 @@ int __devinit ngene_probe(struct pci_dev *pci_dev,
        dev->i2c_current_bus = -1;
 
        /* Register DVB adapters and devices for both channels */
-       if (init_channels(dev) < 0)
+       stat = init_channels(dev);
+       if (stat < 0)
                goto fail2;
 
        return 0;
index f2b37e05b96479e7f534537a3208d120b408f661..8976d0e65813d26d7c2761d7172fd7549899d1d4 100644 (file)
@@ -944,8 +944,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
 
        /* board config */
        dev->board = pci_id->driver_data;
-       if (card[dev->nr] >= 0 &&
-           card[dev->nr] < saa7134_bcount)
+       if ((unsigned)card[dev->nr] < saa7134_bcount)
                dev->board = card[dev->nr];
        if (SAA7134_BOARD_UNKNOWN == dev->board)
                must_configure_manually(0);
index 0f78f5e537e22723a26d1a8036e69ed3e5cdd5e3..e761262f74750efe089cfd163d87eb0b2188909e 100644 (file)
@@ -990,7 +990,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
                dev->init_data.name = "BeholdTV";
                dev->init_data.get_key = get_key_beholdm6xx;
                dev->init_data.ir_codes = RC_MAP_BEHOLD;
-               dev->init_data.type = RC_TYPE_NEC;
+               dev->init_data.type = RC_BIT_NEC;
                info.addr = 0x2d;
                break;
        case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
index 4a77124ee70e2cbda80a414413a85346b7a832c3..3abf52711e132cfa24e8b4e16bf198eb5cc35cc3 100644 (file)
@@ -2511,7 +2511,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
        /* sanitycheck insmod options */
        if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
                gbuffers = 2;
-       if (gbufsize < 0 || gbufsize > gbufsize_max)
+       if (gbufsize > gbufsize_max)
                gbufsize = gbufsize_max;
        gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
 
index eff7135cf0e8999beb790f0c406f0d7fdd1d772e..e042963d377d0c8dc9b7c6d94225f1ccb5983549 100644 (file)
@@ -165,7 +165,7 @@ int saa7164_api_set_vbi_format(struct saa7164_port *port)
        return ret;
 }
 
-int saa7164_api_set_gop_size(struct saa7164_port *port)
+static int saa7164_api_set_gop_size(struct saa7164_port *port)
 {
        struct saa7164_dev *dev = port->dev;
        struct tmComResEncVideoGopStructure gs;
@@ -619,7 +619,7 @@ int saa7164_api_get_videomux(struct saa7164_port *port)
        return ret;
 }
 
-int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
+static int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
 {
        struct saa7164_dev *dev = port->dev;
 
@@ -822,8 +822,8 @@ int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
                &reg[0], 128, buf);
 }
 
-int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
-       struct saa7164_port *port)
+static int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
+                                         struct saa7164_port *port)
 {
        struct tmComResVBIFormatDescrHeader *fmt = &port->vbi_fmt_ntsc;
 
@@ -858,9 +858,10 @@ int saa7164_api_configure_port_vbi(struct saa7164_dev *dev,
        return 0;
 }
 
-int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
-       struct saa7164_port *port,
-       struct tmComResTSFormatDescrHeader *tsfmt)
+static int
+saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
+                                  struct saa7164_port *port,
+                                  struct tmComResTSFormatDescrHeader *tsfmt)
 {
        dprintk(DBGLVL_API, "    bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
        dprintk(DBGLVL_API, "    bDataOffset  = 0x%x\n", tsfmt->bDataOffset);
@@ -892,9 +893,10 @@ int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
        return 0;
 }
 
-int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
-       struct saa7164_port *port,
-       struct tmComResPSFormatDescrHeader *fmt)
+static int
+saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
+                                  struct saa7164_port *port,
+                                  struct tmComResPSFormatDescrHeader *fmt)
 {
        dprintk(DBGLVL_API, "    bFormatIndex = 0x%x\n", fmt->bFormatIndex);
        dprintk(DBGLVL_API, "    wPacketLength= 0x%x\n", fmt->wPacketLength);
@@ -925,7 +927,7 @@ int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
        return 0;
 }
 
-int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
+static int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
 {
        struct saa7164_port *tsport = NULL;
        struct saa7164_port *encport = NULL;
@@ -1486,7 +1488,7 @@ int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
        return ret == SAA_OK ? 0 : -EIO;
 }
 
-int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
+static int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
        u8 pin, u8 state)
 {
        int ret;
index a7f58a9987522c06a45dfcaf3f45ab138f8c3699..5f6f3094c44ecc36a23cb64eba4f38f939a36cb5 100644 (file)
@@ -81,7 +81,7 @@ void saa7164_bus_dump(struct saa7164_dev *dev)
 }
 
 /* Intensionally throw a BUG() if the state of the message bus looks corrupt */
-void saa7164_bus_verify(struct saa7164_dev *dev)
+static void saa7164_bus_verify(struct saa7164_dev *dev)
 {
        struct tmComResBusInfo *b = &dev->bus;
        int bug = 0;
@@ -106,8 +106,8 @@ void saa7164_bus_verify(struct saa7164_dev *dev)
        }
 }
 
-void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo* m,
-       void *buf)
+static void saa7164_bus_dumpmsg(struct saa7164_dev *dev, struct tmComResInfo *m,
+                               void *buf)
 {
        dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
        dprintk(DBGLVL_BUS, " .id               = %d\n",   m->id);
index 62fac7f9d04e14201fe140a20468a283fcb7afa9..cfabcbacc33dd26982c41d28ddebd9ebfaf103b7 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "saa7164.h"
 
-int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
+static int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
 {
        int i, ret = -1;
 
@@ -42,7 +42,7 @@ int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
        return ret;
 }
 
-void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
+static void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
 {
        mutex_lock(&dev->lock);
        if ((dev->cmds[seqno].inuse == 1) &&
@@ -54,7 +54,7 @@ void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
        mutex_unlock(&dev->lock);
 }
 
-void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
+static void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
 {
        mutex_lock(&dev->lock);
        if ((dev->cmds[seqno].inuse == 1) &&
@@ -64,7 +64,7 @@ void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
        mutex_unlock(&dev->lock);
 }
 
-u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
+static u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
 {
        int ret = 0;
 
@@ -132,7 +132,7 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev)
 
 /* Commands to the f/w get marshelled to/from this code then onto the PCI
  * -bus/c running buffer. */
-int saa7164_cmd_dequeue(struct saa7164_dev *dev)
+static int saa7164_cmd_dequeue(struct saa7164_dev *dev)
 {
        int loop = 1;
        int ret;
@@ -186,8 +186,8 @@ int saa7164_cmd_dequeue(struct saa7164_dev *dev)
        return SAA_OK;
 }
 
-int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg,
-       void *buf)
+static int saa7164_cmd_set(struct saa7164_dev *dev, struct tmComResInfo *msg,
+                          void *buf)
 {
        struct tmComResBusInfo *bus = &dev->bus;
        u8 cmd_sent;
@@ -259,7 +259,7 @@ out:
 /* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
  * the event never occurred, or SAA_OK if it was signaled during the wait.
  */
-int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
+static int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
 {
        wait_queue_head_t *q = NULL;
        int ret = SAA_BUS_TIMEOUT;
index 2c9ad878bef3dedab9c91a19019d7443d151affb..063047f567669f1bdc6c33bcfdca33528d56f5a3 100644 (file)
@@ -410,7 +410,7 @@ static void saa7164_work_enchandler(struct work_struct *w)
                } else
                        rp = (port->last_svc_rp + 1) % 8;
 
-               if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
+               if (rp > (port->hwcfg.buffercount - 1)) {
                        printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
                        break;
                }
@@ -486,7 +486,7 @@ static void saa7164_work_vbihandler(struct work_struct *w)
                } else
                        rp = (port->last_svc_rp + 1) % 8;
 
-               if ((rp < 0) || (rp > (port->hwcfg.buffercount - 1))) {
+               if (rp > (port->hwcfg.buffercount - 1)) {
                        printk(KERN_ERR "%s() illegal rp count %d\n", __func__, rp);
                        break;
                }
index a9ed686ad08a55acd270675359215f203f24d9c8..994018e2d0d611d0d2a34947b80469ce4448068e 100644 (file)
@@ -1101,7 +1101,8 @@ static int fops_release(struct file *file)
        return 0;
 }
 
-struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
+static struct
+saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
 {
        struct saa7164_user_buffer *ubuf = NULL;
        struct saa7164_dev *dev = port->dev;
@@ -1287,8 +1288,8 @@ static const struct v4l2_file_operations mpeg_fops = {
        .unlocked_ioctl = video_ioctl2,
 };
 
-int saa7164_g_chip_ident(struct file *file, void *fh,
-       struct v4l2_dbg_chip_ident *chip)
+static int saa7164_g_chip_ident(struct file *file, void *fh,
+                               struct v4l2_dbg_chip_ident *chip)
 {
        struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
        struct saa7164_dev *dev = port->dev;
@@ -1297,8 +1298,8 @@ int saa7164_g_chip_ident(struct file *file, void *fh,
        return 0;
 }
 
-int saa7164_g_register(struct file *file, void *fh,
-       struct v4l2_dbg_register *reg)
+static int saa7164_g_register(struct file *file, void *fh,
+                             struct v4l2_dbg_register *reg)
 {
        struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
        struct saa7164_dev *dev = port->dev;
@@ -1310,8 +1311,8 @@ int saa7164_g_register(struct file *file, void *fh,
        return 0;
 }
 
-int saa7164_s_register(struct file *file, void *fh,
-       struct v4l2_dbg_register *reg)
+static int saa7164_s_register(struct file *file, void *fh,
+                             struct v4l2_dbg_register *reg)
 {
        struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
        struct saa7164_dev *dev = port->dev;
index a266bf0169e6a7d339dd7e946f536a25a3915918..86763203d61dba58d19c0eaba9ab87bb7de237c6 100644 (file)
@@ -37,7 +37,7 @@ struct fw_header {
        u32     version;
 };
 
-int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
+static int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
 {
        u32 timeout = SAA_DEVICE_TIMEOUT;
        while ((saa7164_readl(reg) & 0x01) == 0) {
@@ -53,7 +53,7 @@ int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
        return 0;
 }
 
-int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
+static int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
 {
        u32 timeout = SAA_DEVICE_TIMEOUT;
        while (saa7164_readl(reg) & 0x01) {
@@ -71,8 +71,8 @@ int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
 
 /* TODO: move dlflags into dev-> and change to write/readl/b */
 /* TODO: Excessive levels of debug */
-int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
-       u32 dlflags, u8 *dst, u32 dstsize)
+static int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
+                                u32 dlflags, u8 *dst, u32 dstsize)
 {
        u32 reg, timeout, offset;
        u8 *srcbuf = NULL;
index d8e6c8f1407928cad755ddb2418ad53e610ba820..b4532299c0edf54247e6d7065ef9db03a23ce9c3 100644 (file)
@@ -984,7 +984,8 @@ out:
        return ret;
 }
 
-int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f)
+static int saa7164_vbi_fmt(struct file *file, void *priv,
+                          struct v4l2_format *f)
 {
        /* ntsc */
        f->fmt.vbi.samples_per_line = 1600;
@@ -1047,7 +1048,8 @@ static int fops_release(struct file *file)
        return 0;
 }
 
-struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
+static struct
+saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
 {
        struct saa7164_user_buffer *ubuf = NULL;
        struct saa7164_dev *dev = port->dev;
index 88b3b2d6cc0e9dbcbf04d50987e40b0576b9c6ae..a378662b1dcfce4450f3d0834f72901ac0a63c4c 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/netdevice.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/time.h>
 
 #include <linux/dvb/video.h>
 #include <linux/dvb/audio.h>
index 12ddb53c58dcedf00f5229e229f484238dec363e..1f8b1bb0bf9fb39b9881d9bec07e9c604d913e9f 100644 (file)
@@ -1477,8 +1477,8 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
 
        if (saa7113_init(budget_av) == 0) {
                budget_av->has_saa7113 = 1;
-
-               if (0 != saa7146_vv_init(dev, &vv_data)) {
+               err = saa7146_vv_init(dev, &vv_data);
+               if (err != 0) {
                        /* fixme: proper cleanup here */
                        ERR("cannot init vv subsystem\n");
                        return err;
index 181c7686e412aa485e755867d8fad8e7f5f13bf8..3dcfea612c42975615e7d95f5f613918d8d547d1 100644 (file)
@@ -109,6 +109,18 @@ config VIDEO_OMAP3_DEBUG
        ---help---
          Enable debug messages on OMAP 3 camera controller driver.
 
+config VIDEO_S3C_CAMIF
+       tristate "Samsung S3C24XX/S3C64XX SoC Camera Interface driver"
+       depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
+       depends on (PLAT_S3C64XX || PLAT_S3C24XX) && PM_RUNTIME
+       select VIDEOBUF2_DMA_CONTIG
+       ---help---
+         This is a v4l2 driver for s3c24xx and s3c64xx SoC series camera
+         host interface (CAMIF).
+
+         To compile this driver as a module, choose M here: the module
+         will be called s3c-camif.
+
 source "drivers/media/platform/soc_camera/Kconfig"
 source "drivers/media/platform/s5p-fimc/Kconfig"
 source "drivers/media/platform/s5p-tv/Kconfig"
index baaa55026c8ea7b71d7821fd97606ecb75dc9dfb..4817d280217162ec01b545bcd0164daa1db66b0e 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_VIDEO_CODA)              += coda.o
 
 obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE)        += m2m-deinterlace.o
 
+obj-$(CONFIG_VIDEO_S3C_CAMIF)          += s3c-camif/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)   += s5p-fimc/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG)   += s5p-jpeg/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC)    += s5p-mfc/
index cb2eb26850b179738b49975ea47d82cada2d0d11..ec476ef5b709bbe8c56e354e6fecb5d3c70902d5 100644 (file)
@@ -1050,19 +1050,7 @@ static struct platform_driver bcap_driver = {
        .probe = bcap_probe,
        .remove = __devexit_p(bcap_remove),
 };
-
-static __init int bcap_init(void)
-{
-       return platform_driver_register(&bcap_driver);
-}
-
-static __exit void bcap_exit(void)
-{
-       platform_driver_unregister(&bcap_driver);
-}
-
-module_init(bcap_init);
-module_exit(bcap_exit);
+module_platform_driver(bcap_driver);
 
 MODULE_DESCRIPTION("Analog Devices blackfin video capture driver");
 MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
index cd04ae252c301991d73eebfeb2727e6752d7b9e8..7b8b547f2d51867115f9bf5a510495e6c35baebb 100644 (file)
@@ -1540,7 +1540,7 @@ static irqreturn_t coda_irq_handler(int irq, void *data)
        u32 wr_ptr, start_ptr;
        struct coda_ctx *ctx;
 
-       __cancel_delayed_work(&dev->timeout);
+       cancel_delayed_work(&dev->timeout);
 
        /* read status register to attend the IRQ */
        coda_read(dev, CODA_REG_BIT_INT_STATUS);
@@ -1877,7 +1877,7 @@ static const struct coda_devtype coda_devdata[] = {
 
 static struct platform_device_id coda_platform_ids[] = {
        { .name = "coda-imx27", .driver_data = CODA_IMX27 },
-       { .name = "coda-imx53", .driver_data = CODA_7541 },
+       { .name = "coda-imx53", .driver_data = CODA_IMX53 },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(platform, coda_platform_ids);
index 78e26d24f63754b857d923c727c628b3ee9e5596..3c56037c82fce5e711469b585dbd157da79b01c2 100644 (file)
@@ -101,7 +101,7 @@ config VIDEO_DM644X_VPBE
        tristate "DM644X VPBE HW module"
        depends on ARCH_DAVINCI_DM644x
        select VIDEO_VPSS_SYSTEM
-       select VIDEOBUF_DMA_CONTIG
+       select VIDEOBUF2_DMA_CONTIG
        help
            Enables VPBE modules used for display on a DM644x
            SoC.
index ce0e4131c0672ba882c6a45b819ed7dfe2b960ae..030950dcfb1628d56d0a640e264750da0ea62f45 100644 (file)
@@ -1003,7 +1003,7 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev)
                status = PTR_ERR(ccdc_cfg.mclk);
                goto fail_nomap;
        }
-       if (clk_enable(ccdc_cfg.mclk)) {
+       if (clk_prepare_enable(ccdc_cfg.mclk)) {
                status = -ENODEV;
                goto fail_mclk;
        }
@@ -1014,7 +1014,7 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev)
                status = PTR_ERR(ccdc_cfg.sclk);
                goto fail_mclk;
        }
-       if (clk_enable(ccdc_cfg.sclk)) {
+       if (clk_prepare_enable(ccdc_cfg.sclk)) {
                status = -ENODEV;
                goto fail_sclk;
        }
@@ -1034,8 +1034,10 @@ static int __devinit dm355_ccdc_probe(struct platform_device *pdev)
        printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
        return 0;
 fail_sclk:
+       clk_disable_unprepare(ccdc_cfg.sclk);
        clk_put(ccdc_cfg.sclk);
 fail_mclk:
+       clk_disable_unprepare(ccdc_cfg.mclk);
        clk_put(ccdc_cfg.mclk);
 fail_nomap:
        iounmap(ccdc_cfg.base_addr);
@@ -1050,6 +1052,8 @@ static int dm355_ccdc_remove(struct platform_device *pdev)
 {
        struct resource *res;
 
+       clk_disable_unprepare(ccdc_cfg.sclk);
+       clk_disable_unprepare(ccdc_cfg.mclk);
        clk_put(ccdc_cfg.mclk);
        clk_put(ccdc_cfg.sclk);
        iounmap(ccdc_cfg.base_addr);
index ee7942b1996ed2fdb11f201891178d29c10317f3..0215ab6ebc909d3ae4b4042aa4c8880223b0beb4 100644 (file)
@@ -994,7 +994,7 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev)
                status = PTR_ERR(ccdc_cfg.mclk);
                goto fail_nomap;
        }
-       if (clk_enable(ccdc_cfg.mclk)) {
+       if (clk_prepare_enable(ccdc_cfg.mclk)) {
                status = -ENODEV;
                goto fail_mclk;
        }
@@ -1005,7 +1005,7 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev)
                status = PTR_ERR(ccdc_cfg.sclk);
                goto fail_mclk;
        }
-       if (clk_enable(ccdc_cfg.sclk)) {
+       if (clk_prepare_enable(ccdc_cfg.sclk)) {
                status = -ENODEV;
                goto fail_sclk;
        }
@@ -1013,8 +1013,10 @@ static int __devinit dm644x_ccdc_probe(struct platform_device *pdev)
        printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
        return 0;
 fail_sclk:
+       clk_disable_unprepare(ccdc_cfg.sclk);
        clk_put(ccdc_cfg.sclk);
 fail_mclk:
+       clk_disable_unprepare(ccdc_cfg.mclk);
        clk_put(ccdc_cfg.mclk);
 fail_nomap:
        iounmap(ccdc_cfg.base_addr);
@@ -1029,6 +1031,8 @@ static int dm644x_ccdc_remove(struct platform_device *pdev)
 {
        struct resource *res;
 
+       clk_disable_unprepare(ccdc_cfg.mclk);
+       clk_disable_unprepare(ccdc_cfg.sclk);
        clk_put(ccdc_cfg.mclk);
        clk_put(ccdc_cfg.sclk);
        iounmap(ccdc_cfg.base_addr);
@@ -1046,8 +1050,8 @@ static int dm644x_ccdc_suspend(struct device *dev)
        /* Disable CCDC */
        ccdc_enable(0);
        /* Disable both master and slave clock */
-       clk_disable(ccdc_cfg.mclk);
-       clk_disable(ccdc_cfg.sclk);
+       clk_disable_unprepare(ccdc_cfg.mclk);
+       clk_disable_unprepare(ccdc_cfg.sclk);
 
        return 0;
 }
@@ -1055,8 +1059,8 @@ static int dm644x_ccdc_suspend(struct device *dev)
 static int dm644x_ccdc_resume(struct device *dev)
 {
        /* Enable both master and slave clock */
-       clk_enable(ccdc_cfg.mclk);
-       clk_enable(ccdc_cfg.sclk);
+       clk_prepare_enable(ccdc_cfg.mclk);
+       clk_prepare_enable(ccdc_cfg.sclk);
        /* Restore CCDC context */
        ccdc_restore_context();
 
index b99d5423e3a8dc16d115c244e6e391f870924c79..2c26c3e1837eb05b974a8e071f62640354264407 100644 (file)
@@ -1053,7 +1053,7 @@ static int __devinit isif_probe(struct platform_device *pdev)
                status = PTR_ERR(isif_cfg.mclk);
                goto fail_mclk;
        }
-       if (clk_enable(isif_cfg.mclk)) {
+       if (clk_prepare_enable(isif_cfg.mclk)) {
                status = -ENODEV;
                goto fail_mclk;
        }
@@ -1125,6 +1125,7 @@ fail_nobase_res:
                i--;
        }
 fail_mclk:
+       clk_disable_unprepare(isif_cfg.mclk);
        clk_put(isif_cfg.mclk);
        vpfe_unregister_ccdc_device(&isif_hw_dev);
        return status;
@@ -1145,6 +1146,8 @@ static int isif_remove(struct platform_device *pdev)
                i++;
        }
        vpfe_unregister_ccdc_device(&isif_hw_dev);
+       clk_disable_unprepare(isif_cfg.mclk);
+       clk_put(isif_cfg.mclk);
        return 0;
 }
 
index 69d7a58c92c3e81191adcd3d227f7352a9e5d4d0..7f5cf9b347b2c40e22f5056a0fe062a31cfabf86 100644 (file)
@@ -612,7 +612,7 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
                        ret =  PTR_ERR(vpbe_dev->dac_clk);
                        goto fail_mutex_unlock;
                }
-               if (clk_enable(vpbe_dev->dac_clk)) {
+               if (clk_prepare_enable(vpbe_dev->dac_clk)) {
                        ret =  -ENODEV;
                        goto fail_mutex_unlock;
                }
@@ -759,8 +759,10 @@ fail_kfree_encoders:
 fail_dev_unregister:
        v4l2_device_unregister(&vpbe_dev->v4l2_dev);
 fail_clk_put:
-       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
+       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
+               clk_disable_unprepare(vpbe_dev->dac_clk);
                clk_put(vpbe_dev->dac_clk);
+       }
 fail_mutex_unlock:
        mutex_unlock(&vpbe_dev->lock);
        return ret;
@@ -777,8 +779,10 @@ fail_mutex_unlock:
 static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev)
 {
        v4l2_device_unregister(&vpbe_dev->v4l2_dev);
-       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
+       if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
+               clk_disable_unprepare(vpbe_dev->dac_clk);
                clk_put(vpbe_dev->dac_clk);
+       }
 
        kfree(vpbe_dev->amp);
        kfree(vpbe_dev->encoders);
index 161c77650e2f88ea13fedd063c43ef306a734d67..2bfde7958fefb700d948d9635a32ae9c4888ab88 100644 (file)
@@ -47,6 +47,9 @@ static int debug;
 
 module_param(debug, int, 0644);
 
+static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
+                       struct vpbe_layer *layer);
+
 static int venc_is_second_field(struct vpbe_display *disp_dev)
 {
        struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
@@ -73,10 +76,11 @@ static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
        if (layer->cur_frm == layer->next_frm)
                return;
        ktime_get_ts(&timevalue);
-       layer->cur_frm->ts.tv_sec = timevalue.tv_sec;
-       layer->cur_frm->ts.tv_usec = timevalue.tv_nsec / NSEC_PER_USEC;
-       layer->cur_frm->state = VIDEOBUF_DONE;
-       wake_up_interruptible(&layer->cur_frm->done);
+       layer->cur_frm->vb.v4l2_buf.timestamp.tv_sec =
+               timevalue.tv_sec;
+       layer->cur_frm->vb.v4l2_buf.timestamp.tv_usec =
+               timevalue.tv_nsec / NSEC_PER_USEC;
+       vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_DONE);
        /* Make cur_frm pointing to next_frm */
        layer->cur_frm = layer->next_frm;
 }
@@ -99,16 +103,14 @@ static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
         * otherwise hold on current frame
         * Get next from the buffer queue
         */
-       layer->next_frm = list_entry(
-                               layer->dma_queue.next,
-                               struct  videobuf_buffer,
-                               queue);
+       layer->next_frm = list_entry(layer->dma_queue.next,
+                         struct  vpbe_disp_buffer, list);
        /* Remove that from the buffer queue */
-       list_del(&layer->next_frm->queue);
+       list_del(&layer->next_frm->list);
        spin_unlock(&disp_obj->dma_queue_lock);
        /* Mark state of the frame to active */
-       layer->next_frm->state = VIDEOBUF_ACTIVE;
-       addr = videobuf_to_dma_contig(layer->next_frm);
+       layer->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
+       addr = vb2_dma_contig_plane_dma_addr(&layer->next_frm->vb, 0);
        osd_device->ops.start_layer(osd_device,
                        layer->layer_info.id,
                        addr,
@@ -199,39 +201,29 @@ static irqreturn_t venc_isr(int irq, void *arg)
 
 /*
  * vpbe_buffer_prepare()
- * This is the callback function called from videobuf_qbuf() function
+ * This is the callback function called from vb2_qbuf() function
  * the buffer is prepared and user space virtual address is converted into
  * physical address
  */
-static int vpbe_buffer_prepare(struct videobuf_queue *q,
-                                 struct videobuf_buffer *vb,
-                                 enum v4l2_field field)
+static int vpbe_buffer_prepare(struct vb2_buffer *vb)
 {
-       struct vpbe_fh *fh = q->priv_data;
+       struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
+       struct vb2_queue *q = vb->vb2_queue;
        struct vpbe_layer *layer = fh->layer;
        struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
        unsigned long addr;
-       int ret;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
                                "vpbe_buffer_prepare\n");
 
-       /* If buffer is not initialized, initialize it */
-       if (VIDEOBUF_NEEDS_INIT == vb->state) {
-               vb->width = layer->pix_fmt.width;
-               vb->height = layer->pix_fmt.height;
-               vb->size = layer->pix_fmt.sizeimage;
-               vb->field = field;
-
-               ret = videobuf_iolock(q, vb, NULL);
-               if (ret < 0) {
-                       v4l2_err(&vpbe_dev->v4l2_dev, "Failed to map \
-                               user address\n");
+       if (vb->state != VB2_BUF_STATE_ACTIVE &&
+               vb->state != VB2_BUF_STATE_PREPARED) {
+               vb2_set_plane_payload(vb, 0, layer->pix_fmt.sizeimage);
+               if (vb2_plane_vaddr(vb, 0) &&
+               vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
                        return -EINVAL;
-               }
-
-               addr = videobuf_to_dma_contig(vb);
 
+               addr = vb2_dma_contig_plane_dma_addr(vb, 0);
                if (q->streaming) {
                        if (!IS_ALIGNED(addr, 8)) {
                                v4l2_err(&vpbe_dev->v4l2_dev,
@@ -240,7 +232,6 @@ static int vpbe_buffer_prepare(struct videobuf_queue *q,
                                return -EINVAL;
                        }
                }
-               vb->state = VIDEOBUF_PREPARED;
        }
        return 0;
 }
@@ -249,22 +240,26 @@ static int vpbe_buffer_prepare(struct videobuf_queue *q,
  * vpbe_buffer_setup()
  * This function allocates memory for the buffers
  */
-static int vpbe_buffer_setup(struct videobuf_queue *q,
-                               unsigned int *count,
-                               unsigned int *size)
+static int
+vpbe_buffer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+                       unsigned int *nbuffers, unsigned int *nplanes,
+                       unsigned int sizes[], void *alloc_ctxs[])
+
 {
        /* Get the file handle object and layer object */
-       struct vpbe_fh *fh = q->priv_data;
+       struct vpbe_fh *fh = vb2_get_drv_priv(vq);
        struct vpbe_layer *layer = fh->layer;
        struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
 
-       *size = layer->pix_fmt.sizeimage;
-
        /* Store number of buffers allocated in numbuffer member */
-       if (*count < VPBE_DEFAULT_NUM_BUFS)
-               *count = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS;
+       if (*nbuffers < VPBE_DEFAULT_NUM_BUFS)
+               *nbuffers = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS;
+
+       *nplanes = 1;
+       sizes[0] = layer->pix_fmt.sizeimage;
+       alloc_ctxs[0] = layer->alloc_ctx;
 
        return 0;
 }
@@ -273,11 +268,12 @@ static int vpbe_buffer_setup(struct videobuf_queue *q,
  * vpbe_buffer_queue()
  * This function adds the buffer to DMA queue
  */
-static void vpbe_buffer_queue(struct videobuf_queue *q,
-                                struct videobuf_buffer *vb)
+static void vpbe_buffer_queue(struct vb2_buffer *vb)
 {
        /* Get the file handle object and layer object */
-       struct vpbe_fh *fh = q->priv_data;
+       struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
+       struct vpbe_disp_buffer *buf = container_of(vb,
+                               struct vpbe_disp_buffer, vb);
        struct vpbe_layer *layer = fh->layer;
        struct vpbe_display *disp = fh->disp_dev;
        struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
@@ -288,39 +284,125 @@ static void vpbe_buffer_queue(struct videobuf_queue *q,
 
        /* add the buffer to the DMA queue */
        spin_lock_irqsave(&disp->dma_queue_lock, flags);
-       list_add_tail(&vb->queue, &layer->dma_queue);
+       list_add_tail(&buf->list, &layer->dma_queue);
        spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
-       /* Change state of the buffer */
-       vb->state = VIDEOBUF_QUEUED;
 }
 
 /*
- * vpbe_buffer_release()
- * This function is called from the videobuf layer to free memory allocated to
+ * vpbe_buf_cleanup()
+ * This function is called from the vb2 layer to free memory allocated to
  * the buffers
  */
-static void vpbe_buffer_release(struct videobuf_queue *q,
-                                  struct videobuf_buffer *vb)
+static void vpbe_buf_cleanup(struct vb2_buffer *vb)
 {
        /* Get the file handle object and layer object */
-       struct vpbe_fh *fh = q->priv_data;
+       struct vpbe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
        struct vpbe_layer *layer = fh->layer;
        struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vpbe_disp_buffer *buf = container_of(vb,
+                                       struct vpbe_disp_buffer, vb);
+       unsigned long flags;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
-                       "vpbe_buffer_release\n");
+                       "vpbe_buf_cleanup\n");
+
+       spin_lock_irqsave(&layer->irqlock, flags);
+       if (vb->state == VB2_BUF_STATE_ACTIVE)
+               list_del_init(&buf->list);
+       spin_unlock_irqrestore(&layer->irqlock, flags);
+}
+
+static void vpbe_wait_prepare(struct vb2_queue *vq)
+{
+       struct vpbe_fh *fh = vb2_get_drv_priv(vq);
+       struct vpbe_layer *layer = fh->layer;
+
+       mutex_unlock(&layer->opslock);
+}
+
+static void vpbe_wait_finish(struct vb2_queue *vq)
+{
+       struct vpbe_fh *fh = vb2_get_drv_priv(vq);
+       struct vpbe_layer *layer = fh->layer;
+
+       mutex_lock(&layer->opslock);
+}
+
+static int vpbe_buffer_init(struct vb2_buffer *vb)
+{
+       struct vpbe_disp_buffer *buf = container_of(vb,
+                                       struct vpbe_disp_buffer, vb);
+
+       INIT_LIST_HEAD(&buf->list);
+       return 0;
+}
+
+static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct vpbe_fh *fh = vb2_get_drv_priv(vq);
+       struct vpbe_layer *layer = fh->layer;
+       struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       int ret;
+
+       /* If buffer queue is empty, return error */
+       if (list_empty(&layer->dma_queue)) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n");
+               return -EINVAL;
+       }
+       /* Get the next frame from the buffer queue */
+       layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
+                               struct vpbe_disp_buffer, list);
+       /* Remove buffer from the buffer queue */
+       list_del(&layer->cur_frm->list);
+       /* Mark state of the current frame to active */
+       layer->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
+       /* Initialize field_id and started member */
+       layer->field_id = 0;
+
+       /* Set parameters in OSD and VENC */
+       ret = vpbe_set_osd_display_params(fh->disp_dev, layer);
+       if (ret < 0)
+               return ret;
 
-       if (V4L2_MEMORY_USERPTR != layer->memory)
-               videobuf_dma_contig_free(q, vb);
+       /*
+        * if request format is yuv420 semiplanar, need to
+        * enable both video windows
+        */
+       layer->started = 1;
+       layer->layer_first_int = 1;
+
+       return ret;
+}
+
+static int vpbe_stop_streaming(struct vb2_queue *vq)
+{
+       struct vpbe_fh *fh = vb2_get_drv_priv(vq);
+       struct vpbe_layer *layer = fh->layer;
+
+       if (!vb2_is_streaming(vq))
+               return 0;
+
+       /* release all active buffers */
+       while (!list_empty(&layer->dma_queue)) {
+               layer->next_frm = list_entry(layer->dma_queue.next,
+                                               struct vpbe_disp_buffer, list);
+               list_del(&layer->next_frm->list);
+               vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR);
+       }
 
-       vb->state = VIDEOBUF_NEEDS_INIT;
+       return 0;
 }
 
-static struct videobuf_queue_ops video_qops = {
-       .buf_setup = vpbe_buffer_setup,
+static struct vb2_ops video_qops = {
+       .queue_setup = vpbe_buffer_queue_setup,
+       .wait_prepare = vpbe_wait_prepare,
+       .wait_finish = vpbe_wait_finish,
+       .buf_init = vpbe_buffer_init,
        .buf_prepare = vpbe_buffer_prepare,
+       .start_streaming = vpbe_start_streaming,
+       .stop_streaming = vpbe_stop_streaming,
+       .buf_cleanup = vpbe_buf_cleanup,
        .buf_queue = vpbe_buffer_queue,
-       .buf_release = vpbe_buffer_release,
 };
 
 static
@@ -345,7 +427,7 @@ static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
        unsigned long addr;
        int ret;
 
-       addr = videobuf_to_dma_contig(layer->cur_frm);
+       addr = vb2_dma_contig_plane_dma_addr(&layer->cur_frm->vb, 0);
        /* Set address in the display registers */
        osd_device->ops.start_layer(osd_device,
                                    layer->layer_info.id,
@@ -620,9 +702,12 @@ static int vpbe_display_querycap(struct file *file, void  *priv,
        struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
 
        cap->version = VPBE_DISPLAY_VERSION_CODE;
-       cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
-       strlcpy(cap->driver, VPBE_DISPLAY_DRIVER, sizeof(cap->driver));
-       strlcpy(cap->bus_info, "platform", sizeof(cap->bus_info));
+       cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+       snprintf(cap->driver, sizeof(cap->driver), "%s",
+               dev_name(vpbe_dev->pdev));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+                dev_name(vpbe_dev->pdev));
        strlcpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
 
        return 0;
@@ -1161,7 +1246,7 @@ static int vpbe_display_streamoff(struct file *file, void *priv,
        osd_device->ops.disable_layer(osd_device,
                        layer->layer_info.id);
        layer->started = 0;
-       ret = videobuf_streamoff(&layer->buffer_queue);
+       ret = vb2_streamoff(&layer->buffer_queue, buf_type);
 
        return ret;
 }
@@ -1199,46 +1284,15 @@ static int vpbe_display_streamon(struct file *file, void *priv,
        }
 
        /*
-        * Call videobuf_streamon to start streaming
+        * Call vb2_streamon to start streaming
         * in videobuf
         */
-       ret = videobuf_streamon(&layer->buffer_queue);
+       ret = vb2_streamon(&layer->buffer_queue, buf_type);
        if (ret) {
                v4l2_err(&vpbe_dev->v4l2_dev,
-               "error in videobuf_streamon\n");
+               "error in vb2_streamon\n");
                return ret;
        }
-       /* If buffer queue is empty, return error */
-       if (list_empty(&layer->dma_queue)) {
-               v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n");
-               goto streamoff;
-       }
-       /* Get the next frame from the buffer queue */
-       layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
-                               struct videobuf_buffer, queue);
-       /* Remove buffer from the buffer queue */
-       list_del(&layer->cur_frm->queue);
-       /* Mark state of the current frame to active */
-       layer->cur_frm->state = VIDEOBUF_ACTIVE;
-       /* Initialize field_id and started member */
-       layer->field_id = 0;
-
-       /* Set parameters in OSD and VENC */
-       ret = vpbe_set_osd_display_params(disp_dev, layer);
-       if (ret < 0)
-               goto streamoff;
-
-       /*
-        * if request format is yuv420 semiplanar, need to
-        * enable both video windows
-        */
-       layer->started = 1;
-
-       layer->layer_first_int = 1;
-
-       return ret;
-streamoff:
-       ret = videobuf_streamoff(&layer->buffer_queue);
        return ret;
 }
 
@@ -1265,10 +1319,10 @@ static int vpbe_display_dqbuf(struct file *file, void *priv,
        }
        if (file->f_flags & O_NONBLOCK)
                /* Call videobuf_dqbuf for non blocking mode */
-               ret = videobuf_dqbuf(&layer->buffer_queue, buf, 1);
+               ret = vb2_dqbuf(&layer->buffer_queue, buf, 1);
        else
                /* Call videobuf_dqbuf for blocking mode */
-               ret = videobuf_dqbuf(&layer->buffer_queue, buf, 0);
+               ret = vb2_dqbuf(&layer->buffer_queue, buf, 0);
 
        return ret;
 }
@@ -1295,7 +1349,7 @@ static int vpbe_display_qbuf(struct file *file, void *priv,
                return -EACCES;
        }
 
-       return videobuf_qbuf(&layer->buffer_queue, p);
+       return vb2_qbuf(&layer->buffer_queue, p);
 }
 
 static int vpbe_display_querybuf(struct file *file, void *priv,
@@ -1304,7 +1358,6 @@ static int vpbe_display_querybuf(struct file *file, void *priv,
        struct vpbe_fh *fh = file->private_data;
        struct vpbe_layer *layer = fh->layer;
        struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-       int ret;
 
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
                "VIDIOC_QUERYBUF, layer id = %d\n",
@@ -1314,11 +1367,8 @@ static int vpbe_display_querybuf(struct file *file, void *priv,
                v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
                return -EINVAL;
        }
-
-       /* Call videobuf_querybuf to get information */
-       ret = videobuf_querybuf(&layer->buffer_queue, buf);
-
-       return ret;
+       /* Call vb2_querybuf to get information */
+       return vb2_querybuf(&layer->buffer_queue, buf);
 }
 
 static int vpbe_display_reqbufs(struct file *file, void *priv,
@@ -1327,8 +1377,8 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
        struct vpbe_fh *fh = file->private_data;
        struct vpbe_layer *layer = fh->layer;
        struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
+       struct vb2_queue *q;
        int ret;
-
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n");
 
        if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) {
@@ -1342,15 +1392,26 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
                return -EBUSY;
        }
        /* Initialize videobuf queue as per the buffer type */
-       videobuf_queue_dma_contig_init(&layer->buffer_queue,
-                               &video_qops,
-                               vpbe_dev->pdev,
-                               &layer->irqlock,
-                               V4L2_BUF_TYPE_VIDEO_OUTPUT,
-                               layer->pix_fmt.field,
-                               sizeof(struct videobuf_buffer),
-                               fh, NULL);
+       layer->alloc_ctx = vb2_dma_contig_init_ctx(vpbe_dev->pdev);
+       if (!layer->alloc_ctx) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "Failed to get the context\n");
+               return -EINVAL;
+       }
+       q = &layer->buffer_queue;
+       memset(q, 0, sizeof(*q));
+       q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+       q->io_modes = VB2_MMAP | VB2_USERPTR;
+       q->drv_priv = fh;
+       q->ops = &video_qops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->buf_struct_size = sizeof(struct vpbe_disp_buffer);
 
+       ret = vb2_queue_init(q);
+       if (ret) {
+               v4l2_err(&vpbe_dev->v4l2_dev, "vb2_queue_init() failed\n");
+               vb2_dma_contig_cleanup_ctx(layer->alloc_ctx);
+               return ret;
+       }
        /* Set io allowed member of file handle to TRUE */
        fh->io_allowed = 1;
        /* Increment io usrs member of layer object to 1 */
@@ -1360,9 +1421,7 @@ static int vpbe_display_reqbufs(struct file *file, void *priv,
        /* Initialize buffer queue */
        INIT_LIST_HEAD(&layer->dma_queue);
        /* Allocate buffers */
-       ret = videobuf_reqbufs(&layer->buffer_queue, req_buf);
-
-       return ret;
+       return vb2_reqbufs(q, req_buf);
 }
 
 /*
@@ -1381,7 +1440,7 @@ static int vpbe_display_mmap(struct file *filep, struct vm_area_struct *vma)
 
        if (mutex_lock_interruptible(&layer->opslock))
                return -ERESTARTSYS;
-       ret = videobuf_mmap_mapper(&layer->buffer_queue, vma);
+       ret = vb2_mmap(&layer->buffer_queue, vma);
        mutex_unlock(&layer->opslock);
        return ret;
 }
@@ -1398,7 +1457,7 @@ static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait)
        v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_poll\n");
        if (layer->started) {
                mutex_lock(&layer->opslock);
-               err = videobuf_poll_stream(filep, &layer->buffer_queue, wait);
+               err = vb2_poll(&layer->buffer_queue, filep, wait);
                mutex_unlock(&layer->opslock);
        }
        return err;
@@ -1488,8 +1547,8 @@ static int vpbe_display_release(struct file *file)
                                layer->layer_info.id);
                layer->started = 0;
                /* Free buffers allocated */
-               videobuf_queue_cancel(&layer->buffer_queue);
-               videobuf_mmap_free(&layer->buffer_queue);
+               vb2_queue_release(&layer->buffer_queue);
+               vb2_dma_contig_cleanup_ctx(&layer->buffer_queue);
        }
 
        /* Decrement layer usrs counter */
index bba299dbf3967c6e7e708f9631eb9853912d1833..707f243f810d806fcc5efc04a13b66bd2a47ca63 100644 (file)
@@ -62,7 +62,7 @@ static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset)
 {
        struct osd_state *osd = sd;
 
-       u32 addr = osd->osd_base + offset;
+       void __iomem *addr = osd->osd_base + offset;
        u32 val = readl(addr) | mask;
 
        writel(val, addr);
@@ -74,7 +74,7 @@ static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset)
 {
        struct osd_state *osd = sd;
 
-       u32 addr = osd->osd_base + offset;
+       void __iomem *addr = osd->osd_base + offset;
        u32 val = readl(addr) & ~mask;
 
        writel(val, addr);
@@ -87,7 +87,7 @@ static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val,
 {
        struct osd_state *osd = sd;
 
-       u32 addr = osd->osd_base + offset;
+       void __iomem *addr = osd->osd_base + offset;
        u32 new_val = (readl(addr) & ~mask) | (val & mask);
 
        writel(new_val, addr);
@@ -1559,8 +1559,7 @@ static int osd_probe(struct platform_device *pdev)
                ret = -ENODEV;
                goto free_mem;
        }
-       osd->osd_base = (unsigned long)ioremap_nocache(res->start,
-                                                       osd->osd_size);
+       osd->osd_base = ioremap_nocache(res->start, osd->osd_size);
        if (!osd->osd_base) {
                dev_err(osd->dev, "Unable to map the OSD region\n");
                ret = -ENODEV;
index cff3c0ab501f6751c745fbdf9461a3dc745f837e..0d6cc8e4deb28889ea2286b0e84cb8a194475dd2 100644 (file)
@@ -444,7 +444,7 @@ static int __devinit vpif_probe(struct platform_device *pdev)
                status = PTR_ERR(vpif_clk);
                goto clk_fail;
        }
-       clk_enable(vpif_clk);
+       clk_prepare_enable(vpif_clk);
 
        spin_lock_init(&vpif_lock);
        dev_info(&pdev->dev, "vpif probe success\n");
@@ -460,7 +460,7 @@ fail:
 static int __devexit vpif_remove(struct platform_device *pdev)
 {
        if (vpif_clk) {
-               clk_disable(vpif_clk);
+               clk_disable_unprepare(vpif_clk);
                clk_put(vpif_clk);
        }
 
@@ -472,13 +472,13 @@ static int __devexit vpif_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int vpif_suspend(struct device *dev)
 {
-       clk_disable(vpif_clk);
+       clk_disable_unprepare(vpif_clk);
        return 0;
 }
 
 static int vpif_resume(struct device *dev)
 {
-       clk_enable(vpif_clk);
+       clk_prepare_enable(vpif_clk);
        return 0;
 }
 
index fcabc023885d06c66b33db117d5c744f138a2e45..a409ccefb38073ec2c67d74d96ea53079bc6f38a 100644 (file)
@@ -201,13 +201,16 @@ static void vpif_buffer_queue(struct vb2_buffer *vb)
        struct vpif_cap_buffer *buf = container_of(vb,
                                struct vpif_cap_buffer, vb);
        struct common_obj *common;
+       unsigned long flags;
 
        common = &ch->common[VPIF_VIDEO_INDEX];
 
        vpif_dbg(2, debug, "vpif_buffer_queue\n");
 
+       spin_lock_irqsave(&common->irqlock, flags);
        /* add the buffer to the DMA queue */
        list_add_tail(&buf->list, &common->dma_queue);
+       spin_unlock_irqrestore(&common->irqlock, flags);
 }
 
 /**
@@ -278,10 +281,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
        struct vpif_params *vpif = &ch->vpifparams;
        unsigned long addr = 0;
+       unsigned long flags;
        int ret;
 
-               /* If buffer queue is empty, return error */
+       /* If buffer queue is empty, return error */
+       spin_lock_irqsave(&common->irqlock, flags);
        if (list_empty(&common->dma_queue)) {
+               spin_unlock_irqrestore(&common->irqlock, flags);
                vpif_dbg(1, debug, "buffer queue is empty\n");
                return -EIO;
        }
@@ -291,6 +297,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
                                    struct vpif_cap_buffer, list);
        /* Remove buffer from the buffer queue */
        list_del(&common->cur_frm->list);
+       spin_unlock_irqrestore(&common->irqlock, flags);
        /* Mark state of the current frame to active */
        common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
        /* Initialize field_id and started member */
@@ -362,6 +369,7 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
        struct vpif_fh *fh = vb2_get_drv_priv(vq);
        struct channel_obj *ch = fh->channel;
        struct common_obj *common;
+       unsigned long flags;
 
        if (!vb2_is_streaming(vq))
                return 0;
@@ -369,12 +377,14 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
        common = &ch->common[VPIF_VIDEO_INDEX];
 
        /* release all active buffers */
+       spin_lock_irqsave(&common->irqlock, flags);
        while (!list_empty(&common->dma_queue)) {
                common->next_frm = list_entry(common->dma_queue.next,
                                                struct vpif_cap_buffer, list);
                list_del(&common->next_frm->list);
                vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
        }
+       spin_unlock_irqrestore(&common->irqlock, flags);
 
        return 0;
 }
@@ -420,10 +430,12 @@ static void vpif_schedule_next_buffer(struct common_obj *common)
 {
        unsigned long addr = 0;
 
+       spin_lock(&common->irqlock);
        common->next_frm = list_entry(common->dma_queue.next,
                                     struct vpif_cap_buffer, list);
        /* Remove that buffer from the buffer queue */
        list_del(&common->next_frm->list);
+       spin_unlock(&common->irqlock);
        common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
        addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
 
@@ -468,8 +480,12 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
                /* Check the field format */
                if (1 == ch->vpifparams.std_info.frm_fmt) {
                        /* Progressive mode */
-                       if (list_empty(&common->dma_queue))
+                       spin_lock(&common->irqlock);
+                       if (list_empty(&common->dma_queue)) {
+                               spin_unlock(&common->irqlock);
                                continue;
+                       }
+                       spin_unlock(&common->irqlock);
 
                        if (!channel_first_int[i][channel_id])
                                vpif_process_buffer_complete(common);
@@ -513,9 +529,13 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
                                vpif_process_buffer_complete(common);
                        } else if (1 == fid) {
                                /* odd field */
+                               spin_lock(&common->irqlock);
                                if (list_empty(&common->dma_queue) ||
-                                   (common->cur_frm != common->next_frm))
+                                   (common->cur_frm != common->next_frm)) {
+                                       spin_unlock(&common->irqlock);
                                        continue;
+                               }
+                               spin_unlock(&common->irqlock);
 
                                vpif_schedule_next_buffer(common);
                        }
@@ -1004,9 +1024,9 @@ static int vpif_reqbufs(struct file *file, void *priv,
 
        /* Initialize videobuf2 queue as per the buffer type */
        common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
-       if (!common->alloc_ctx) {
+       if (IS_ERR(common->alloc_ctx)) {
                vpif_err("Failed to get the context\n");
-               return -EINVAL;
+               return PTR_ERR(common->alloc_ctx);
        }
        q = &common->buffer_queue;
        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1715,7 +1735,7 @@ vpif_enum_dv_timings(struct file *file, void *priv,
        int ret;
 
        ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
-       if (ret == -ENOIOCTLCMD && ret == -ENODEV)
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
                return -EINVAL;
        return ret;
 }
@@ -1735,7 +1755,7 @@ vpif_query_dv_timings(struct file *file, void *priv,
        int ret;
 
        ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
-       if (ret == -ENOIOCTLCMD && ret == -ENODEV)
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
                return -ENODATA;
        return ret;
 }
index b716fbd4241f8599f90c8dbf7caf4b99e0f338bb..9f2b603be9c9b319d56b72bd99c3028df07632aa 100644 (file)
@@ -177,11 +177,14 @@ static void vpif_buffer_queue(struct vb2_buffer *vb)
                                struct vpif_disp_buffer, vb);
        struct channel_obj *ch = fh->channel;
        struct common_obj *common;
+       unsigned long flags;
 
        common = &ch->common[VPIF_VIDEO_INDEX];
 
        /* add the buffer to the DMA queue */
+       spin_lock_irqsave(&common->irqlock, flags);
        list_add_tail(&buf->list, &common->dma_queue);
+       spin_unlock_irqrestore(&common->irqlock, flags);
 }
 
 /*
@@ -246,10 +249,13 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
        struct vpif_params *vpif = &ch->vpifparams;
        unsigned long addr = 0;
+       unsigned long flags;
        int ret;
 
        /* If buffer queue is empty, return error */
+       spin_lock_irqsave(&common->irqlock, flags);
        if (list_empty(&common->dma_queue)) {
+               spin_unlock_irqrestore(&common->irqlock, flags);
                vpif_err("buffer queue is empty\n");
                return -EIO;
        }
@@ -260,6 +266,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
                                       struct vpif_disp_buffer, list);
 
        list_del(&common->cur_frm->list);
+       spin_unlock_irqrestore(&common->irqlock, flags);
        /* Mark state of the current frame to active */
        common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
 
@@ -330,6 +337,7 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
        struct vpif_fh *fh = vb2_get_drv_priv(vq);
        struct channel_obj *ch = fh->channel;
        struct common_obj *common;
+       unsigned long flags;
 
        if (!vb2_is_streaming(vq))
                return 0;
@@ -337,12 +345,14 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
        common = &ch->common[VPIF_VIDEO_INDEX];
 
        /* release all active buffers */
+       spin_lock_irqsave(&common->irqlock, flags);
        while (!list_empty(&common->dma_queue)) {
                common->next_frm = list_entry(common->dma_queue.next,
                                                struct vpif_disp_buffer, list);
                list_del(&common->next_frm->list);
                vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
        }
+       spin_unlock_irqrestore(&common->irqlock, flags);
 
        return 0;
 }
@@ -363,11 +373,13 @@ static void process_progressive_mode(struct common_obj *common)
 {
        unsigned long addr = 0;
 
+       spin_lock(&common->irqlock);
        /* Get the next buffer from buffer queue */
        common->next_frm = list_entry(common->dma_queue.next,
                                struct vpif_disp_buffer, list);
        /* Remove that buffer from the buffer queue */
        list_del(&common->next_frm->list);
+       spin_unlock(&common->irqlock);
        /* Mark status of the buffer as active */
        common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
 
@@ -398,16 +410,18 @@ static void process_interlaced_mode(int fid, struct common_obj *common)
                common->cur_frm = common->next_frm;
 
        } else if (1 == fid) {  /* odd field */
+               spin_lock(&common->irqlock);
                if (list_empty(&common->dma_queue)
                    || (common->cur_frm != common->next_frm)) {
+                       spin_unlock(&common->irqlock);
                        return;
                }
+               spin_unlock(&common->irqlock);
                /* one field is displayed configure the next
                 * frame if it is available else hold on current
                 * frame */
                /* Get next from the buffer queue */
                process_progressive_mode(common);
-
        }
 }
 
@@ -437,8 +451,12 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
                        continue;
 
                if (1 == ch->vpifparams.std_info.frm_fmt) {
-                       if (list_empty(&common->dma_queue))
+                       spin_lock(&common->irqlock);
+                       if (list_empty(&common->dma_queue)) {
+                               spin_unlock(&common->irqlock);
                                continue;
+                       }
+                       spin_unlock(&common->irqlock);
 
                        /* Progressive mode */
                        if (!channel_first_int[i][channel_id]) {
@@ -972,9 +990,9 @@ static int vpif_reqbufs(struct file *file, void *priv,
        }
        /* Initialize videobuf2 queue as per the buffer type */
        common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
-       if (!common->alloc_ctx) {
+       if (IS_ERR(common->alloc_ctx)) {
                vpif_err("Failed to get the context\n");
-               return -EINVAL;
+               return PTR_ERR(common->alloc_ctx);
        }
        q = &common->buffer_queue;
        q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
@@ -1380,7 +1398,7 @@ vpif_enum_dv_timings(struct file *file, void *priv,
        int ret;
 
        ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
-       if (ret == -ENOIOCTLCMD && ret == -ENODEV)
+       if (ret == -ENOIOCTLCMD || ret == -ENODEV)
                return -EINVAL;
        return ret;
 }
index 19cbb12a12a2c814424a32b8db8ae2b30074d687..cc7b218d047cffb5e48e0e031eaae6ae7a0bbffb 100644 (file)
@@ -982,7 +982,7 @@ static void *gsc_get_drv_data(struct platform_device *pdev)
                match = of_match_node(of_match_ptr(exynos_gsc_match),
                                        pdev->dev.of_node);
                if (match)
-                       driver_data =  match->data;
+                       driver_data = (struct gsc_driverdata *)match->data;
        } else {
                driver_data = (struct gsc_driverdata *)
                        platform_get_device_id(pdev)->driver_data;
index c065d040ed944630b9d3a4b569fcfc0c5db5f4f4..c267c57c76fdeec23c6fb51c0609929f630c0e91 100644 (file)
@@ -122,7 +122,7 @@ static void gsc_m2m_device_run(void *priv)
        struct gsc_ctx *ctx = priv;
        struct gsc_dev *gsc;
        unsigned long flags;
-       u32 ret;
+       int ret;
        bool is_set = false;
 
        if (WARN(!ctx, "null hardware context\n"))
index 31ac4dc692475a5b5f1339941617569fd936f43e..a8ddb0cacab82cc7d81e5c3f17b6d4d5f29d9a2a 100644 (file)
@@ -352,8 +352,7 @@ static int restart_video_queue(struct viu_dmaqueue *vidq)
                        return 0;
                buf = list_entry(vidq->queued.next, struct viu_buf, vb.queue);
                if (prev == NULL) {
-                       list_del(&buf->vb.queue);
-                       list_add_tail(&buf->vb.queue, &vidq->active);
+                       list_move_tail(&buf->vb.queue, &vidq->active);
 
                        dprintk(1, "Restarting video dma\n");
                        viu_stop_dma(vidq->dev);
@@ -367,8 +366,7 @@ static int restart_video_queue(struct viu_dmaqueue *vidq)
                } else if (prev->vb.width  == buf->vb.width  &&
                           prev->vb.height == buf->vb.height &&
                           prev->fmt       == buf->fmt) {
-                       list_del(&buf->vb.queue);
-                       list_add_tail(&buf->vb.queue, &vidq->active);
+                       list_move_tail(&buf->vb.queue, &vidq->active);
                        buf->vb.state = VIDEOBUF_ACTIVE;
                        dprintk(2, "[%p/%d] restart_queue - move to active\n",
                                buf, buf->vb.i);
index 45164c4f8452975d2bbd12978b3c6d9ff8229118..05c560f2ef062c8f21ba44a943fe004942de0e81 100644 (file)
@@ -218,15 +218,14 @@ static void dma_callback(void *data)
 static void deinterlace_issue_dma(struct deinterlace_ctx *ctx, int op,
                                  int do_callback)
 {
-       struct deinterlace_q_data *s_q_data, *d_q_data;
+       struct deinterlace_q_data *s_q_data;
        struct vb2_buffer *src_buf, *dst_buf;
        struct deinterlace_dev *pcdev = ctx->dev;
        struct dma_chan *chan = pcdev->dma_chan;
        struct dma_device *dmadev = chan->device;
        struct dma_async_tx_descriptor *tx;
        unsigned int s_width, s_height;
-       unsigned int d_width, d_height;
-       unsigned int d_size, s_size;
+       unsigned int s_size;
        dma_addr_t p_in, p_out;
        enum dma_ctrl_flags flags;
 
@@ -238,11 +237,6 @@ static void deinterlace_issue_dma(struct deinterlace_ctx *ctx, int op,
        s_height = s_q_data->height;
        s_size = s_width * s_height;
 
-       d_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_CAPTURE);
-       d_width = d_q_data->width;
-       d_height = d_q_data->height;
-       d_size = d_width * d_height;
-
        p_in = (dma_addr_t)vb2_dma_contig_plane_dma_addr(src_buf, 0);
        p_out = (dma_addr_t)vb2_dma_contig_plane_dma_addr(dst_buf, 0);
        if (!p_in || !p_out) {
@@ -1108,17 +1102,5 @@ static struct platform_driver deinterlace_pdrv = {
                .owner  = THIS_MODULE,
        },
 };
-
-static void __exit deinterlace_exit(void)
-{
-       platform_driver_unregister(&deinterlace_pdrv);
-}
-
-static int __init deinterlace_init(void)
-{
-       return platform_driver_register(&deinterlace_pdrv);
-}
-
-module_init(deinterlace_init);
-module_exit(deinterlace_exit);
+module_platform_driver(deinterlace_pdrv);
 
index 2e2121e98133d0ff56f7510c79a06cac8b9182d8..7487d7208dea0d8370620ab8a932cb5e6c4d95a4 100644 (file)
@@ -839,7 +839,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
        int ret;
 
        src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-       src_vq->io_modes = VB2_MMAP;
+       src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
        src_vq->drv_priv = ctx;
        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        src_vq->ops = &m2mtest_qops;
@@ -850,7 +850,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *ds
                return ret;
 
        dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       dst_vq->io_modes = VB2_MMAP;
+       dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
        dst_vq->drv_priv = ctx;
        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
        dst_vq->ops = &m2mtest_qops;
index bfa65079fc38de832e3eabc8c0227ff3f9e96fda..6b155d7be8e0d3c23e419fc3d6d2cdc6601fcd0e 100644 (file)
@@ -1013,16 +1013,4 @@ static struct platform_driver emmaprp_pdrv = {
                .owner  = THIS_MODULE,
        },
 };
-
-static void __exit emmaprp_exit(void)
-{
-       platform_driver_unregister(&emmaprp_pdrv);
-}
-
-static int __init emmaprp_init(void)
-{
-       return platform_driver_register(&emmaprp_pdrv);
-}
-
-module_init(emmaprp_init);
-module_exit(emmaprp_exit);
+module_platform_driver(emmaprp_pdrv);
index 993504015963bf8789f910b4532c2320ff653231..202d1b4b9beee7f2c04ef84ddd32150435fef9e1 100644 (file)
@@ -1174,13 +1174,6 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
        /* set default crop and win */
        omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
 
-       /* Save the changes in the overlay strcuture */
-       ret = omapvid_init(vout, 0);
-       if (ret) {
-               v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
-               goto s_fmt_vid_out_exit;
-       }
-
        ret = 0;
 
 s_fmt_vid_out_exit:
@@ -1684,20 +1677,6 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
        omap_dispc_register_isr(omap_vout_isr, vout, mask);
 
-       for (j = 0; j < ovid->num_overlays; j++) {
-               struct omap_overlay *ovl = ovid->overlays[j];
-
-               if (ovl->get_device(ovl)) {
-                       struct omap_overlay_info info;
-                       ovl->get_overlay_info(ovl, &info);
-                       info.paddr = addr;
-                       if (ovl->set_overlay_info(ovl, &info)) {
-                               ret = -EINVAL;
-                               goto streamon_err1;
-                       }
-               }
-       }
-
        /* First save the configuration in ovelray structure */
        ret = omapvid_init(vout, addr);
        if (ret)
@@ -2094,11 +2073,12 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev)
                }
                video_set_drvdata(vfd, vout);
 
-               /* Configure the overlay structure */
-               ret = omapvid_init(vid_dev->vouts[k], 0);
-               if (!ret)
-                       goto success;
+               dev_info(&pdev->dev, ": registered and initialized"
+                               " video device %d\n", vfd->minor);
+               if (k == (pdev->num_resources - 1))
+                       return 0;
 
+               continue;
 error2:
                if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
                        omap_vout_release_vrfb(vout);
@@ -2108,12 +2088,6 @@ error1:
 error:
                kfree(vout);
                return ret;
-
-success:
-               dev_info(&pdev->dev, ": registered and initialized"
-                               " video device %d\n", vfd->minor);
-               if (k == (pdev->num_resources - 1))
-                       return 0;
        }
 
        return -ENODEV;
index 7f182f0ff3daaacfd578a2590d4ec06db24f0e2a..a9f6de5b69d85949fdda469d9ed2e9aaafa8cdd5 100644 (file)
@@ -103,7 +103,8 @@ static const struct isp_res_mapping isp_res_maps[] = {
                       1 << OMAP3_ISP_IOMEM_RESZ |
                       1 << OMAP3_ISP_IOMEM_SBL |
                       1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
-                      1 << OMAP3_ISP_IOMEM_CSIPHY2,
+                      1 << OMAP3_ISP_IOMEM_CSIPHY2 |
+                      1 << OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE,
        },
        {
                .isp_rev = ISP_REVISION_15_0,
@@ -120,7 +121,8 @@ static const struct isp_res_mapping isp_res_maps[] = {
                       1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 |
                       1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 |
                       1 << OMAP3_ISP_IOMEM_CSIPHY1 |
-                      1 << OMAP3_ISP_IOMEM_CSI2C_REGS2,
+                      1 << OMAP3_ISP_IOMEM_CSI2C_REGS2 |
+                      1 << OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL,
        },
 };
 
@@ -1331,7 +1333,8 @@ void omap3isp_subclk_disable(struct isp_device *isp,
  * isp_enable_clocks - Enable ISP clocks
  * @isp: OMAP3 ISP device
  *
- * Return 0 if successful, or clk_enable return value if any of tthem fails.
+ * Return 0 if successful, or clk_prepare_enable return value if any of them
+ * fails.
  */
 static int isp_enable_clocks(struct isp_device *isp)
 {
@@ -1348,14 +1351,11 @@ static int isp_enable_clocks(struct isp_device *isp)
         * has to be twice of what is set on OMAP3430 to get
         * the required value for cam_mclk
         */
-       if (cpu_is_omap3630())
-               divisor = 1;
-       else
-               divisor = 2;
+       divisor = isp->revision == ISP_REVISION_15_0 ? 1 : 2;
 
-       r = clk_enable(isp->clock[ISP_CLK_CAM_ICK]);
+       r = clk_prepare_enable(isp->clock[ISP_CLK_CAM_ICK]);
        if (r) {
-               dev_err(isp->dev, "clk_enable cam_ick failed\n");
+               dev_err(isp->dev, "failed to enable cam_ick clock\n");
                goto out_clk_enable_ick;
        }
        r = clk_set_rate(isp->clock[ISP_CLK_DPLL4_M5_CK],
@@ -1364,9 +1364,9 @@ static int isp_enable_clocks(struct isp_device *isp)
                dev_err(isp->dev, "clk_set_rate for dpll4_m5_ck failed\n");
                goto out_clk_enable_mclk;
        }
-       r = clk_enable(isp->clock[ISP_CLK_CAM_MCLK]);
+       r = clk_prepare_enable(isp->clock[ISP_CLK_CAM_MCLK]);
        if (r) {
-               dev_err(isp->dev, "clk_enable cam_mclk failed\n");
+               dev_err(isp->dev, "failed to enable cam_mclk clock\n");
                goto out_clk_enable_mclk;
        }
        rate = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
@@ -1374,17 +1374,17 @@ static int isp_enable_clocks(struct isp_device *isp)
                dev_warn(isp->dev, "unexpected cam_mclk rate:\n"
                                   " expected : %d\n"
                                   " actual   : %ld\n", CM_CAM_MCLK_HZ, rate);
-       r = clk_enable(isp->clock[ISP_CLK_CSI2_FCK]);
+       r = clk_prepare_enable(isp->clock[ISP_CLK_CSI2_FCK]);
        if (r) {
-               dev_err(isp->dev, "clk_enable csi2_fck failed\n");
+               dev_err(isp->dev, "failed to enable csi2_fck clock\n");
                goto out_clk_enable_csi2_fclk;
        }
        return 0;
 
 out_clk_enable_csi2_fclk:
-       clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
+       clk_disable_unprepare(isp->clock[ISP_CLK_CAM_MCLK]);
 out_clk_enable_mclk:
-       clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
+       clk_disable_unprepare(isp->clock[ISP_CLK_CAM_ICK]);
 out_clk_enable_ick:
        return r;
 }
@@ -1395,9 +1395,9 @@ out_clk_enable_ick:
  */
 static void isp_disable_clocks(struct isp_device *isp)
 {
-       clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
-       clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
-       clk_disable(isp->clock[ISP_CLK_CSI2_FCK]);
+       clk_disable_unprepare(isp->clock[ISP_CLK_CAM_ICK]);
+       clk_disable_unprepare(isp->clock[ISP_CLK_CAM_MCLK]);
+       clk_disable_unprepare(isp->clock[ISP_CLK_CSI2_FCK]);
 }
 
 static const char *isp_clocks[] = {
@@ -1678,7 +1678,7 @@ isp_register_subdev_group(struct isp_device *isp,
 
                adapter = i2c_get_adapter(board_info->i2c_adapter_id);
                if (adapter == NULL) {
-                       printk(KERN_ERR "%s: Unable to get I2C adapter %d for "
+                       dev_err(isp->dev, "%s: Unable to get I2C adapter %d for "
                                "device %s\n", __func__,
                                board_info->i2c_adapter_id,
                                board_info->board_info->type);
@@ -1688,7 +1688,7 @@ isp_register_subdev_group(struct isp_device *isp,
                subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
                                board_info->board_info, NULL);
                if (subdev == NULL) {
-                       printk(KERN_ERR "%s: Unable to register subdev %s\n",
+                       dev_err(isp->dev, "%s: Unable to register subdev %s\n",
                                __func__, board_info->board_info->type);
                        continue;
                }
@@ -1713,7 +1713,7 @@ static int isp_register_entities(struct isp_device *isp)
        isp->media_dev.link_notify = isp_pipeline_link_notify;
        ret = media_device_register(&isp->media_dev);
        if (ret < 0) {
-               printk(KERN_ERR "%s: Media device registration failed (%d)\n",
+               dev_err(isp->dev, "%s: Media device registration failed (%d)\n",
                        __func__, ret);
                return ret;
        }
@@ -1721,7 +1721,7 @@ static int isp_register_entities(struct isp_device *isp)
        isp->v4l2_dev.mdev = &isp->media_dev;
        ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);
        if (ret < 0) {
-               printk(KERN_ERR "%s: V4L2 device registration failed (%d)\n",
+               dev_err(isp->dev, "%s: V4L2 device registration failed (%d)\n",
                        __func__, ret);
                goto done;
        }
@@ -1766,6 +1766,7 @@ static int isp_register_entities(struct isp_device *isp)
                struct media_entity *input;
                unsigned int flags;
                unsigned int pad;
+               unsigned int i;
 
                sensor = isp_register_subdev_group(isp, subdevs->subdevs);
                if (sensor == NULL)
@@ -1807,13 +1808,25 @@ static int isp_register_entities(struct isp_device *isp)
                        break;
 
                default:
-                       printk(KERN_ERR "%s: invalid interface type %u\n",
-                              __func__, subdevs->interface);
+                       dev_err(isp->dev, "%s: invalid interface type %u\n",
+                               __func__, subdevs->interface);
+                       ret = -EINVAL;
+                       goto done;
+               }
+
+               for (i = 0; i < sensor->entity.num_pads; i++) {
+                       if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
+                               break;
+               }
+               if (i == sensor->entity.num_pads) {
+                       dev_err(isp->dev,
+                               "%s: no source pad in external entity\n",
+                               __func__);
                        ret = -EINVAL;
                        goto done;
                }
 
-               ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+               ret = media_entity_create_link(&sensor->entity, i, input, pad,
                                               flags);
                if (ret < 0)
                        goto done;
@@ -2096,7 +2109,11 @@ static int __devinit isp_probe(struct platform_device *pdev)
        isp->isp_csiphy1.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY1");
        isp->isp_csiphy2.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY2");
 
-       /* Clocks */
+       /* Clocks
+        *
+        * The ISP clock tree is revision-dependent. We thus need to enable ICLK
+        * manually to read the revision before calling __omap3isp_get().
+        */
        ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN);
        if (ret < 0)
                goto error;
@@ -2105,6 +2122,16 @@ static int __devinit isp_probe(struct platform_device *pdev)
        if (ret < 0)
                goto error;
 
+       ret = clk_enable(isp->clock[ISP_CLK_CAM_ICK]);
+       if (ret < 0)
+               goto error;
+
+       isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
+       dev_info(isp->dev, "Revision %d.%d found\n",
+                (isp->revision & 0xf0) >> 4, isp->revision & 0x0f);
+
+       clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
+
        if (__omap3isp_get(isp, false) == NULL) {
                ret = -ENODEV;
                goto error;
@@ -2115,10 +2142,6 @@ static int __devinit isp_probe(struct platform_device *pdev)
                goto error_isp;
 
        /* Memory resources */
-       isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
-       dev_info(isp->dev, "Revision %d.%d found\n",
-                (isp->revision & 0xf0) >> 4, isp->revision & 0x0f);
-
        for (m = 0; m < ARRAY_SIZE(isp_res_maps); m++)
                if (isp->revision == isp_res_maps[m].isp_rev)
                        break;
index 8d6866942b85a2b1266a0fbfa3a692c6437d6e4b..517d348ce32b1b4871315d5a7d367cd3c475087c 100644 (file)
@@ -70,6 +70,8 @@ enum isp_mem_resources {
        OMAP3_ISP_IOMEM_CSI2C_REGS1,
        OMAP3_ISP_IOMEM_CSIPHY1,
        OMAP3_ISP_IOMEM_CSI2C_REGS2,
+       OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE,
+       OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL,
        OMAP3_ISP_IOMEM_LAST
 };
 
@@ -125,9 +127,6 @@ struct isp_reg {
 
 struct isp_platform_callback {
        u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
-       int (*csiphy_config)(struct isp_csiphy *phy,
-                            struct isp_csiphy_dphy_cfg *dphy,
-                            struct isp_csiphy_lanes_cfg *lanes);
 };
 
 /*
index 6a3ff792af7d6a3b07042bc2d7c582b9f9ba5b95..783f4b05b153703ef1a7504743102f0d41617803 100644 (file)
@@ -517,7 +517,7 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
        } while (soft_reset_retries < 5);
 
        if (soft_reset_retries == 5) {
-               printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n");
+               dev_err(isp->dev, "CSI2: Soft reset try count exceeded!\n");
                return -EBUSY;
        }
 
@@ -535,8 +535,8 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
        } while (--i > 0);
 
        if (i == 0) {
-               printk(KERN_ERR
-                      "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
+               dev_err(isp->dev,
+                       "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
                return -EBUSY;
        }
 
index 348f67ebbbc9278e67dfe9dfcfc0a77f115db2cc..3d56b33f85e867147e3df83b3670c2daa3644238 100644 (file)
 #include "ispreg.h"
 #include "ispcsiphy.h"
 
-/*
- * csiphy_lanes_config - Configuration of CSIPHY lanes.
- *
- * Updates HW configuration.
- * Called with phy->mutex taken.
- */
-static void csiphy_lanes_config(struct isp_csiphy *phy)
+static void csiphy_routing_cfg_3630(struct isp_csiphy *phy, u32 iface,
+                                   bool ccp2_strobe)
 {
-       unsigned int i;
-       u32 reg;
+       u32 reg = isp_reg_readl(
+               phy->isp, OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0);
+       u32 shift, mode;
+
+       switch (iface) {
+       case ISP_INTERFACE_CCP2B_PHY1:
+               reg &= ~OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2;
+               shift = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY1_SHIFT;
+               break;
+       case ISP_INTERFACE_CSI2C_PHY1:
+               shift = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY1_SHIFT;
+               mode = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_DPHY;
+               break;
+       case ISP_INTERFACE_CCP2B_PHY2:
+               reg |= OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2;
+               shift = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY2_SHIFT;
+               break;
+       case ISP_INTERFACE_CSI2A_PHY2:
+               shift = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY2_SHIFT;
+               mode = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_DPHY;
+               break;
+       }
 
-       reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG);
+       /* Select data/clock or data/strobe mode for CCP2 */
+       switch (iface) {
+       case ISP_INTERFACE_CCP2B_PHY1:
+       case ISP_INTERFACE_CCP2B_PHY2:
+               if (ccp2_strobe)
+                       mode = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_CCP2_DATA_STROBE;
+               else
+                       mode = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_CCP2_DATA_CLOCK;
+       }
 
-       for (i = 0; i < phy->num_data_lanes; i++) {
-               reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) |
-                        ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1));
-               reg |= (phy->lanes.data[i].pol <<
-                       ISPCSI2_PHY_CFG_DATA_POL_SHIFT(i + 1));
-               reg |= (phy->lanes.data[i].pos <<
-                       ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(i + 1));
+       reg &= ~(OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK << shift);
+       reg |= mode << shift;
+
+       isp_reg_writel(phy->isp, reg,
+                      OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0);
+}
+
+static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on,
+                                   bool ccp2_strobe)
+{
+       u32 csirxfe = OMAP343X_CONTROL_CSIRXFE_PWRDNZ
+               | OMAP343X_CONTROL_CSIRXFE_RESET;
+
+       /* Only the CCP2B on PHY1 is configurable. */
+       if (iface != ISP_INTERFACE_CCP2B_PHY1)
+               return;
+
+       if (!on) {
+               isp_reg_writel(phy->isp, 0,
+                              OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0);
+               return;
        }
 
-       reg &= ~(ISPCSI2_PHY_CFG_CLOCK_POL_MASK |
-                ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK);
-       reg |= phy->lanes.clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT;
-       reg |= phy->lanes.clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT;
+       if (ccp2_strobe)
+               csirxfe |= OMAP343X_CONTROL_CSIRXFE_SELFORM;
 
-       isp_reg_writel(phy->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG);
+       isp_reg_writel(phy->isp, csirxfe,
+                      OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0);
+}
+
+/*
+ * Configure OMAP 3 CSI PHY routing.
+ * @phy: relevant phy device
+ * @iface: ISP_INTERFACE_*
+ * @on: power on or off
+ * @ccp2_strobe: false: data/clock, true: data/strobe
+ *
+ * Note that the underlying routing configuration registers are part of the
+ * control (SCM) register space and part of the CORE power domain on both 3430
+ * and 3630, so they will not hold their contents in off-mode. This isn't an
+ * issue since the MPU power domain is forced on whilst the ISP is in use.
+ */
+static void csiphy_routing_cfg(struct isp_csiphy *phy, u32 iface, bool on,
+                              bool ccp2_strobe)
+{
+       if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL]
+           && on)
+               return csiphy_routing_cfg_3630(phy, iface, ccp2_strobe);
+       if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE])
+               return csiphy_routing_cfg_3430(phy, iface, on, ccp2_strobe);
 }
 
 /*
@@ -99,7 +157,7 @@ static int csiphy_set_power(struct isp_csiphy *phy, u32 power)
        } while ((reg != power >> 2) && (retry_count < 100));
 
        if (retry_count == 100) {
-               printk(KERN_ERR "CSI2 CIO set power failed!\n");
+               dev_err(phy->isp->dev, "CSI2 CIO set power failed!\n");
                return -EBUSY;
        }
 
@@ -107,43 +165,28 @@ static int csiphy_set_power(struct isp_csiphy *phy, u32 power)
 }
 
 /*
- * csiphy_dphy_config - Configure CSI2 D-PHY parameters.
- *
- * Called with phy->mutex taken.
+ * TCLK values are OK at their reset values
  */
-static void csiphy_dphy_config(struct isp_csiphy *phy)
-{
-       u32 reg;
-
-       /* Set up ISPCSIPHY_REG0 */
-       reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG0);
-
-       reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK |
-                ISPCSIPHY_REG0_THS_SETTLE_MASK);
-       reg |= phy->dphy.ths_term << ISPCSIPHY_REG0_THS_TERM_SHIFT;
-       reg |= phy->dphy.ths_settle << ISPCSIPHY_REG0_THS_SETTLE_SHIFT;
-
-       isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG0);
-
-       /* Set up ISPCSIPHY_REG1 */
-       reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG1);
-
-       reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK |
-                ISPCSIPHY_REG1_TCLK_MISS_MASK |
-                ISPCSIPHY_REG1_TCLK_SETTLE_MASK);
-       reg |= phy->dphy.tclk_term << ISPCSIPHY_REG1_TCLK_TERM_SHIFT;
-       reg |= phy->dphy.tclk_miss << ISPCSIPHY_REG1_TCLK_MISS_SHIFT;
-       reg |= phy->dphy.tclk_settle << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT;
-
-       isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
-}
+#define TCLK_TERM      0
+#define TCLK_MISS      1
+#define TCLK_SETTLE    14
 
-static int csiphy_config(struct isp_csiphy *phy,
-                        struct isp_csiphy_dphy_cfg *dphy,
-                        struct isp_csiphy_lanes_cfg *lanes)
+static int omap3isp_csiphy_config(struct isp_csiphy *phy)
 {
+       struct isp_csi2_device *csi2 = phy->csi2;
+       struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
+       struct isp_v4l2_subdevs_group *subdevs = pipe->external->host_priv;
+       struct isp_csiphy_lanes_cfg *lanes;
+       int csi2_ddrclk_khz;
        unsigned int used_lanes = 0;
        unsigned int i;
+       u32 reg;
+
+       if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1
+           || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
+               lanes = &subdevs->bus.ccp2.lanecfg;
+       else
+               lanes = &subdevs->bus.csi2.lanecfg;
 
        /* Clock and data lanes verification */
        for (i = 0; i < phy->num_data_lanes; i++) {
@@ -162,10 +205,61 @@ static int csiphy_config(struct isp_csiphy *phy,
        if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos))
                return -EINVAL;
 
-       mutex_lock(&phy->mutex);
-       phy->dphy = *dphy;
-       phy->lanes = *lanes;
-       mutex_unlock(&phy->mutex);
+       /*
+        * The PHY configuration is lost in off mode, that's not an
+        * issue since the MPU power domain is forced on whilst the
+        * ISP is in use.
+        */
+       csiphy_routing_cfg(phy, subdevs->interface, true,
+                          subdevs->bus.ccp2.phy_layer);
+
+       /* DPHY timing configuration */
+       /* CSI-2 is DDR and we only count used lanes. */
+       csi2_ddrclk_khz = pipe->external_rate / 1000
+               / (2 * hweight32(used_lanes)) * pipe->external_width;
+
+       reg = isp_reg_readl(csi2->isp, phy->phy_regs, ISPCSIPHY_REG0);
+
+       reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK |
+                ISPCSIPHY_REG0_THS_SETTLE_MASK);
+       /* THS_TERM: Programmed value = ceil(12.5 ns/DDRClk period) - 1. */
+       reg |= (DIV_ROUND_UP(25 * csi2_ddrclk_khz, 2000000) - 1)
+               << ISPCSIPHY_REG0_THS_TERM_SHIFT;
+       /* THS_SETTLE: Programmed value = ceil(90 ns/DDRClk period) + 3. */
+       reg |= (DIV_ROUND_UP(90 * csi2_ddrclk_khz, 1000000) + 3)
+               << ISPCSIPHY_REG0_THS_SETTLE_SHIFT;
+
+       isp_reg_writel(csi2->isp, reg, phy->phy_regs, ISPCSIPHY_REG0);
+
+       reg = isp_reg_readl(csi2->isp, phy->phy_regs, ISPCSIPHY_REG1);
+
+       reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK |
+                ISPCSIPHY_REG1_TCLK_MISS_MASK |
+                ISPCSIPHY_REG1_TCLK_SETTLE_MASK);
+       reg |= TCLK_TERM << ISPCSIPHY_REG1_TCLK_TERM_SHIFT;
+       reg |= TCLK_MISS << ISPCSIPHY_REG1_TCLK_MISS_SHIFT;
+       reg |= TCLK_SETTLE << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT;
+
+       isp_reg_writel(csi2->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
+
+       /* DPHY lane configuration */
+       reg = isp_reg_readl(csi2->isp, phy->cfg_regs, ISPCSI2_PHY_CFG);
+
+       for (i = 0; i < phy->num_data_lanes; i++) {
+               reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) |
+                        ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1));
+               reg |= (lanes->data[i].pol <<
+                       ISPCSI2_PHY_CFG_DATA_POL_SHIFT(i + 1));
+               reg |= (lanes->data[i].pos <<
+                       ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(i + 1));
+       }
+
+       reg &= ~(ISPCSI2_PHY_CFG_CLOCK_POL_MASK |
+                ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK);
+       reg |= lanes->clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT;
+       reg |= lanes->clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT;
+
+       isp_reg_writel(csi2->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG);
 
        return 0;
 }
@@ -190,8 +284,9 @@ int omap3isp_csiphy_acquire(struct isp_csiphy *phy)
        if (rval < 0)
                goto done;
 
-       csiphy_dphy_config(phy);
-       csiphy_lanes_config(phy);
+       rval = omap3isp_csiphy_config(phy);
+       if (rval < 0)
+               goto done;
 
        rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON);
        if (rval) {
@@ -211,6 +306,14 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy)
 {
        mutex_lock(&phy->mutex);
        if (phy->phy_in_use) {
+               struct isp_csi2_device *csi2 = phy->csi2;
+               struct isp_pipeline *pipe =
+                       to_isp_pipeline(&csi2->subdev.entity);
+               struct isp_v4l2_subdevs_group *subdevs =
+                       pipe->external->host_priv;
+
+               csiphy_routing_cfg(phy, subdevs->interface, false,
+                                  subdevs->bus.ccp2.phy_layer);
                csiphy_power_autoswitch_enable(phy, false);
                csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF);
                regulator_disable(phy->vdd);
@@ -227,8 +330,6 @@ int omap3isp_csiphy_init(struct isp_device *isp)
        struct isp_csiphy *phy1 = &isp->isp_csiphy1;
        struct isp_csiphy *phy2 = &isp->isp_csiphy2;
 
-       isp->platform_cb.csiphy_config = csiphy_config;
-
        phy2->isp = isp;
        phy2->csi2 = &isp->isp_csi2a;
        phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES;
index e93a661e65d99af981fb541ae7f7cdd39b47706b..14551fd7769780d3f319c6d5d146ed4742b291ac 100644 (file)
 struct isp_csi2_device;
 struct regulator;
 
-struct isp_csiphy_dphy_cfg {
-       u8 ths_term;
-       u8 ths_settle;
-       u8 tclk_term;
-       unsigned tclk_miss:1;
-       u8 tclk_settle;
-};
-
 struct isp_csiphy {
        struct isp_device *isp;
        struct mutex mutex;     /* serialize csiphy configuration */
@@ -52,8 +44,6 @@ struct isp_csiphy {
        unsigned int phy_regs;
 
        u8 num_data_lanes;      /* number of CSI2 Data Lanes supported */
-       struct isp_csiphy_lanes_cfg lanes;
-       struct isp_csiphy_dphy_cfg dphy;
 };
 
 int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
index e7f9c4292cc61b40190dee390731faa75c73f9d8..2d759c56f37c33f4f4b09362acf8125344a34937 100644 (file)
@@ -74,11 +74,14 @@ static void hist_reset_mem(struct ispstat *hist)
 
 static void hist_dma_config(struct ispstat *hist)
 {
+       struct isp_device *isp = hist->isp;
+
        hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32;
        hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT;
        hist->dma_config.frame_count = 1;
        hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT;
-       hist->dma_config.src_start = OMAP3ISP_HIST_REG_BASE + ISPHIST_DATA;
+       hist->dma_config.src_start = isp->mmio_base_phys[OMAP3_ISP_IOMEM_HIST]
+                                  + ISPHIST_DATA;
        hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC;
        hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
 }
@@ -479,6 +482,8 @@ int omap3isp_hist_init(struct isp_device *isp)
                return -ENOMEM;
 
        memset(hist, 0, sizeof(*hist));
+       hist->isp = isp;
+
        if (HIST_CONFIG_DMA)
                ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST",
                                       hist_dma_cb, hist, &hist->dma_ch);
@@ -496,7 +501,6 @@ int omap3isp_hist_init(struct isp_device *isp)
        hist->ops = &hist_ops;
        hist->priv = hist_cfg;
        hist->event_type = V4L2_EVENT_OMAP3ISP_HIST;
-       hist->isp = isp;
 
        ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops);
        if (ret) {
index 1ae1c0909ed1c5f5302dd21982f32ec39f19044e..691b92a3c3e7c18bc8b95f1d57e99c6fc9606043 100644 (file)
@@ -200,10 +200,10 @@ static void preview_enable_invalaw(struct isp_prev_device *prev, bool enable)
 
        if (enable)
                isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
-                           ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
+                           ISPPRV_PCR_INVALAW);
        else
                isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
-                           ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
+                           ISPPRV_PCR_INVALAW);
 }
 
 /*
@@ -1014,7 +1014,7 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average)
 /*
  * preview_config_input_format - Configure the input format
  * @prev: The preview engine
- * @format: Format on the preview engine sink pad
+ * @info: Sink pad format information
  *
  * Enable and configure CFA interpolation for Bayer formats and disable it for
  * greyscale formats.
@@ -1025,22 +1025,29 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average)
  * reordered to support non-GRBG Bayer patterns.
  */
 static void preview_config_input_format(struct isp_prev_device *prev,
-                                       const struct v4l2_mbus_framefmt *format)
+                                       const struct isp_format_info *info)
 {
        struct isp_device *isp = to_isp_device(prev);
        struct prev_params *params;
 
-       switch (format->code) {
-       case V4L2_MBUS_FMT_SGRBG10_1X10:
+       if (info->width == 8)
+               isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+                           ISPPRV_PCR_WIDTH);
+       else
+               isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
+                           ISPPRV_PCR_WIDTH);
+
+       switch (info->flavor) {
+       case V4L2_MBUS_FMT_SGRBG8_1X8:
                prev->params.cfa_order = 0;
                break;
-       case V4L2_MBUS_FMT_SRGGB10_1X10:
+       case V4L2_MBUS_FMT_SRGGB8_1X8:
                prev->params.cfa_order = 1;
                break;
-       case V4L2_MBUS_FMT_SBGGR10_1X10:
+       case V4L2_MBUS_FMT_SBGGR8_1X8:
                prev->params.cfa_order = 2;
                break;
-       case V4L2_MBUS_FMT_SGBRG10_1X10:
+       case V4L2_MBUS_FMT_SGBRG8_1X8:
                prev->params.cfa_order = 3;
                break;
        default:
@@ -1081,7 +1088,8 @@ static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
        unsigned int elv = prev->crop.top + prev->crop.height - 1;
        u32 features;
 
-       if (format->code != V4L2_MBUS_FMT_Y10_1X10) {
+       if (format->code != V4L2_MBUS_FMT_Y8_1X8 &&
+           format->code != V4L2_MBUS_FMT_Y10_1X10) {
                sph -= 2;
                eph += 2;
                slv -= 2;
@@ -1389,6 +1397,7 @@ static unsigned int preview_max_out_width(struct isp_prev_device *prev)
 static void preview_configure(struct isp_prev_device *prev)
 {
        struct isp_device *isp = to_isp_device(prev);
+       const struct isp_format_info *info;
        struct v4l2_mbus_framefmt *format;
        unsigned long flags;
        u32 update;
@@ -1402,17 +1411,18 @@ static void preview_configure(struct isp_prev_device *prev)
 
        /* PREV_PAD_SINK */
        format = &prev->formats[PREV_PAD_SINK];
+       info = omap3isp_video_format_info(format->code);
 
        preview_adjust_bandwidth(prev);
 
-       preview_config_input_format(prev, format);
+       preview_config_input_format(prev, info);
        preview_config_input_size(prev, active);
 
        if (prev->input == PREVIEW_INPUT_CCDC)
                preview_config_inlineoffset(prev, 0);
        else
-               preview_config_inlineoffset(prev,
-                               ALIGN(format->width, 0x20) * 2);
+               preview_config_inlineoffset(prev, ALIGN(format->width, 0x20) *
+                                           info->bpp);
 
        preview_setup_hw(prev, update, active);
 
@@ -1709,6 +1719,11 @@ __preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
 
 /* previewer format descriptions */
 static const unsigned int preview_input_fmts[] = {
+       V4L2_MBUS_FMT_Y8_1X8,
+       V4L2_MBUS_FMT_SGRBG8_1X8,
+       V4L2_MBUS_FMT_SRGGB8_1X8,
+       V4L2_MBUS_FMT_SBGGR8_1X8,
+       V4L2_MBUS_FMT_SGBRG8_1X8,
        V4L2_MBUS_FMT_Y10_1X10,
        V4L2_MBUS_FMT_SGRBG10_1X10,
        V4L2_MBUS_FMT_SRGGB10_1X10,
index e2c57f334c5d4a4da780069bf5869eb383f4b4a0..b7d90e6fb01dc043c240a20bd27ae444dd96fc79 100644 (file)
 
 #define CM_CAM_MCLK_HZ                 172800000       /* Hz */
 
-/* ISP Submodules offset */
-
-#define L4_34XX_BASE                   0x48000000
-#define OMAP3430_ISP_BASE              (L4_34XX_BASE + 0xBC000)
-
-#define OMAP3ISP_REG_BASE              OMAP3430_ISP_BASE
-#define OMAP3ISP_REG(offset)           (OMAP3ISP_REG_BASE + (offset))
-
-#define OMAP3ISP_CCP2_REG_OFFSET       0x0400
-#define OMAP3ISP_CCP2_REG_BASE         (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_CCP2_REG_OFFSET)
-#define OMAP3ISP_CCP2_REG(offset)      (OMAP3ISP_CCP2_REG_BASE + (offset))
-
-#define OMAP3ISP_CCDC_REG_OFFSET       0x0600
-#define OMAP3ISP_CCDC_REG_BASE         (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_CCDC_REG_OFFSET)
-#define OMAP3ISP_CCDC_REG(offset)      (OMAP3ISP_CCDC_REG_BASE + (offset))
-
-#define OMAP3ISP_HIST_REG_OFFSET       0x0A00
-#define OMAP3ISP_HIST_REG_BASE         (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_HIST_REG_OFFSET)
-#define OMAP3ISP_HIST_REG(offset)      (OMAP3ISP_HIST_REG_BASE + (offset))
-
-#define OMAP3ISP_H3A_REG_OFFSET                0x0C00
-#define OMAP3ISP_H3A_REG_BASE          (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_H3A_REG_OFFSET)
-#define OMAP3ISP_H3A_REG(offset)       (OMAP3ISP_H3A_REG_BASE + (offset))
-
-#define OMAP3ISP_PREV_REG_OFFSET       0x0E00
-#define OMAP3ISP_PREV_REG_BASE         (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_PREV_REG_OFFSET)
-#define OMAP3ISP_PREV_REG(offset)      (OMAP3ISP_PREV_REG_BASE + (offset))
-
-#define OMAP3ISP_RESZ_REG_OFFSET       0x1000
-#define OMAP3ISP_RESZ_REG_BASE         (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_RESZ_REG_OFFSET)
-#define OMAP3ISP_RESZ_REG(offset)      (OMAP3ISP_RESZ_REG_BASE + (offset))
-
-#define OMAP3ISP_SBL_REG_OFFSET                0x1200
-#define OMAP3ISP_SBL_REG_BASE          (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_SBL_REG_OFFSET)
-#define OMAP3ISP_SBL_REG(offset)       (OMAP3ISP_SBL_REG_BASE + (offset))
-
-#define OMAP3ISP_CSI2A_REGS1_REG_OFFSET        0x1800
-#define OMAP3ISP_CSI2A_REGS1_REG_BASE  (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_CSI2A_REGS1_REG_OFFSET)
-#define OMAP3ISP_CSI2A_REGS1_REG(offset)                               \
-                               (OMAP3ISP_CSI2A_REGS1_REG_BASE + (offset))
-
-#define OMAP3ISP_CSIPHY2_REG_OFFSET    0x1970
-#define OMAP3ISP_CSIPHY2_REG_BASE      (OMAP3ISP_REG_BASE +    \
-                                        OMAP3ISP_CSIPHY2_REG_OFFSET)
-#define OMAP3ISP_CSIPHY2_REG(offset)   (OMAP3ISP_CSIPHY2_REG_BASE + (offset))
-
-#define OMAP3ISP_CSI2A_REGS2_REG_OFFSET        0x19C0
-#define OMAP3ISP_CSI2A_REGS2_REG_BASE  (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_CSI2A_REGS2_REG_OFFSET)
-#define OMAP3ISP_CSI2A_REGS2_REG(offset)                               \
-                               (OMAP3ISP_CSI2A_REGS2_REG_BASE + (offset))
-
-#define OMAP3ISP_CSI2C_REGS1_REG_OFFSET        0x1C00
-#define OMAP3ISP_CSI2C_REGS1_REG_BASE  (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_CSI2C_REGS1_REG_OFFSET)
-#define OMAP3ISP_CSI2C_REGS1_REG(offset)                               \
-                               (OMAP3ISP_CSI2C_REGS1_REG_BASE + (offset))
-
-#define OMAP3ISP_CSIPHY1_REG_OFFSET    0x1D70
-#define OMAP3ISP_CSIPHY1_REG_BASE      (OMAP3ISP_REG_BASE +    \
-                                        OMAP3ISP_CSIPHY1_REG_OFFSET)
-#define OMAP3ISP_CSIPHY1_REG(offset)   (OMAP3ISP_CSIPHY1_REG_BASE + (offset))
-
-#define OMAP3ISP_CSI2C_REGS2_REG_OFFSET        0x1DC0
-#define OMAP3ISP_CSI2C_REGS2_REG_BASE  (OMAP3ISP_REG_BASE +            \
-                                        OMAP3ISP_CSI2C_REGS2_REG_OFFSET)
-#define OMAP3ISP_CSI2C_REGS2_REG(offset)                               \
-                               (OMAP3ISP_CSI2C_REGS2_REG_BASE + (offset))
-
 /* ISP module register offset */
 
 #define ISP_REVISION                   (0x000)
 #define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_MASK          \
        (0x7fffff << ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT)
 
+/* -----------------------------------------------------------------------------
+ * CONTROL registers for CSI-2 phy routing
+ */
+
+/* OMAP343X_CONTROL_CSIRXFE */
+#define OMAP343X_CONTROL_CSIRXFE_CSIB_INV      (1 << 7)
+#define OMAP343X_CONTROL_CSIRXFE_RESENABLE     (1 << 8)
+#define OMAP343X_CONTROL_CSIRXFE_SELFORM       (1 << 10)
+#define OMAP343X_CONTROL_CSIRXFE_PWRDNZ                (1 << 12)
+#define OMAP343X_CONTROL_CSIRXFE_RESET         (1 << 13)
+
+/* OMAP3630_CONTROL_CAMERA_PHY_CTRL */
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY1_SHIFT    2
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY2_SHIFT    0
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_DPHY          0x0
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_CCP2_DATA_STROBE 0x1
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_CCP2_DATA_CLOCK 0x2
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_GPI           0x3
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK          0x3
+/* CCP2B: set to receive data from PHY2 instead of PHY1 */
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2      (1 << 4)
+
 #endif /* OMAP3_ISP_REG_H */
index e7939869bda76c1037366223e6691fc456ca6876..61e17f9bd8b92148457a45e973aefdb0487dbcec 100644 (file)
@@ -257,7 +257,7 @@ static int isp_stat_buf_queue(struct ispstat *stat)
        if (!stat->active_buf)
                return STAT_NO_BUF;
 
-       do_gettimeofday(&stat->active_buf->ts);
+       ktime_get_ts(&stat->active_buf->ts);
 
        stat->active_buf->buf_size = stat->buf_size;
        if (isp_stat_buf_check_magic(stat, stat->active_buf)) {
@@ -537,7 +537,8 @@ int omap3isp_stat_request_statistics(struct ispstat *stat,
                return PTR_ERR(buf);
        }
 
-       data->ts = buf->ts;
+       data->ts.tv_sec = buf->ts.tv_sec;
+       data->ts.tv_usec = buf->ts.tv_nsec / NSEC_PER_USEC;
        data->config_counter = buf->config_counter;
        data->frame_number = buf->frame_number;
        data->buf_size = buf->buf_size;
index fd15094de34aa45005076bea18dd0025cd048e2e..9a047c929b9f95d47a758267cc341c92bd4f5c8c 100644 (file)
@@ -50,7 +50,7 @@ struct ispstat_buffer {
        struct iovm_struct *iovm;
        void *virt_addr;
        dma_addr_t dma_addr;
-       struct timeval ts;
+       struct timespec ts;
        u32 buf_size;
        u32 frame_number;
        u16 config_counter;
index 3311d6bb3456f7d62329bdc8ad9016fc88c65a48..e0d73a642186d34ae63d841cabe3f42c57604acd 100644 (file)
@@ -1392,7 +1392,8 @@ int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
 
        ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
        if (ret < 0)
-               printk(KERN_ERR "%s: could not register video device (%d)\n",
+               dev_err(video->isp->dev,
+                       "%s: could not register video device (%d)\n",
                        __func__, ret);
 
        return ret;
diff --git a/drivers/media/platform/s3c-camif/Makefile b/drivers/media/platform/s3c-camif/Makefile
new file mode 100644 (file)
index 0000000..50bf8c5
--- /dev/null
@@ -0,0 +1,5 @@
+# Makefile for s3c244x/s3c64xx CAMIF driver
+
+s3c-camif-objs := camif-core.o camif-capture.o camif-regs.o
+
+obj-$(CONFIG_VIDEO_S3C_CAMIF) += s3c-camif.o
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
new file mode 100644 (file)
index 0000000..a55793c
--- /dev/null
@@ -0,0 +1,1672 @@
+/*
+ * s3c24xx/s3c64xx SoC series Camera Interface (CAMIF) driver
+ *
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ * Copyright (C) 2012 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Based on drivers/media/platform/s5p-fimc,
+ * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/bug.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/ratelimit.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+#include <media/media-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "camif-core.h"
+#include "camif-regs.h"
+
+static int debug;
+module_param(debug, int, 0644);
+
+/* Locking: called with vp->camif->slock spinlock held */
+static void camif_cfg_video_path(struct camif_vp *vp)
+{
+       WARN_ON(s3c_camif_get_scaler_config(vp, &vp->scaler));
+       camif_hw_set_scaler(vp);
+       camif_hw_set_flip(vp);
+       camif_hw_set_target_format(vp);
+       camif_hw_set_output_dma(vp);
+}
+
+static void camif_prepare_dma_offset(struct camif_vp *vp)
+{
+       struct camif_frame *f = &vp->out_frame;
+
+       f->dma_offset.initial = f->rect.top * f->f_width + f->rect.left;
+       f->dma_offset.line = f->f_width - (f->rect.left + f->rect.width);
+
+       pr_debug("dma_offset: initial: %d, line: %d\n",
+                f->dma_offset.initial, f->dma_offset.line);
+}
+
+/* Locking: called with camif->slock spinlock held */
+static int s3c_camif_hw_init(struct camif_dev *camif, struct camif_vp *vp)
+{
+       const struct s3c_camif_variant *variant = camif->variant;
+
+       if (camif->sensor.sd == NULL || vp->out_fmt == NULL)
+               return -EINVAL;
+
+       if (variant->ip_revision == S3C244X_CAMIF_IP_REV)
+               camif_hw_clear_fifo_overflow(vp);
+       camif_hw_set_camera_bus(camif);
+       camif_hw_set_source_format(camif);
+       camif_hw_set_camera_crop(camif);
+       camif_hw_set_test_pattern(camif, camif->test_pattern);
+       if (variant->has_img_effect)
+               camif_hw_set_effect(camif, camif->colorfx,
+                               camif->colorfx_cb, camif->colorfx_cr);
+       if (variant->ip_revision == S3C6410_CAMIF_IP_REV)
+               camif_hw_set_input_path(vp);
+       camif_cfg_video_path(vp);
+       vp->state &= ~ST_VP_CONFIG;
+
+       return 0;
+}
+
+/*
+ * Initialize the video path, only up from the scaler stage. The camera
+ * input interface set up is skipped. This is useful to enable one of the
+ * video paths when the other is already running.
+ * Locking: called with camif->slock spinlock held.
+ */
+static int s3c_camif_hw_vp_init(struct camif_dev *camif, struct camif_vp *vp)
+{
+       unsigned int ip_rev = camif->variant->ip_revision;
+
+       if (vp->out_fmt == NULL)
+               return -EINVAL;
+
+       camif_prepare_dma_offset(vp);
+       if (ip_rev == S3C244X_CAMIF_IP_REV)
+               camif_hw_clear_fifo_overflow(vp);
+       camif_cfg_video_path(vp);
+       vp->state &= ~ST_VP_CONFIG;
+       return 0;
+}
+
+static int sensor_set_power(struct camif_dev *camif, int on)
+{
+       struct cam_sensor *sensor = &camif->sensor;
+       int err = 0;
+
+       if (!on == camif->sensor.power_count)
+               err = v4l2_subdev_call(sensor->sd, core, s_power, on);
+       if (!err)
+               sensor->power_count += on ? 1 : -1;
+
+       pr_debug("on: %d, power_count: %d, err: %d\n",
+                on, sensor->power_count, err);
+
+       return err;
+}
+
+static int sensor_set_streaming(struct camif_dev *camif, int on)
+{
+       struct cam_sensor *sensor = &camif->sensor;
+       int err = 0;
+
+       if (!on == camif->sensor.stream_count)
+               err = v4l2_subdev_call(sensor->sd, video, s_stream, on);
+       if (!err)
+               sensor->stream_count += on ? 1 : -1;
+
+       pr_debug("on: %d, stream_count: %d, err: %d\n",
+                on, sensor->stream_count, err);
+
+       return err;
+}
+
+/*
+ * Reinitialize the driver so it is ready to start streaming again.
+ * Return any buffers to vb2, perform CAMIF software reset and
+ * turn off streaming at the data pipeline (sensor) if required.
+ */
+static int camif_reinitialize(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       struct camif_buffer *buf;
+       unsigned long flags;
+       bool streaming;
+
+       spin_lock_irqsave(&camif->slock, flags);
+       streaming = vp->state & ST_VP_SENSOR_STREAMING;
+
+       vp->state &= ~(ST_VP_PENDING | ST_VP_RUNNING | ST_VP_OFF |
+                      ST_VP_ABORTING | ST_VP_STREAMING |
+                      ST_VP_SENSOR_STREAMING | ST_VP_LASTIRQ);
+
+       /* Release unused buffers */
+       while (!list_empty(&vp->pending_buf_q)) {
+               buf = camif_pending_queue_pop(vp);
+               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+       }
+
+       while (!list_empty(&vp->active_buf_q)) {
+               buf = camif_active_queue_pop(vp);
+               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+       }
+
+       spin_unlock_irqrestore(&camif->slock, flags);
+
+       if (!streaming)
+               return 0;
+
+       return sensor_set_streaming(camif, 0);
+}
+
+static bool s3c_vp_active(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       unsigned long flags;
+       bool ret;
+
+       spin_lock_irqsave(&camif->slock, flags);
+       ret = (vp->state & ST_VP_RUNNING) || (vp->state & ST_VP_PENDING);
+       spin_unlock_irqrestore(&camif->slock, flags);
+
+       return ret;
+}
+
+static bool camif_is_streaming(struct camif_dev *camif)
+{
+       unsigned long flags;
+       bool status;
+
+       spin_lock_irqsave(&camif->slock, flags);
+       status = camif->stream_count > 0;
+       spin_unlock_irqrestore(&camif->slock, flags);
+
+       return status;
+}
+
+static int camif_stop_capture(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       unsigned long flags;
+       int ret;
+
+       if (!s3c_vp_active(vp))
+               return 0;
+
+       spin_lock_irqsave(&camif->slock, flags);
+       vp->state &= ~(ST_VP_OFF | ST_VP_LASTIRQ);
+       vp->state |= ST_VP_ABORTING;
+       spin_unlock_irqrestore(&camif->slock, flags);
+
+       ret = wait_event_timeout(vp->irq_queue,
+                          !(vp->state & ST_VP_ABORTING),
+                          msecs_to_jiffies(CAMIF_STOP_TIMEOUT));
+
+       spin_lock_irqsave(&camif->slock, flags);
+
+       if (ret == 0 && !(vp->state & ST_VP_OFF)) {
+               /* Timed out, forcibly stop capture */
+               vp->state &= ~(ST_VP_OFF | ST_VP_ABORTING |
+                              ST_VP_LASTIRQ);
+
+               camif_hw_disable_capture(vp);
+               camif_hw_enable_scaler(vp, false);
+       }
+
+       spin_unlock_irqrestore(&camif->slock, flags);
+
+       return camif_reinitialize(vp);
+}
+
+static int camif_prepare_addr(struct camif_vp *vp, struct vb2_buffer *vb,
+                             struct camif_addr *paddr)
+{
+       struct camif_frame *frame = &vp->out_frame;
+       u32 pix_size;
+
+       if (vb == NULL || frame == NULL)
+               return -EINVAL;
+
+       pix_size = frame->rect.width * frame->rect.height;
+
+       pr_debug("colplanes: %d, pix_size: %u\n",
+                vp->out_fmt->colplanes, pix_size);
+
+       paddr->y = vb2_dma_contig_plane_dma_addr(vb, 0);
+
+       switch (vp->out_fmt->colplanes) {
+       case 1:
+               paddr->cb = 0;
+               paddr->cr = 0;
+               break;
+       case 2:
+               /* decompose Y into Y/Cb */
+               paddr->cb = (u32)(paddr->y + pix_size);
+               paddr->cr = 0;
+               break;
+       case 3:
+               paddr->cb = (u32)(paddr->y + pix_size);
+               /* decompose Y into Y/Cb/Cr */
+               if (vp->out_fmt->color == IMG_FMT_YCBCR422P)
+                       paddr->cr = (u32)(paddr->cb + (pix_size >> 1));
+               else /* 420 */
+                       paddr->cr = (u32)(paddr->cb + (pix_size >> 2));
+
+               if (vp->out_fmt->color == IMG_FMT_YCRCB420)
+                       swap(paddr->cb, paddr->cr);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       pr_debug("DMA address: y: %#x  cb: %#x cr: %#x\n",
+                paddr->y, paddr->cb, paddr->cr);
+
+       return 0;
+}
+
+irqreturn_t s3c_camif_irq_handler(int irq, void *priv)
+{
+       struct camif_vp *vp = priv;
+       struct camif_dev *camif = vp->camif;
+       unsigned int ip_rev = camif->variant->ip_revision;
+       unsigned int status;
+
+       spin_lock(&camif->slock);
+
+       if (ip_rev == S3C6410_CAMIF_IP_REV)
+               camif_hw_clear_pending_irq(vp);
+
+       status = camif_hw_get_status(vp);
+
+       if (ip_rev == S3C244X_CAMIF_IP_REV && (status & CISTATUS_OVF_MASK)) {
+               camif_hw_clear_fifo_overflow(vp);
+               goto unlock;
+       }
+
+       if (vp->state & ST_VP_ABORTING) {
+               if (vp->state & ST_VP_OFF) {
+                       /* Last IRQ */
+                       vp->state &= ~(ST_VP_OFF | ST_VP_ABORTING |
+                                      ST_VP_LASTIRQ);
+                       wake_up(&vp->irq_queue);
+                       goto unlock;
+               } else if (vp->state & ST_VP_LASTIRQ) {
+                       camif_hw_disable_capture(vp);
+                       camif_hw_enable_scaler(vp, false);
+                       camif_hw_set_lastirq(vp, false);
+                       vp->state |= ST_VP_OFF;
+               } else {
+                       /* Disable capture, enable last IRQ */
+                       camif_hw_set_lastirq(vp, true);
+                       vp->state |= ST_VP_LASTIRQ;
+               }
+       }
+
+       if (!list_empty(&vp->pending_buf_q) && (vp->state & ST_VP_RUNNING) &&
+           !list_empty(&vp->active_buf_q)) {
+               unsigned int index;
+               struct camif_buffer *vbuf;
+               struct timeval *tv;
+               struct timespec ts;
+               /*
+                * Get previous DMA write buffer index:
+                * 0 => DMA buffer 0, 2;
+                * 1 => DMA buffer 1, 3.
+                */
+               index = (CISTATUS_FRAMECNT(status) + 2) & 1;
+
+               ktime_get_ts(&ts);
+               vbuf = camif_active_queue_peek(vp, index);
+
+               if (!WARN_ON(vbuf == NULL)) {
+                       /* Dequeue a filled buffer */
+                       tv = &vbuf->vb.v4l2_buf.timestamp;
+                       tv->tv_sec = ts.tv_sec;
+                       tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+                       vbuf->vb.v4l2_buf.sequence = vp->frame_sequence++;
+                       vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
+
+                       /* Set up an empty buffer at the DMA engine */
+                       vbuf = camif_pending_queue_pop(vp);
+                       vbuf->index = index;
+                       camif_hw_set_output_addr(vp, &vbuf->paddr, index);
+                       camif_hw_set_output_addr(vp, &vbuf->paddr, index + 2);
+
+                       /* Scheduled in H/W, add to the queue */
+                       camif_active_queue_add(vp, vbuf);
+               }
+       } else if (!(vp->state & ST_VP_ABORTING) &&
+                  (vp->state & ST_VP_PENDING))  {
+               vp->state |= ST_VP_RUNNING;
+       }
+
+       if (vp->state & ST_VP_CONFIG) {
+               camif_prepare_dma_offset(vp);
+               camif_hw_set_camera_crop(camif);
+               camif_hw_set_scaler(vp);
+               camif_hw_set_flip(vp);
+               camif_hw_set_test_pattern(camif, camif->test_pattern);
+               if (camif->variant->has_img_effect)
+                       camif_hw_set_effect(camif, camif->colorfx,
+                                   camif->colorfx_cb, camif->colorfx_cr);
+               vp->state &= ~ST_VP_CONFIG;
+       }
+unlock:
+       spin_unlock(&camif->slock);
+       return IRQ_HANDLED;
+}
+
+static int start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct camif_vp *vp = vb2_get_drv_priv(vq);
+       struct camif_dev *camif = vp->camif;
+       unsigned long flags;
+       int ret;
+
+       /*
+        * We assume the codec capture path is always activated
+        * first, before the preview path starts streaming.
+        * This is required to avoid internal FIFO overflow and
+        * a need for CAMIF software reset.
+        */
+       spin_lock_irqsave(&camif->slock, flags);
+
+       if (camif->stream_count == 0) {
+               camif_hw_reset(camif);
+               ret = s3c_camif_hw_init(camif, vp);
+       } else {
+               ret = s3c_camif_hw_vp_init(camif, vp);
+       }
+       spin_unlock_irqrestore(&camif->slock, flags);
+
+       if (ret < 0) {
+               camif_reinitialize(vp);
+               return ret;
+       }
+
+       spin_lock_irqsave(&camif->slock, flags);
+       vp->frame_sequence = 0;
+       vp->state |= ST_VP_PENDING;
+
+       if (!list_empty(&vp->pending_buf_q) &&
+           (!(vp->state & ST_VP_STREAMING) ||
+            !(vp->state & ST_VP_SENSOR_STREAMING))) {
+
+               camif_hw_enable_scaler(vp, vp->scaler.enable);
+               camif_hw_enable_capture(vp);
+               vp->state |= ST_VP_STREAMING;
+
+               if (!(vp->state & ST_VP_SENSOR_STREAMING)) {
+                       vp->state |= ST_VP_SENSOR_STREAMING;
+                       spin_unlock_irqrestore(&camif->slock, flags);
+                       ret = sensor_set_streaming(camif, 1);
+                       if (ret)
+                               v4l2_err(&vp->vdev, "Sensor s_stream failed\n");
+                       if (debug)
+                               camif_hw_dump_regs(camif, __func__);
+
+                       return ret;
+               }
+       }
+
+       spin_unlock_irqrestore(&camif->slock, flags);
+       return 0;
+}
+
+static int stop_streaming(struct vb2_queue *vq)
+{
+       struct camif_vp *vp = vb2_get_drv_priv(vq);
+       return camif_stop_capture(vp);
+}
+
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
+                      unsigned int *num_buffers, unsigned int *num_planes,
+                      unsigned int sizes[], void *allocators[])
+{
+       const struct v4l2_pix_format *pix = NULL;
+       struct camif_vp *vp = vb2_get_drv_priv(vq);
+       struct camif_dev *camif = vp->camif;
+       struct camif_frame *frame = &vp->out_frame;
+       const struct camif_fmt *fmt = vp->out_fmt;
+       unsigned int size;
+
+       if (pfmt) {
+               pix = &pfmt->fmt.pix;
+               fmt = s3c_camif_find_format(vp, &pix->pixelformat, -1);
+               size = (pix->width * pix->height * fmt->depth) / 8;
+       } else {
+               size = (frame->f_width * frame->f_height * fmt->depth) / 8;
+       }
+
+       if (fmt == NULL)
+               return -EINVAL;
+       *num_planes = 1;
+
+       if (pix)
+               sizes[0] = max(size, pix->sizeimage);
+       else
+               sizes[0] = size;
+       allocators[0] = camif->alloc_ctx;
+
+       pr_debug("size: %u\n", sizes[0]);
+       return 0;
+}
+
+static int buffer_prepare(struct vb2_buffer *vb)
+{
+       struct camif_vp *vp = vb2_get_drv_priv(vb->vb2_queue);
+
+       if (vp->out_fmt == NULL)
+               return -EINVAL;
+
+       if (vb2_plane_size(vb, 0) < vp->payload) {
+               v4l2_err(&vp->vdev, "buffer too small: %lu, required: %u\n",
+                        vb2_plane_size(vb, 0), vp->payload);
+               return -EINVAL;
+       }
+       vb2_set_plane_payload(vb, 0, vp->payload);
+
+       return 0;
+}
+
+static void buffer_queue(struct vb2_buffer *vb)
+{
+       struct camif_buffer *buf = container_of(vb, struct camif_buffer, vb);
+       struct camif_vp *vp = vb2_get_drv_priv(vb->vb2_queue);
+       struct camif_dev *camif = vp->camif;
+       unsigned long flags;
+
+       spin_lock_irqsave(&camif->slock, flags);
+       WARN_ON(camif_prepare_addr(vp, &buf->vb, &buf->paddr));
+
+       if (!(vp->state & ST_VP_STREAMING) && vp->active_buffers < 2) {
+               /* Schedule an empty buffer in H/W */
+               buf->index = vp->buf_index;
+
+               camif_hw_set_output_addr(vp, &buf->paddr, buf->index);
+               camif_hw_set_output_addr(vp, &buf->paddr, buf->index + 2);
+
+               camif_active_queue_add(vp, buf);
+               vp->buf_index = !vp->buf_index;
+       } else {
+               camif_pending_queue_add(vp, buf);
+       }
+
+       if (vb2_is_streaming(&vp->vb_queue) && !list_empty(&vp->pending_buf_q)
+               && !(vp->state & ST_VP_STREAMING)) {
+
+               vp->state |= ST_VP_STREAMING;
+               camif_hw_enable_scaler(vp, vp->scaler.enable);
+               camif_hw_enable_capture(vp);
+               spin_unlock_irqrestore(&camif->slock, flags);
+
+               if (!(vp->state & ST_VP_SENSOR_STREAMING)) {
+                       if (sensor_set_streaming(camif, 1) == 0)
+                               vp->state |= ST_VP_SENSOR_STREAMING;
+                       else
+                               v4l2_err(&vp->vdev, "Sensor s_stream failed\n");
+
+                       if (debug)
+                               camif_hw_dump_regs(camif, __func__);
+               }
+               return;
+       }
+       spin_unlock_irqrestore(&camif->slock, flags);
+}
+
+static void camif_lock(struct vb2_queue *vq)
+{
+       struct camif_vp *vp = vb2_get_drv_priv(vq);
+       mutex_lock(&vp->camif->lock);
+}
+
+static void camif_unlock(struct vb2_queue *vq)
+{
+       struct camif_vp *vp = vb2_get_drv_priv(vq);
+       mutex_unlock(&vp->camif->lock);
+}
+
+static const struct vb2_ops s3c_camif_qops = {
+       .queue_setup     = queue_setup,
+       .buf_prepare     = buffer_prepare,
+       .buf_queue       = buffer_queue,
+       .wait_prepare    = camif_unlock,
+       .wait_finish     = camif_lock,
+       .start_streaming = start_streaming,
+       .stop_streaming  = stop_streaming,
+};
+
+static int s3c_camif_open(struct file *file)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       struct camif_dev *camif = vp->camif;
+       int ret;
+
+       pr_debug("[vp%d] state: %#x,  owner: %p, pid: %d\n", vp->id,
+                vp->state, vp->owner, task_pid_nr(current));
+
+       if (mutex_lock_interruptible(&camif->lock))
+               return -ERESTARTSYS;
+
+       ret = v4l2_fh_open(file);
+       if (ret < 0)
+               goto unlock;
+
+       ret = pm_runtime_get_sync(camif->dev);
+       if (ret < 0)
+               goto err_pm;
+
+       ret = sensor_set_power(camif, 1);
+       if (!ret)
+               goto unlock;
+
+       pm_runtime_put(camif->dev);
+err_pm:
+       v4l2_fh_release(file);
+unlock:
+       mutex_unlock(&camif->lock);
+       return ret;
+}
+
+static int s3c_camif_close(struct file *file)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       struct camif_dev *camif = vp->camif;
+       int ret;
+
+       pr_debug("[vp%d] state: %#x, owner: %p, pid: %d\n", vp->id,
+                vp->state, vp->owner, task_pid_nr(current));
+
+       mutex_lock(&camif->lock);
+
+       if (vp->owner == file->private_data) {
+               camif_stop_capture(vp);
+               vb2_queue_release(&vp->vb_queue);
+               vp->owner = NULL;
+       }
+
+       sensor_set_power(camif, 0);
+
+       pm_runtime_put(camif->dev);
+       ret = v4l2_fh_release(file);
+
+       mutex_unlock(&camif->lock);
+       return ret;
+}
+
+static unsigned int s3c_camif_poll(struct file *file,
+                                  struct poll_table_struct *wait)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       struct camif_dev *camif = vp->camif;
+       int ret;
+
+       mutex_lock(&camif->lock);
+       if (vp->owner && vp->owner != file->private_data)
+               ret = -EBUSY;
+       else
+               ret = vb2_poll(&vp->vb_queue, file, wait);
+
+       mutex_unlock(&camif->lock);
+       return ret;
+}
+
+static int s3c_camif_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       int ret;
+
+       if (vp->owner && vp->owner != file->private_data)
+               ret = -EBUSY;
+       else
+               ret = vb2_mmap(&vp->vb_queue, vma);
+
+       return ret;
+}
+
+static const struct v4l2_file_operations s3c_camif_fops = {
+       .owner          = THIS_MODULE,
+       .open           = s3c_camif_open,
+       .release        = s3c_camif_close,
+       .poll           = s3c_camif_poll,
+       .unlocked_ioctl = video_ioctl2,
+       .mmap           = s3c_camif_mmap,
+};
+
+/*
+ * Video node IOCTLs
+ */
+
+static int s3c_camif_vidioc_querycap(struct file *file, void *priv,
+                                    struct v4l2_capability *cap)
+{
+       struct camif_vp *vp = video_drvdata(file);
+
+       strlcpy(cap->driver, S3C_CAMIF_DRIVER_NAME, sizeof(cap->driver));
+       strlcpy(cap->card, S3C_CAMIF_DRIVER_NAME, sizeof(cap->card));
+       snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s.%d",
+                dev_name(vp->camif->dev), vp->id);
+
+       cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+       return 0;
+}
+
+static int s3c_camif_vidioc_enum_input(struct file *file, void *priv,
+                                      struct v4l2_input *input)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       struct v4l2_subdev *sensor = vp->camif->sensor.sd;
+
+       if (input->index || sensor == NULL)
+               return -EINVAL;
+
+       input->type = V4L2_INPUT_TYPE_CAMERA;
+       strlcpy(input->name, sensor->name, sizeof(input->name));
+       return 0;
+}
+
+static int s3c_camif_vidioc_s_input(struct file *file, void *priv,
+                                   unsigned int i)
+{
+       return i == 0 ? 0 : -EINVAL;
+}
+
+static int s3c_camif_vidioc_g_input(struct file *file, void *priv,
+                                   unsigned int *i)
+{
+       *i = 0;
+       return 0;
+}
+
+static int s3c_camif_vidioc_enum_fmt(struct file *file, void *priv,
+                                    struct v4l2_fmtdesc *f)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       const struct camif_fmt *fmt;
+
+       fmt = s3c_camif_find_format(vp, NULL, f->index);
+       if (!fmt)
+               return -EINVAL;
+
+       strlcpy(f->description, fmt->name, sizeof(f->description));
+       f->pixelformat = fmt->fourcc;
+
+       pr_debug("fmt(%d): %s\n", f->index, f->description);
+       return 0;
+}
+
+static int s3c_camif_vidioc_g_fmt(struct file *file, void *priv,
+                                 struct v4l2_format *f)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       struct camif_frame *frame = &vp->out_frame;
+       const struct camif_fmt *fmt = vp->out_fmt;
+
+       pix->bytesperline = frame->f_width * fmt->ybpp;
+       pix->sizeimage = vp->payload;
+
+       pix->pixelformat = fmt->fourcc;
+       pix->width = frame->f_width;
+       pix->height = frame->f_height;
+       pix->field = V4L2_FIELD_NONE;
+       pix->colorspace = V4L2_COLORSPACE_JPEG;
+
+       return 0;
+}
+
+static int __camif_video_try_format(struct camif_vp *vp,
+                                   struct v4l2_pix_format *pix,
+                                   const struct camif_fmt **ffmt)
+{
+       struct camif_dev *camif = vp->camif;
+       struct v4l2_rect *crop = &camif->camif_crop;
+       unsigned int wmin, hmin, sc_hrmax, sc_vrmax;
+       const struct vp_pix_limits *pix_lim;
+       const struct camif_fmt *fmt;
+
+       fmt = s3c_camif_find_format(vp, &pix->pixelformat, 0);
+
+       if (WARN_ON(fmt == NULL))
+               return -EINVAL;
+
+       if (ffmt)
+               *ffmt = fmt;
+
+       pix_lim = &camif->variant->vp_pix_limits[vp->id];
+
+       pr_debug("fmt: %ux%u, crop: %ux%u, bytesperline: %u\n",
+                pix->width, pix->height, crop->width, crop->height,
+                pix->bytesperline);
+       /*
+        * Calculate minimum width and height according to the configured
+        * camera input interface crop rectangle and the resizer's capabilities.
+        */
+       sc_hrmax = min(SCALER_MAX_RATIO, 1 << (ffs(crop->width) - 3));
+       sc_vrmax = min(SCALER_MAX_RATIO, 1 << (ffs(crop->height) - 1));
+
+       wmin = max_t(u32, pix_lim->min_out_width, crop->width / sc_hrmax);
+       wmin = round_up(wmin, pix_lim->out_width_align);
+       hmin = max_t(u32, 8, crop->height / sc_vrmax);
+       hmin = round_up(hmin, 8);
+
+       v4l_bound_align_image(&pix->width, wmin, pix_lim->max_sc_out_width,
+                             ffs(pix_lim->out_width_align) - 1,
+                             &pix->height, hmin, pix_lim->max_height, 0, 0);
+
+       pix->bytesperline = pix->width * fmt->ybpp;
+       pix->sizeimage = (pix->width * pix->height * fmt->depth) / 8;
+       pix->pixelformat = fmt->fourcc;
+       pix->colorspace = V4L2_COLORSPACE_JPEG;
+       pix->field = V4L2_FIELD_NONE;
+
+       pr_debug("%ux%u, wmin: %d, hmin: %d, sc_hrmax: %d, sc_vrmax: %d\n",
+                pix->width, pix->height, wmin, hmin, sc_hrmax, sc_vrmax);
+
+       return 0;
+}
+
+static int s3c_camif_vidioc_try_fmt(struct file *file, void *priv,
+                                   struct v4l2_format *f)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       return __camif_video_try_format(vp, &f->fmt.pix, NULL);
+}
+
+static int s3c_camif_vidioc_s_fmt(struct file *file, void *priv,
+                                 struct v4l2_format *f)
+{
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       struct camif_vp *vp = video_drvdata(file);
+       struct camif_frame *out_frame = &vp->out_frame;
+       const struct camif_fmt *fmt = NULL;
+       int ret;
+
+       pr_debug("[vp%d]\n", vp->id);
+
+       if (vb2_is_busy(&vp->vb_queue))
+               return -EBUSY;
+
+       ret = __camif_video_try_format(vp, &f->fmt.pix, &fmt);
+       if (ret < 0)
+               return ret;
+
+       vp->out_fmt = fmt;
+       vp->payload = pix->sizeimage;
+       out_frame->f_width = pix->width;
+       out_frame->f_height = pix->height;
+
+       /* Reset composition rectangle */
+       out_frame->rect.width = pix->width;
+       out_frame->rect.height = pix->height;
+       out_frame->rect.left = 0;
+       out_frame->rect.top = 0;
+
+       if (vp->owner == NULL)
+               vp->owner = priv;
+
+       pr_debug("%ux%u. payload: %u. fmt: %s. %d %d. sizeimage: %d. bpl: %d\n",
+               out_frame->f_width, out_frame->f_height, vp->payload, fmt->name,
+               pix->width * pix->height * fmt->depth, fmt->depth,
+               pix->sizeimage, pix->bytesperline);
+
+       return 0;
+}
+
+/* Only check pixel formats at the sensor and the camif subdev pads */
+static int camif_pipeline_validate(struct camif_dev *camif)
+{
+       struct v4l2_subdev_format src_fmt;
+       struct media_pad *pad;
+       int ret;
+
+       /* Retrieve format at the sensor subdev source pad */
+       pad = media_entity_remote_source(&camif->pads[0]);
+       if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+               return -EPIPE;
+
+       src_fmt.pad = pad->index;
+       src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+       ret = v4l2_subdev_call(camif->sensor.sd, pad, get_fmt, NULL, &src_fmt);
+       if (ret < 0 && ret != -ENOIOCTLCMD)
+               return -EPIPE;
+
+       if (src_fmt.format.width != camif->mbus_fmt.width ||
+           src_fmt.format.height != camif->mbus_fmt.height ||
+           src_fmt.format.code != camif->mbus_fmt.code)
+               return -EPIPE;
+
+       return 0;
+}
+
+static int s3c_camif_streamon(struct file *file, void *priv,
+                             enum v4l2_buf_type type)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       struct camif_dev *camif = vp->camif;
+       struct media_entity *sensor = &camif->sensor.sd->entity;
+       int ret;
+
+       pr_debug("[vp%d]\n", vp->id);
+
+       if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if (vp->owner && vp->owner != priv)
+               return -EBUSY;
+
+       if (s3c_vp_active(vp))
+               return 0;
+
+       ret = media_entity_pipeline_start(sensor, camif->m_pipeline);
+       if (ret < 0)
+               return ret;
+
+       ret = camif_pipeline_validate(camif);
+       if (ret < 0) {
+               media_entity_pipeline_stop(sensor);
+               return ret;
+       }
+
+       return vb2_streamon(&vp->vb_queue, type);
+}
+
+static int s3c_camif_streamoff(struct file *file, void *priv,
+                              enum v4l2_buf_type type)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       struct camif_dev *camif = vp->camif;
+       int ret;
+
+       pr_debug("[vp%d]\n", vp->id);
+
+       if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if (vp->owner && vp->owner != priv)
+               return -EBUSY;
+
+       ret = vb2_streamoff(&vp->vb_queue, type);
+       if (ret == 0)
+               media_entity_pipeline_stop(&camif->sensor.sd->entity);
+       return ret;
+}
+
+static int s3c_camif_reqbufs(struct file *file, void *priv,
+                            struct v4l2_requestbuffers *rb)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       int ret;
+
+       pr_debug("[vp%d] rb count: %d, owner: %p, priv: %p\n",
+                vp->id, rb->count, vp->owner, priv);
+
+       if (vp->owner && vp->owner != priv)
+               return -EBUSY;
+
+       if (rb->count)
+               rb->count = max_t(u32, CAMIF_REQ_BUFS_MIN, rb->count);
+       else
+               vp->owner = NULL;
+
+       ret = vb2_reqbufs(&vp->vb_queue, rb);
+       if (!ret) {
+               vp->reqbufs_count = rb->count;
+               if (vp->owner == NULL && rb->count > 0)
+                       vp->owner = priv;
+       }
+
+       return ret;
+}
+
+static int s3c_camif_querybuf(struct file *file, void *priv,
+                             struct v4l2_buffer *buf)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       return vb2_querybuf(&vp->vb_queue, buf);
+}
+
+static int s3c_camif_qbuf(struct file *file, void *priv,
+                         struct v4l2_buffer *buf)
+{
+       struct camif_vp *vp = video_drvdata(file);
+
+       pr_debug("[vp%d]\n", vp->id);
+
+       if (vp->owner && vp->owner != priv)
+               return -EBUSY;
+
+       return vb2_qbuf(&vp->vb_queue, buf);
+}
+
+static int s3c_camif_dqbuf(struct file *file, void *priv,
+                          struct v4l2_buffer *buf)
+{
+       struct camif_vp *vp = video_drvdata(file);
+
+       pr_debug("[vp%d] sequence: %d\n", vp->id, vp->frame_sequence);
+
+       if (vp->owner && vp->owner != priv)
+               return -EBUSY;
+
+       return vb2_dqbuf(&vp->vb_queue, buf, file->f_flags & O_NONBLOCK);
+}
+
+static int s3c_camif_create_bufs(struct file *file, void *priv,
+                                struct v4l2_create_buffers *create)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       int ret;
+
+       if (vp->owner && vp->owner != priv)
+               return -EBUSY;
+
+       create->count = max_t(u32, 1, create->count);
+       ret = vb2_create_bufs(&vp->vb_queue, create);
+
+       if (!ret && vp->owner == NULL)
+               vp->owner = priv;
+
+       return ret;
+}
+
+static int s3c_camif_prepare_buf(struct file *file, void *priv,
+                                struct v4l2_buffer *b)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       return vb2_prepare_buf(&vp->vb_queue, b);
+}
+
+static int s3c_camif_g_selection(struct file *file, void *priv,
+                                struct v4l2_selection *sel)
+{
+       struct camif_vp *vp = video_drvdata(file);
+
+       if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+       case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+               sel->r.left = 0;
+               sel->r.top = 0;
+               sel->r.width = vp->out_frame.f_width;
+               sel->r.height = vp->out_frame.f_height;
+               return 0;
+
+       case V4L2_SEL_TGT_COMPOSE:
+               sel->r = vp->out_frame.rect;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static void __camif_try_compose(struct camif_dev *camif, struct camif_vp *vp,
+                               struct v4l2_rect *r)
+{
+       /* s3c244x doesn't support composition */
+       if (camif->variant->ip_revision == S3C244X_CAMIF_IP_REV) {
+               *r = vp->out_frame.rect;
+               return;
+       }
+
+       /* TODO: s3c64xx */
+}
+
+static int s3c_camif_s_selection(struct file *file, void *priv,
+                                struct v4l2_selection *sel)
+{
+       struct camif_vp *vp = video_drvdata(file);
+       struct camif_dev *camif = vp->camif;
+       struct v4l2_rect rect = sel->r;
+       unsigned long flags;
+
+       if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+           sel->target != V4L2_SEL_TGT_COMPOSE)
+               return -EINVAL;
+
+       __camif_try_compose(camif, vp, &rect);
+
+       sel->r = rect;
+       spin_lock_irqsave(&camif->slock, flags);
+       vp->out_frame.rect = rect;
+       vp->state |= ST_VP_CONFIG;
+       spin_unlock_irqrestore(&camif->slock, flags);
+
+       pr_debug("type: %#x, target: %#x, flags: %#x, (%d,%d)/%dx%d\n",
+               sel->type, sel->target, sel->flags,
+               sel->r.left, sel->r.top, sel->r.width, sel->r.height);
+
+       return 0;
+}
+
+static const struct v4l2_ioctl_ops s3c_camif_ioctl_ops = {
+       .vidioc_querycap          = s3c_camif_vidioc_querycap,
+       .vidioc_enum_input        = s3c_camif_vidioc_enum_input,
+       .vidioc_g_input           = s3c_camif_vidioc_g_input,
+       .vidioc_s_input           = s3c_camif_vidioc_s_input,
+       .vidioc_enum_fmt_vid_cap  = s3c_camif_vidioc_enum_fmt,
+       .vidioc_try_fmt_vid_cap   = s3c_camif_vidioc_try_fmt,
+       .vidioc_s_fmt_vid_cap     = s3c_camif_vidioc_s_fmt,
+       .vidioc_g_fmt_vid_cap     = s3c_camif_vidioc_g_fmt,
+       .vidioc_g_selection       = s3c_camif_g_selection,
+       .vidioc_s_selection       = s3c_camif_s_selection,
+       .vidioc_reqbufs           = s3c_camif_reqbufs,
+       .vidioc_querybuf          = s3c_camif_querybuf,
+       .vidioc_prepare_buf       = s3c_camif_prepare_buf,
+       .vidioc_create_bufs       = s3c_camif_create_bufs,
+       .vidioc_qbuf              = s3c_camif_qbuf,
+       .vidioc_dqbuf             = s3c_camif_dqbuf,
+       .vidioc_streamon          = s3c_camif_streamon,
+       .vidioc_streamoff         = s3c_camif_streamoff,
+       .vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+       .vidioc_log_status        = v4l2_ctrl_log_status,
+};
+
+/*
+ * Video node controls
+ */
+static int s3c_camif_video_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct camif_vp *vp = ctrl->priv;
+       struct camif_dev *camif = vp->camif;
+       unsigned long flags;
+
+       pr_debug("[vp%d] ctrl: %s, value: %d\n", vp->id,
+                ctrl->name, ctrl->val);
+
+       spin_lock_irqsave(&camif->slock, flags);
+
+       switch (ctrl->id) {
+       case V4L2_CID_HFLIP:
+               vp->hflip = ctrl->val;
+               break;
+
+       case V4L2_CID_VFLIP:
+               vp->vflip = ctrl->val;
+               break;
+       }
+
+       vp->state |= ST_VP_CONFIG;
+       spin_unlock_irqrestore(&camif->slock, flags);
+       return 0;
+}
+
+/* Codec and preview video node control ops */
+static const struct v4l2_ctrl_ops s3c_camif_video_ctrl_ops = {
+       .s_ctrl = s3c_camif_video_s_ctrl,
+};
+
+int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
+{
+       struct camif_vp *vp = &camif->vp[idx];
+       struct vb2_queue *q = &vp->vb_queue;
+       struct video_device *vfd = &vp->vdev;
+       struct v4l2_ctrl *ctrl;
+       int ret;
+
+       memset(vfd, 0, sizeof(*vfd));
+       snprintf(vfd->name, sizeof(vfd->name), "camif-%s",
+                vp->id == 0 ? "codec" : "preview");
+
+       vfd->fops = &s3c_camif_fops;
+       vfd->ioctl_ops = &s3c_camif_ioctl_ops;
+       vfd->v4l2_dev = &camif->v4l2_dev;
+       vfd->minor = -1;
+       vfd->release = video_device_release_empty;
+       vfd->lock = &camif->lock;
+       vp->reqbufs_count = 0;
+
+       INIT_LIST_HEAD(&vp->pending_buf_q);
+       INIT_LIST_HEAD(&vp->active_buf_q);
+
+       memset(q, 0, sizeof(*q));
+       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       q->io_modes = VB2_MMAP | VB2_USERPTR;
+       q->ops = &s3c_camif_qops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->buf_struct_size = sizeof(struct camif_buffer);
+       q->drv_priv = vp;
+
+       ret = vb2_queue_init(q);
+       if (ret)
+               goto err_vd_rel;
+
+       vp->pad.flags = MEDIA_PAD_FL_SINK;
+       ret = media_entity_init(&vfd->entity, 1, &vp->pad, 0);
+       if (ret)
+               goto err_vd_rel;
+
+       video_set_drvdata(vfd, vp);
+       set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
+
+       v4l2_ctrl_handler_init(&vp->ctrl_handler, 1);
+       ctrl = v4l2_ctrl_new_std(&vp->ctrl_handler, &s3c_camif_video_ctrl_ops,
+                                V4L2_CID_HFLIP, 0, 1, 1, 0);
+       if (ctrl)
+               ctrl->priv = vp;
+       ctrl = v4l2_ctrl_new_std(&vp->ctrl_handler, &s3c_camif_video_ctrl_ops,
+                                V4L2_CID_VFLIP, 0, 1, 1, 0);
+       if (ctrl)
+               ctrl->priv = vp;
+
+       ret = vp->ctrl_handler.error;
+       if (ret < 0)
+               goto err_me_cleanup;
+
+       vfd->ctrl_handler = &vp->ctrl_handler;
+
+       ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+       if (ret)
+               goto err_ctrlh_free;
+
+       v4l2_info(&camif->v4l2_dev, "registered %s as /dev/%s\n",
+                 vfd->name, video_device_node_name(vfd));
+       return 0;
+
+err_ctrlh_free:
+       v4l2_ctrl_handler_free(&vp->ctrl_handler);
+err_me_cleanup:
+       media_entity_cleanup(&vfd->entity);
+err_vd_rel:
+       video_device_release(vfd);
+       return ret;
+}
+
+void s3c_camif_unregister_video_node(struct camif_dev *camif, int idx)
+{
+       struct video_device *vfd = &camif->vp[idx].vdev;
+
+       if (video_is_registered(vfd)) {
+               video_unregister_device(vfd);
+               media_entity_cleanup(&vfd->entity);
+               v4l2_ctrl_handler_free(vfd->ctrl_handler);
+       }
+}
+
+/* Media bus pixel formats supported at the camif input */
+static const enum v4l2_mbus_pixelcode camif_mbus_formats[] = {
+       V4L2_MBUS_FMT_YUYV8_2X8,
+       V4L2_MBUS_FMT_YVYU8_2X8,
+       V4L2_MBUS_FMT_UYVY8_2X8,
+       V4L2_MBUS_FMT_VYUY8_2X8,
+};
+
+/*
+ *  Camera input interface subdev operations
+ */
+
+static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+                                       struct v4l2_subdev_fh *fh,
+                                       struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->index >= ARRAY_SIZE(camif_mbus_formats))
+               return -EINVAL;
+
+       code->code = camif_mbus_formats[code->index];
+       return 0;
+}
+
+static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
+                                   struct v4l2_subdev_fh *fh,
+                                   struct v4l2_subdev_format *fmt)
+{
+       struct camif_dev *camif = v4l2_get_subdevdata(sd);
+       struct v4l2_mbus_framefmt *mf = &fmt->format;
+
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+               fmt->format = *mf;
+               return 0;
+       }
+
+       mutex_lock(&camif->lock);
+
+       switch (fmt->pad) {
+       case CAMIF_SD_PAD_SINK:
+               /* full camera input pixel size */
+               *mf = camif->mbus_fmt;
+               break;
+
+       case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
+               /* crop rectangle at camera interface input */
+               mf->width = camif->camif_crop.width;
+               mf->height = camif->camif_crop.height;
+               mf->code = camif->mbus_fmt.code;
+               break;
+       }
+
+       mutex_unlock(&camif->lock);
+       mf->colorspace = V4L2_COLORSPACE_JPEG;
+       return 0;
+}
+
+static void __camif_subdev_try_format(struct camif_dev *camif,
+                               struct v4l2_mbus_framefmt *mf, int pad)
+{
+       const struct s3c_camif_variant *variant = camif->variant;
+       const struct vp_pix_limits *pix_lim;
+       int i = ARRAY_SIZE(camif_mbus_formats);
+
+       /* FIXME: constraints against codec or preview path ? */
+       pix_lim = &variant->vp_pix_limits[VP_CODEC];
+
+       while (i-- >= 0)
+               if (camif_mbus_formats[i] == mf->code)
+                       break;
+
+       mf->code = camif_mbus_formats[i];
+
+       if (pad == CAMIF_SD_PAD_SINK) {
+               v4l_bound_align_image(&mf->width, 8, CAMIF_MAX_PIX_WIDTH,
+                                     ffs(pix_lim->out_width_align) - 1,
+                                     &mf->height, 8, CAMIF_MAX_PIX_HEIGHT, 0,
+                                     0);
+       } else {
+               struct v4l2_rect *crop = &camif->camif_crop;
+               v4l_bound_align_image(&mf->width, 8, crop->width,
+                                     ffs(pix_lim->out_width_align) - 1,
+                                     &mf->height, 8, crop->height,
+                                     0, 0);
+       }
+
+       v4l2_dbg(1, debug, &camif->subdev, "%ux%u\n", mf->width, mf->height);
+}
+
+static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
+                                   struct v4l2_subdev_fh *fh,
+                                   struct v4l2_subdev_format *fmt)
+{
+       struct camif_dev *camif = v4l2_get_subdevdata(sd);
+       struct v4l2_mbus_framefmt *mf = &fmt->format;
+       struct v4l2_rect *crop = &camif->camif_crop;
+       int i;
+
+       v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %ux%u\n",
+                fmt->pad, mf->code, mf->width, mf->height);
+
+       mf->colorspace = V4L2_COLORSPACE_JPEG;
+       mutex_lock(&camif->lock);
+
+       /*
+        * No pixel format change at the camera input is allowed
+        * while streaming.
+        */
+       if (vb2_is_busy(&camif->vp[VP_CODEC].vb_queue) ||
+           vb2_is_busy(&camif->vp[VP_PREVIEW].vb_queue)) {
+               mutex_unlock(&camif->lock);
+               return -EBUSY;
+       }
+
+       __camif_subdev_try_format(camif, mf, fmt->pad);
+
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+               *mf = fmt->format;
+               mutex_unlock(&camif->lock);
+               return 0;
+       }
+
+       switch (fmt->pad) {
+       case CAMIF_SD_PAD_SINK:
+               camif->mbus_fmt = *mf;
+               /* Reset sink crop rectangle. */
+               crop->width = mf->width;
+               crop->height = mf->height;
+               crop->left = 0;
+               crop->top = 0;
+               /*
+                * Reset source format (the camif's crop rectangle)
+                * and the video output resolution.
+                */
+               for (i = 0; i < CAMIF_VP_NUM; i++) {
+                       struct camif_frame *frame = &camif->vp[i].out_frame;
+                       frame->rect = *crop;
+                       frame->f_width = mf->width;
+                       frame->f_height = mf->height;
+               }
+               break;
+
+       case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
+               /* Pixel format can be only changed on the sink pad. */
+               mf->code = camif->mbus_fmt.code;
+               mf->width = crop->width;
+               mf->height = crop->height;
+               break;
+       }
+
+       mutex_unlock(&camif->lock);
+       return 0;
+}
+
+static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd,
+                                         struct v4l2_subdev_fh *fh,
+                                         struct v4l2_subdev_selection *sel)
+{
+       struct camif_dev *camif = v4l2_get_subdevdata(sd);
+       struct v4l2_rect *crop = &camif->camif_crop;
+       struct v4l2_mbus_framefmt *mf = &camif->mbus_fmt;
+
+       if ((sel->target != V4L2_SEL_TGT_CROP &&
+           sel->target != V4L2_SEL_TGT_CROP_BOUNDS) ||
+           sel->pad != CAMIF_SD_PAD_SINK)
+               return -EINVAL;
+
+       if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
+               sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
+               return 0;
+       }
+
+       mutex_lock(&camif->lock);
+
+       if (sel->target == V4L2_SEL_TGT_CROP) {
+               sel->r = *crop;
+       } else { /* crop bounds */
+               sel->r.width = mf->width;
+               sel->r.height = mf->height;
+               sel->r.left = 0;
+               sel->r.top = 0;
+       }
+
+       mutex_unlock(&camif->lock);
+
+       v4l2_dbg(1, debug, sd, "%s: crop: (%d,%d) %dx%d, size: %ux%u\n",
+                __func__, crop->left, crop->top, crop->width,
+                crop->height, mf->width, mf->height);
+
+       return 0;
+}
+
+static void __camif_try_crop(struct camif_dev *camif, struct v4l2_rect *r)
+{
+       struct v4l2_mbus_framefmt *mf = &camif->mbus_fmt;
+       const struct camif_pix_limits *pix_lim = &camif->variant->pix_limits;
+       unsigned int left = 2 * r->left;
+       unsigned int top = 2 * r->top;
+
+       /*
+        * Following constraints must be met:
+        *  - r->width + 2 * r->left = mf->width;
+        *  - r->height + 2 * r->top = mf->height;
+        *  - crop rectangle size and position must be aligned
+        *    to 8 or 2 pixels, depending on SoC version.
+        */
+       v4l_bound_align_image(&r->width, 0, mf->width,
+                             ffs(pix_lim->win_hor_offset_align) - 1,
+                             &r->height, 0, mf->height, 1, 0);
+
+       v4l_bound_align_image(&left, 0, mf->width - r->width,
+                             ffs(pix_lim->win_hor_offset_align),
+                             &top, 0, mf->height - r->height, 2, 0);
+
+       r->left = left / 2;
+       r->top = top / 2;
+       r->width = mf->width - left;
+       r->height = mf->height - top;
+       /*
+        * Make sure we either downscale or upscale both the pixel
+        * width and height. Just return current crop rectangle if
+        * this scaler constraint is not met.
+        */
+       if (camif->variant->ip_revision == S3C244X_CAMIF_IP_REV &&
+           camif_is_streaming(camif)) {
+               unsigned int i;
+
+               for (i = 0; i < CAMIF_VP_NUM; i++) {
+                       struct v4l2_rect *or = &camif->vp[i].out_frame.rect;
+                       if ((or->width > r->width) == (or->height > r->height))
+                               continue;
+                       *r = camif->camif_crop;
+                       pr_debug("Width/height scaling direction limitation\n");
+                       break;
+               }
+       }
+
+       v4l2_dbg(1, debug, &camif->v4l2_dev, "crop: (%d,%d)/%dx%d, fmt: %ux%u\n",
+                r->left, r->top, r->width, r->height, mf->width, mf->height);
+}
+
+static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd,
+                                         struct v4l2_subdev_fh *fh,
+                                         struct v4l2_subdev_selection *sel)
+{
+       struct camif_dev *camif = v4l2_get_subdevdata(sd);
+       struct v4l2_rect *crop = &camif->camif_crop;
+       struct camif_scaler scaler;
+
+       if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != CAMIF_SD_PAD_SINK)
+               return -EINVAL;
+
+       mutex_lock(&camif->lock);
+       __camif_try_crop(camif, &sel->r);
+
+       if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
+               *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r;
+       } else {
+               unsigned long flags;
+               unsigned int i;
+
+               spin_lock_irqsave(&camif->slock, flags);
+               *crop = sel->r;
+
+               for (i = 0; i < CAMIF_VP_NUM; i++) {
+                       struct camif_vp *vp = &camif->vp[i];
+                       scaler = vp->scaler;
+                       if (s3c_camif_get_scaler_config(vp, &scaler))
+                               continue;
+                       vp->scaler = scaler;
+                       vp->state |= ST_VP_CONFIG;
+               }
+
+               spin_unlock_irqrestore(&camif->slock, flags);
+       }
+       mutex_unlock(&camif->lock);
+
+       v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %u, f_h: %u\n",
+                __func__, crop->left, crop->top, crop->width, crop->height,
+                camif->mbus_fmt.width, camif->mbus_fmt.height);
+
+       return 0;
+}
+
+static const struct v4l2_subdev_pad_ops s3c_camif_subdev_pad_ops = {
+       .enum_mbus_code = s3c_camif_subdev_enum_mbus_code,
+       .get_selection = s3c_camif_subdev_get_selection,
+       .set_selection = s3c_camif_subdev_set_selection,
+       .get_fmt = s3c_camif_subdev_get_fmt,
+       .set_fmt = s3c_camif_subdev_set_fmt,
+};
+
+static struct v4l2_subdev_ops s3c_camif_subdev_ops = {
+       .pad = &s3c_camif_subdev_pad_ops,
+};
+
+static int s3c_camif_subdev_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct camif_dev *camif = container_of(ctrl->handler, struct camif_dev,
+                                              ctrl_handler);
+       unsigned long flags;
+
+       spin_lock_irqsave(&camif->slock, flags);
+
+       switch (ctrl->id) {
+       case V4L2_CID_COLORFX:
+               camif->colorfx = camif->ctrl_colorfx->val;
+               /* Set Cb, Cr */
+               switch (ctrl->val) {
+               case V4L2_COLORFX_SEPIA:
+                       camif->colorfx_cb = 115;
+                       camif->colorfx_cr = 145;
+                       break;
+               case V4L2_COLORFX_SET_CBCR:
+                       camif->colorfx_cb = camif->ctrl_colorfx_cbcr->val >> 8;
+                       camif->colorfx_cr = camif->ctrl_colorfx_cbcr->val & 0xff;
+                       break;
+               default:
+                       /* for V4L2_COLORFX_BW and others */
+                       camif->colorfx_cb = 128;
+                       camif->colorfx_cr = 128;
+               }
+               break;
+       case V4L2_CID_TEST_PATTERN:
+               camif->test_pattern = camif->ctrl_test_pattern->val;
+               break;
+       default:
+               WARN_ON(1);
+       }
+
+       camif->vp[VP_CODEC].state |= ST_VP_CONFIG;
+       camif->vp[VP_PREVIEW].state |= ST_VP_CONFIG;
+       spin_unlock_irqrestore(&camif->slock, flags);
+
+       return 0;
+}
+
+static const struct v4l2_ctrl_ops s3c_camif_subdev_ctrl_ops = {
+       .s_ctrl = s3c_camif_subdev_s_ctrl,
+};
+
+static const char * const s3c_camif_test_pattern_menu[] = {
+       "Disabled",
+       "Color bars",
+       "Horizontal increment",
+       "Vertical increment",
+};
+
+int s3c_camif_create_subdev(struct camif_dev *camif)
+{
+       struct v4l2_ctrl_handler *handler = &camif->ctrl_handler;
+       struct v4l2_subdev *sd = &camif->subdev;
+       int ret;
+
+       v4l2_subdev_init(sd, &s3c_camif_subdev_ops);
+       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+       strlcpy(sd->name, "S3C-CAMIF", sizeof(sd->name));
+
+       camif->pads[CAMIF_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+       camif->pads[CAMIF_SD_PAD_SOURCE_C].flags = MEDIA_PAD_FL_SOURCE;
+       camif->pads[CAMIF_SD_PAD_SOURCE_P].flags = MEDIA_PAD_FL_SOURCE;
+
+       ret = media_entity_init(&sd->entity, CAMIF_SD_PADS_NUM,
+                               camif->pads, 0);
+       if (ret)
+               return ret;
+
+       v4l2_ctrl_handler_init(handler, 3);
+       camif->ctrl_test_pattern = v4l2_ctrl_new_std_menu_items(handler,
+                       &s3c_camif_subdev_ctrl_ops, V4L2_CID_TEST_PATTERN,
+                       ARRAY_SIZE(s3c_camif_test_pattern_menu) - 1, 0, 0,
+                       s3c_camif_test_pattern_menu);
+
+       camif->ctrl_colorfx = v4l2_ctrl_new_std_menu(handler,
+                               &s3c_camif_subdev_ctrl_ops,
+                               V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR,
+                               ~0x981f, V4L2_COLORFX_NONE);
+
+       camif->ctrl_colorfx_cbcr = v4l2_ctrl_new_std(handler,
+                               &s3c_camif_subdev_ctrl_ops,
+                               V4L2_CID_COLORFX_CBCR, 0, 0xffff, 1, 0);
+       if (handler->error) {
+               v4l2_ctrl_handler_free(handler);
+               media_entity_cleanup(&sd->entity);
+               return handler->error;
+       }
+
+       v4l2_ctrl_auto_cluster(2, &camif->ctrl_colorfx,
+                              V4L2_COLORFX_SET_CBCR, false);
+       if (!camif->variant->has_img_effect) {
+               camif->ctrl_colorfx->flags |= V4L2_CTRL_FLAG_DISABLED;
+               camif->ctrl_colorfx_cbcr->flags |= V4L2_CTRL_FLAG_DISABLED;
+       }
+       sd->ctrl_handler = handler;
+       v4l2_set_subdevdata(sd, camif);
+
+       return 0;
+}
+
+void s3c_camif_unregister_subdev(struct camif_dev *camif)
+{
+       struct v4l2_subdev *sd = &camif->subdev;
+
+       /* Return if not registered */
+       if (v4l2_get_subdevdata(sd) == NULL)
+               return;
+
+       v4l2_device_unregister_subdev(sd);
+       media_entity_cleanup(&sd->entity);
+       v4l2_ctrl_handler_free(&camif->ctrl_handler);
+       v4l2_set_subdevdata(sd, NULL);
+}
+
+int s3c_camif_set_defaults(struct camif_dev *camif)
+{
+       unsigned int ip_rev = camif->variant->ip_revision;
+       int i;
+
+       for (i = 0; i < CAMIF_VP_NUM; i++) {
+               struct camif_vp *vp = &camif->vp[i];
+               struct camif_frame *f = &vp->out_frame;
+
+               vp->camif = camif;
+               vp->id = i;
+               vp->offset = camif->variant->vp_offset;
+
+               if (ip_rev == S3C244X_CAMIF_IP_REV)
+                       vp->fmt_flags = i ? FMT_FL_S3C24XX_PREVIEW :
+                                       FMT_FL_S3C24XX_CODEC;
+               else
+                       vp->fmt_flags = FMT_FL_S3C64XX;
+
+               vp->out_fmt = s3c_camif_find_format(vp, NULL, 0);
+               BUG_ON(vp->out_fmt == NULL);
+
+               memset(f, 0, sizeof(*f));
+               f->f_width = CAMIF_DEF_WIDTH;
+               f->f_height = CAMIF_DEF_HEIGHT;
+               f->rect.width = CAMIF_DEF_WIDTH;
+               f->rect.height = CAMIF_DEF_HEIGHT;
+
+               /* Scaler is always enabled */
+               vp->scaler.enable = 1;
+
+               vp->payload = (f->f_width * f->f_height *
+                              vp->out_fmt->depth) / 8;
+       }
+
+       memset(&camif->mbus_fmt, 0, sizeof(camif->mbus_fmt));
+       camif->mbus_fmt.width = CAMIF_DEF_WIDTH;
+       camif->mbus_fmt.height = CAMIF_DEF_HEIGHT;
+       camif->mbus_fmt.code  = camif_mbus_formats[0];
+
+       memset(&camif->camif_crop, 0, sizeof(camif->camif_crop));
+       camif->camif_crop.width = CAMIF_DEF_WIDTH;
+       camif->camif_crop.height = CAMIF_DEF_HEIGHT;
+
+       return 0;
+}
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
new file mode 100644 (file)
index 0000000..0dd6537
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ * s3c24xx/s3c64xx SoC series Camera Interface (CAMIF) driver
+ *
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ * Copyright (C) 2012 Tomasz Figa <tomasz.figa@gmail.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.
+ */
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/bug.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <media/media-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "camif-core.h"
+
+static char *camif_clocks[CLK_MAX_NUM] = {
+       /* HCLK CAMIF clock */
+       [CLK_GATE]      = "camif",
+       /* CAMIF / external camera sensor master clock */
+       [CLK_CAM]       = "camera",
+};
+
+static const struct camif_fmt camif_formats[] = {
+       {
+               .name           = "YUV 4:2:2 planar, Y/Cb/Cr",
+               .fourcc         = V4L2_PIX_FMT_YUV422P,
+               .depth          = 16,
+               .ybpp           = 1,
+               .color          = IMG_FMT_YCBCR422P,
+               .colplanes      = 3,
+               .flags          = FMT_FL_S3C24XX_CODEC |
+                                 FMT_FL_S3C64XX,
+       }, {
+               .name           = "YUV 4:2:0 planar, Y/Cb/Cr",
+               .fourcc         = V4L2_PIX_FMT_YUV420,
+               .depth          = 12,
+               .ybpp           = 1,
+               .color          = IMG_FMT_YCBCR420,
+               .colplanes      = 3,
+               .flags          = FMT_FL_S3C24XX_CODEC |
+                                 FMT_FL_S3C64XX,
+       }, {
+               .name           = "YVU 4:2:0 planar, Y/Cr/Cb",
+               .fourcc         = V4L2_PIX_FMT_YVU420,
+               .depth          = 12,
+               .ybpp           = 1,
+               .color          = IMG_FMT_YCRCB420,
+               .colplanes      = 3,
+               .flags          = FMT_FL_S3C24XX_CODEC |
+                                 FMT_FL_S3C64XX,
+       }, {
+               .name           = "RGB565, 16 bpp",
+               .fourcc         = V4L2_PIX_FMT_RGB565X,
+               .depth          = 16,
+               .ybpp           = 2,
+               .color          = IMG_FMT_RGB565,
+               .colplanes      = 1,
+               .flags          = FMT_FL_S3C24XX_PREVIEW |
+                                 FMT_FL_S3C64XX,
+       }, {
+               .name           = "XRGB8888, 32 bpp",
+               .fourcc         = V4L2_PIX_FMT_RGB32,
+               .depth          = 32,
+               .ybpp           = 4,
+               .color          = IMG_FMT_XRGB8888,
+               .colplanes      = 1,
+               .flags          = FMT_FL_S3C24XX_PREVIEW |
+                                 FMT_FL_S3C64XX,
+       }, {
+               .name           = "BGR666",
+               .fourcc         = V4L2_PIX_FMT_BGR666,
+               .depth          = 32,
+               .ybpp           = 4,
+               .color          = IMG_FMT_RGB666,
+               .colplanes      = 1,
+               .flags          = FMT_FL_S3C64XX,
+       }
+};
+
+/**
+ * s3c_camif_find_format() - lookup camif color format by fourcc or an index
+ * @pixelformat: fourcc to match, ignored if null
+ * @index: index to the camif_formats array, ignored if negative
+ */
+const struct camif_fmt *s3c_camif_find_format(struct camif_vp *vp,
+                                             const u32 *pixelformat,
+                                             int index)
+{
+       const struct camif_fmt *fmt, *def_fmt = NULL;
+       unsigned int i;
+       int id = 0;
+
+       if (index >= (int)ARRAY_SIZE(camif_formats))
+               return NULL;
+
+       for (i = 0; i < ARRAY_SIZE(camif_formats); ++i) {
+               fmt = &camif_formats[i];
+               if (vp && !(vp->fmt_flags & fmt->flags))
+                       continue;
+               if (pixelformat && fmt->fourcc == *pixelformat)
+                       return fmt;
+               if (index == id)
+                       def_fmt = fmt;
+               id++;
+       }
+       return def_fmt;
+}
+
+static int camif_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
+{
+       unsigned int sh = 6;
+
+       if (src >= 64 * tar)
+               return -EINVAL;
+
+       while (sh--) {
+               unsigned int tmp = 1 << sh;
+               if (src >= tar * tmp) {
+                       *shift = sh, *ratio = tmp;
+                       return 0;
+               }
+       }
+       *shift = 0, *ratio = 1;
+       return 0;
+}
+
+int s3c_camif_get_scaler_config(struct camif_vp *vp,
+                               struct camif_scaler *scaler)
+{
+       struct v4l2_rect *camif_crop = &vp->camif->camif_crop;
+       int source_x = camif_crop->width;
+       int source_y = camif_crop->height;
+       int target_x = vp->out_frame.rect.width;
+       int target_y = vp->out_frame.rect.height;
+       int ret;
+
+       if (vp->rotation == 90 || vp->rotation == 270)
+               swap(target_x, target_y);
+
+       ret = camif_get_scaler_factor(source_x, target_x, &scaler->pre_h_ratio,
+                                     &scaler->h_shift);
+       if (ret < 0)
+               return ret;
+
+       ret = camif_get_scaler_factor(source_y, target_y, &scaler->pre_v_ratio,
+                                     &scaler->v_shift);
+       if (ret < 0)
+               return ret;
+
+       scaler->pre_dst_width = source_x / scaler->pre_h_ratio;
+       scaler->pre_dst_height = source_y / scaler->pre_v_ratio;
+
+       scaler->main_h_ratio = (source_x << 8) / (target_x << scaler->h_shift);
+       scaler->main_v_ratio = (source_y << 8) / (target_y << scaler->v_shift);
+
+       scaler->scaleup_h = (target_x >= source_x);
+       scaler->scaleup_v = (target_y >= source_y);
+
+       scaler->copy = 0;
+
+       pr_debug("H: ratio: %u, shift: %u. V: ratio: %u, shift: %u.\n",
+                scaler->pre_h_ratio, scaler->h_shift,
+                scaler->pre_v_ratio, scaler->v_shift);
+
+       pr_debug("Source: %dx%d, Target: %dx%d, scaleup_h/v: %d/%d\n",
+                source_x, source_y, target_x, target_y,
+                scaler->scaleup_h, scaler->scaleup_v);
+
+       return 0;
+}
+
+static int camif_register_sensor(struct camif_dev *camif)
+{
+       struct s3c_camif_sensor_info *sensor = &camif->pdata.sensor;
+       struct v4l2_device *v4l2_dev = &camif->v4l2_dev;
+       struct i2c_adapter *adapter;
+       struct v4l2_subdev_format format;
+       struct v4l2_subdev *sd;
+       int ret;
+
+       camif->sensor.sd = NULL;
+
+       if (sensor->i2c_board_info.addr == 0)
+               return -EINVAL;
+
+       adapter = i2c_get_adapter(sensor->i2c_bus_num);
+       if (adapter == NULL) {
+               v4l2_warn(v4l2_dev, "failed to get I2C adapter %d\n",
+                         sensor->i2c_bus_num);
+               return -EPROBE_DEFER;
+       }
+
+       sd = v4l2_i2c_new_subdev_board(v4l2_dev, adapter,
+                                      &sensor->i2c_board_info, NULL);
+       if (sd == NULL) {
+               i2c_put_adapter(adapter);
+               v4l2_warn(v4l2_dev, "failed to acquire subdev %s\n",
+                         sensor->i2c_board_info.type);
+               return -EPROBE_DEFER;
+       }
+       camif->sensor.sd = sd;
+
+       v4l2_info(v4l2_dev, "registered sensor subdevice %s\n", sd->name);
+
+       /* Get initial pixel format and set it at the camif sink pad */
+       format.pad = 0;
+       format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+       ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &format);
+
+       if (ret < 0)
+               return 0;
+
+       format.pad = CAMIF_SD_PAD_SINK;
+       v4l2_subdev_call(&camif->subdev, pad, set_fmt, NULL, &format);
+
+       v4l2_info(sd, "Initial format from sensor: %dx%d, %#x\n",
+                 format.format.width, format.format.height,
+                 format.format.code);
+       return 0;
+}
+
+static void camif_unregister_sensor(struct camif_dev *camif)
+{
+       struct v4l2_subdev *sd = camif->sensor.sd;
+       struct i2c_client *client = sd ? v4l2_get_subdevdata(sd) : NULL;
+       struct i2c_adapter *adapter;
+
+       if (client == NULL)
+               return;
+
+       adapter = client->adapter;
+       v4l2_device_unregister_subdev(sd);
+       camif->sensor.sd = NULL;
+       i2c_unregister_device(client);
+       if (adapter)
+               i2c_put_adapter(adapter);
+}
+
+static int camif_create_media_links(struct camif_dev *camif)
+{
+       int i, ret;
+
+       ret = media_entity_create_link(&camif->sensor.sd->entity, 0,
+                               &camif->subdev.entity, CAMIF_SD_PAD_SINK,
+                               MEDIA_LNK_FL_IMMUTABLE |
+                               MEDIA_LNK_FL_ENABLED);
+       if (ret)
+               return ret;
+
+       for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) {
+               ret = media_entity_create_link(&camif->subdev.entity, i,
+                               &camif->vp[i - 1].vdev.entity, 0,
+                               MEDIA_LNK_FL_IMMUTABLE |
+                               MEDIA_LNK_FL_ENABLED);
+       }
+
+       return ret;
+}
+
+static int camif_register_video_nodes(struct camif_dev *camif)
+{
+       int ret = s3c_camif_register_video_node(camif, VP_CODEC);
+       if (ret < 0)
+               return ret;
+
+       return s3c_camif_register_video_node(camif, VP_PREVIEW);
+}
+
+static void camif_unregister_video_nodes(struct camif_dev *camif)
+{
+       s3c_camif_unregister_video_node(camif, VP_CODEC);
+       s3c_camif_unregister_video_node(camif, VP_PREVIEW);
+}
+
+static void camif_unregister_media_entities(struct camif_dev *camif)
+{
+       camif_unregister_video_nodes(camif);
+       camif_unregister_sensor(camif);
+       s3c_camif_unregister_subdev(camif);
+}
+
+/*
+ * Media device
+ */
+static int camif_media_dev_register(struct camif_dev *camif)
+{
+       struct media_device *md = &camif->media_dev;
+       struct v4l2_device *v4l2_dev = &camif->v4l2_dev;
+       unsigned int ip_rev = camif->variant->ip_revision;
+       int ret;
+
+       memset(md, 0, sizeof(*md));
+       snprintf(md->model, sizeof(md->model), "SAMSUNG S3C%s CAMIF",
+                ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X");
+       strlcpy(md->bus_info, "platform", sizeof(md->bus_info));
+       md->hw_revision = ip_rev;
+       md->driver_version = KERNEL_VERSION(1, 0, 0);
+
+       md->dev = camif->dev;
+
+       strlcpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name));
+       v4l2_dev->mdev = md;
+
+       ret = v4l2_device_register(camif->dev, v4l2_dev);
+       if (ret < 0)
+               return ret;
+
+       ret = media_device_register(md);
+       if (ret < 0)
+               v4l2_device_unregister(v4l2_dev);
+
+       return ret;
+}
+
+static void camif_clk_put(struct camif_dev *camif)
+{
+       int i;
+
+       for (i = 0; i < CLK_MAX_NUM; i++) {
+               if (IS_ERR_OR_NULL(camif->clock[i]))
+                       continue;
+               clk_unprepare(camif->clock[i]);
+               clk_put(camif->clock[i]);
+       }
+}
+
+static int camif_clk_get(struct camif_dev *camif)
+{
+       int ret, i;
+
+       for (i = 0; i < CLK_MAX_NUM; i++) {
+               camif->clock[i] = clk_get(camif->dev, camif_clocks[i]);
+               if (IS_ERR(camif->clock[i])) {
+                       ret = PTR_ERR(camif->clock[i]);
+                       goto err;
+               }
+               ret = clk_prepare(camif->clock[i]);
+               if (ret < 0) {
+                       clk_put(camif->clock[i]);
+                       camif->clock[i] = NULL;
+                       goto err;
+               }
+       }
+       return 0;
+err:
+       camif_clk_put(camif);
+       dev_err(camif->dev, "failed to get clock: %s\n",
+               camif_clocks[i]);
+       return ret;
+}
+
+/*
+ * The CAMIF device has two relatively independent data processing paths
+ * that can source data from memory or the common camera input frontend.
+ * Register interrupts for each data processing path (camif_vp).
+ */
+static int camif_request_irqs(struct platform_device *pdev,
+                             struct camif_dev *camif)
+{
+       int irq, ret, i;
+
+       for (i = 0; i < CAMIF_VP_NUM; i++) {
+               struct camif_vp *vp = &camif->vp[i];
+
+               init_waitqueue_head(&vp->irq_queue);
+
+               irq = platform_get_irq(pdev, i);
+               if (irq <= 0) {
+                       dev_err(&pdev->dev, "failed to get IRQ %d\n", i);
+                       return -ENXIO;
+               }
+
+               ret = devm_request_irq(&pdev->dev, irq, s3c_camif_irq_handler,
+                                      0, dev_name(&pdev->dev), vp);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "failed to install IRQ: %d\n", ret);
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+static int s3c_camif_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct s3c_camif_plat_data *pdata = dev->platform_data;
+       struct s3c_camif_drvdata *drvdata;
+       struct camif_dev *camif;
+       struct resource *mres;
+       int ret = 0;
+
+       camif = devm_kzalloc(dev, sizeof(*camif), GFP_KERNEL);
+       if (!camif)
+               return -ENOMEM;
+
+       spin_lock_init(&camif->slock);
+       mutex_init(&camif->lock);
+
+       camif->dev = dev;
+
+       if (!pdata || !pdata->gpio_get || !pdata->gpio_put) {
+               dev_err(dev, "wrong platform data\n");
+               return -EINVAL;
+       }
+
+       camif->pdata = *pdata;
+       drvdata = (void *)platform_get_device_id(pdev)->driver_data;
+       camif->variant = drvdata->variant;
+
+       mres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       camif->io_base = devm_request_and_ioremap(dev, mres);
+       if (!camif->io_base) {
+               dev_err(dev, "failed to obtain I/O memory\n");
+               return -ENOENT;
+       }
+
+       ret = camif_request_irqs(pdev, camif);
+       if (ret < 0)
+               return ret;
+
+       ret = pdata->gpio_get();
+       if (ret < 0)
+               return ret;
+
+       ret = s3c_camif_create_subdev(camif);
+       if (ret < 0)
+               goto err_sd;
+
+       ret = camif_clk_get(camif);
+       if (ret < 0)
+               goto err_clk;
+
+       platform_set_drvdata(pdev, camif);
+       clk_set_rate(camif->clock[CLK_CAM],
+                       camif->pdata.sensor.clock_frequency);
+
+       dev_info(dev, "sensor clock frequency: %lu\n",
+                clk_get_rate(camif->clock[CLK_CAM]));
+       /*
+        * Set initial pixel format, resolution and crop rectangle.
+        * Must be done before a sensor subdev is registered as some
+        * settings are overrode with values from sensor subdev.
+        */
+       s3c_camif_set_defaults(camif);
+
+       pm_runtime_enable(dev);
+
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
+               goto err_pm;
+
+       /* Initialize contiguous memory allocator */
+       camif->alloc_ctx = vb2_dma_contig_init_ctx(dev);
+       if (IS_ERR(camif->alloc_ctx)) {
+               ret = PTR_ERR(camif->alloc_ctx);
+               goto err_alloc;
+       }
+
+       ret = camif_media_dev_register(camif);
+       if (ret < 0)
+               goto err_mdev;
+
+       ret = camif_register_sensor(camif);
+       if (ret < 0)
+               goto err_sens;
+
+       ret = v4l2_device_register_subdev(&camif->v4l2_dev, &camif->subdev);
+       if (ret < 0)
+               goto err_sens;
+
+       mutex_lock(&camif->media_dev.graph_mutex);
+
+       ret = v4l2_device_register_subdev_nodes(&camif->v4l2_dev);
+       if (ret < 0)
+               goto err_unlock;
+
+       ret = camif_register_video_nodes(camif);
+       if (ret < 0)
+               goto err_unlock;
+
+       ret = camif_create_media_links(camif);
+       if (ret < 0)
+               goto err_unlock;
+
+       mutex_unlock(&camif->media_dev.graph_mutex);
+       pm_runtime_put(dev);
+       return 0;
+
+err_unlock:
+       mutex_unlock(&camif->media_dev.graph_mutex);
+err_sens:
+       v4l2_device_unregister(&camif->v4l2_dev);
+       media_device_unregister(&camif->media_dev);
+       camif_unregister_media_entities(camif);
+err_mdev:
+       vb2_dma_contig_cleanup_ctx(camif->alloc_ctx);
+err_alloc:
+       pm_runtime_put(dev);
+       pm_runtime_disable(dev);
+err_pm:
+       camif_clk_put(camif);
+err_clk:
+       s3c_camif_unregister_subdev(camif);
+err_sd:
+       pdata->gpio_put();
+       return ret;
+}
+
+static int __devexit s3c_camif_remove(struct platform_device *pdev)
+{
+       struct camif_dev *camif = platform_get_drvdata(pdev);
+       struct s3c_camif_plat_data *pdata = &camif->pdata;
+
+       media_device_unregister(&camif->media_dev);
+       camif_unregister_media_entities(camif);
+       v4l2_device_unregister(&camif->v4l2_dev);
+
+       pm_runtime_disable(&pdev->dev);
+       camif_clk_put(camif);
+       pdata->gpio_put();
+
+       return 0;
+}
+
+static int s3c_camif_runtime_resume(struct device *dev)
+{
+       struct camif_dev *camif = dev_get_drvdata(dev);
+
+       clk_enable(camif->clock[CLK_GATE]);
+       /* null op on s3c244x */
+       clk_enable(camif->clock[CLK_CAM]);
+       return 0;
+}
+
+static int s3c_camif_runtime_suspend(struct device *dev)
+{
+       struct camif_dev *camif = dev_get_drvdata(dev);
+
+       /* null op on s3c244x */
+       clk_disable(camif->clock[CLK_CAM]);
+
+       clk_disable(camif->clock[CLK_GATE]);
+       return 0;
+}
+
+static const struct s3c_camif_variant s3c244x_camif_variant = {
+       .vp_pix_limits = {
+               [VP_CODEC] = {
+                       .max_out_width          = 4096,
+                       .max_sc_out_width       = 2048,
+                       .out_width_align        = 16,
+                       .min_out_width          = 16,
+                       .max_height             = 4096,
+               },
+               [VP_PREVIEW] = {
+                       .max_out_width          = 640,
+                       .max_sc_out_width       = 640,
+                       .out_width_align        = 16,
+                       .min_out_width          = 16,
+                       .max_height             = 480,
+               }
+       },
+       .pix_limits = {
+               .win_hor_offset_align   = 8,
+       },
+       .ip_revision = S3C244X_CAMIF_IP_REV,
+};
+
+static struct s3c_camif_drvdata s3c244x_camif_drvdata = {
+       .variant        = &s3c244x_camif_variant,
+       .bus_clk_freq   = 24000000UL,
+};
+
+static const struct s3c_camif_variant s3c6410_camif_variant = {
+       .vp_pix_limits = {
+               [VP_CODEC] = {
+                       .max_out_width          = 4096,
+                       .max_sc_out_width       = 2048,
+                       .out_width_align        = 16,
+                       .min_out_width          = 16,
+                       .max_height             = 4096,
+               },
+               [VP_PREVIEW] = {
+                       .max_out_width          = 4096,
+                       .max_sc_out_width       = 720,
+                       .out_width_align        = 16,
+                       .min_out_width          = 16,
+                       .max_height             = 4096,
+               }
+       },
+       .pix_limits = {
+               .win_hor_offset_align   = 8,
+       },
+       .ip_revision = S3C6410_CAMIF_IP_REV,
+       .has_img_effect = 1,
+       .vp_offset = 0x20,
+};
+
+static struct s3c_camif_drvdata s3c6410_camif_drvdata = {
+       .variant        = &s3c6410_camif_variant,
+       .bus_clk_freq   = 133000000UL,
+};
+
+static struct platform_device_id s3c_camif_driver_ids[] = {
+       {
+               .name           = "s3c2440-camif",
+               .driver_data    = (unsigned long)&s3c244x_camif_drvdata,
+       }, {
+               .name           = "s3c6410-camif",
+               .driver_data    = (unsigned long)&s3c6410_camif_drvdata,
+       },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, s3c_camif_driver_ids);
+
+static const struct dev_pm_ops s3c_camif_pm_ops = {
+       .runtime_suspend        = s3c_camif_runtime_suspend,
+       .runtime_resume         = s3c_camif_runtime_resume,
+};
+
+static struct platform_driver s3c_camif_driver = {
+       .probe          = s3c_camif_probe,
+       .remove         = __devexit_p(s3c_camif_remove),
+       .id_table       = s3c_camif_driver_ids,
+       .driver = {
+               .name   = S3C_CAMIF_DRIVER_NAME,
+               .owner  = THIS_MODULE,
+               .pm     = &s3c_camif_pm_ops,
+       }
+};
+
+module_platform_driver(s3c_camif_driver);
+
+MODULE_AUTHOR("Sylwester Nawrocki <sylvester.nawrocki@gmail.com>");
+MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
+MODULE_DESCRIPTION("S3C24XX/S3C64XX SoC camera interface driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/s3c-camif/camif-core.h b/drivers/media/platform/s3c-camif/camif-core.h
new file mode 100644 (file)
index 0000000..261134b
--- /dev/null
@@ -0,0 +1,393 @@
+/*
+ * s3c24xx/s3c64xx SoC series Camera Interface (CAMIF) driver
+ *
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ * Copyright (C) 2012 Tomasz Figa <tomasz.figa@gmail.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 CAMIF_CORE_H_
+#define CAMIF_CORE_H_
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-mediabus.h>
+#include <media/videobuf2-core.h>
+#include <media/s3c_camif.h>
+
+#define S3C_CAMIF_DRIVER_NAME  "s3c-camif"
+#define CAMIF_REQ_BUFS_MIN     3
+#define CAMIF_MAX_OUT_BUFS     4
+#define CAMIF_MAX_PIX_WIDTH    4096
+#define CAMIF_MAX_PIX_HEIGHT   4096
+#define SCALER_MAX_RATIO       64
+#define CAMIF_DEF_WIDTH                640
+#define CAMIF_DEF_HEIGHT       480
+#define CAMIF_STOP_TIMEOUT     1500 /* ms */
+
+#define S3C244X_CAMIF_IP_REV   0x20 /* 2.0 */
+#define S3C2450_CAMIF_IP_REV   0x30 /* 3.0 - not implemented, not tested */
+#define S3C6400_CAMIF_IP_REV   0x31 /* 3.1 - not implemented, not tested */
+#define S3C6410_CAMIF_IP_REV   0x32 /* 3.2 */
+
+/* struct camif_vp::state */
+
+#define ST_VP_PENDING          (1 << 0)
+#define ST_VP_RUNNING          (1 << 1)
+#define ST_VP_STREAMING                (1 << 2)
+#define ST_VP_SENSOR_STREAMING (1 << 3)
+
+#define ST_VP_ABORTING         (1 << 4)
+#define ST_VP_OFF              (1 << 5)
+#define ST_VP_LASTIRQ          (1 << 6)
+
+#define ST_VP_CONFIG           (1 << 8)
+
+#define CAMIF_SD_PAD_SINK      0
+#define CAMIF_SD_PAD_SOURCE_C  1
+#define CAMIF_SD_PAD_SOURCE_P  2
+#define CAMIF_SD_PADS_NUM      3
+
+enum img_fmt {
+       IMG_FMT_RGB565 = 0x0010,
+       IMG_FMT_RGB666,
+       IMG_FMT_XRGB8888,
+       IMG_FMT_YCBCR420 = 0x0020,
+       IMG_FMT_YCRCB420,
+       IMG_FMT_YCBCR422P,
+       IMG_FMT_YCBYCR422 = 0x0040,
+       IMG_FMT_YCRYCB422,
+       IMG_FMT_CBYCRY422,
+       IMG_FMT_CRYCBY422,
+};
+
+#define img_fmt_is_rgb(x) ((x) & 0x10)
+#define img_fmt_is_ycbcr(x) ((x) & 0x60)
+
+/* Possible values for struct camif_fmt::flags */
+#define FMT_FL_S3C24XX_CODEC   (1 << 0)
+#define FMT_FL_S3C24XX_PREVIEW (1 << 1)
+#define FMT_FL_S3C64XX         (1 << 2)
+
+/**
+ * struct camif_fmt - pixel format description
+ * @fourcc:    fourcc code for this format, 0 if not applicable
+ * @color:     a corresponding enum img_fmt
+ * @colplanes: number of physically contiguous data planes
+ * @flags:     indicate for which SoCs revisions this format is valid
+ * @depth:     bits per pixel (total)
+ * @ybpp:      number of luminance bytes per pixel
+ */
+struct camif_fmt {
+       char *name;
+       u32 fourcc;
+       u32 color;
+       u16 colplanes;
+       u16 flags;
+       u8 depth;
+       u8 ybpp;
+};
+
+/**
+ * struct camif_dma_offset - pixel offset information for DMA
+ * @initial: offset (in pixels) to first pixel
+ * @line: offset (in pixels) from end of line to start of next line
+ */
+struct camif_dma_offset {
+       int     initial;
+       int     line;
+};
+
+/**
+ * struct camif_frame - source/target frame properties
+ * @f_width: full pixel width
+ * @f_height: full pixel height
+ * @rect: crop/composition rectangle
+ * @dma_offset: DMA offset configuration
+ */
+struct camif_frame {
+       u16 f_width;
+       u16 f_height;
+       struct v4l2_rect rect;
+       struct camif_dma_offset dma_offset;
+};
+
+/* CAMIF clocks enumeration */
+enum {
+       CLK_GATE,
+       CLK_CAM,
+       CLK_MAX_NUM,
+};
+
+struct vp_pix_limits {
+       u16 max_out_width;
+       u16 max_sc_out_width;
+       u16 out_width_align;
+       u16 max_height;
+       u8 min_out_width;
+       u16 out_hor_offset_align;
+};
+
+struct camif_pix_limits {
+       u16 win_hor_offset_align;
+};
+
+/**
+ * struct s3c_camif_variant - CAMIF variant structure
+ * @vp_pix_limits:    pixel limits for the codec and preview paths
+ * @camif_pix_limits: pixel limits for the camera input interface
+ * @ip_revision:      the CAMIF IP revision: 0x20 for s3c244x, 0x32 for s3c6410
+ */
+struct s3c_camif_variant {
+       struct vp_pix_limits vp_pix_limits[2];
+       struct camif_pix_limits pix_limits;
+       u8 ip_revision;
+       u8 has_img_effect;
+       unsigned int vp_offset;
+};
+
+struct s3c_camif_drvdata {
+       const struct s3c_camif_variant *variant;
+       unsigned long bus_clk_freq;
+};
+
+struct camif_scaler {
+       u8 scaleup_h;
+       u8 scaleup_v;
+       u8 copy;
+       u8 enable;
+       u32 h_shift;
+       u32 v_shift;
+       u32 pre_h_ratio;
+       u32 pre_v_ratio;
+       u32 pre_dst_width;
+       u32 pre_dst_height;
+       u32 main_h_ratio;
+       u32 main_v_ratio;
+};
+
+struct camif_dev;
+
+/**
+ * struct camif_vp - CAMIF data processing path structure (codec/preview)
+ * @irq_queue:     interrupt handling waitqueue
+ * @irq:           interrupt number for this data path
+ * @camif:         pointer to the camif structure
+ * @pad:           media pad for the video node
+ * @vdev            video device
+ * @ctrl_handler:   video node controls handler
+ * @owner:         file handle that own the streaming
+ * @pending_buf_q:  pending (empty) buffers queue head
+ * @active_buf_q:   active (being written) buffers queue head
+ * @active_buffers: counter of buffer set up at the DMA engine
+ * @buf_index:     identifier of a last empty buffer set up in H/W
+ * @frame_sequence: image frame sequence counter
+ * @reqbufs_count:  the number of buffers requested
+ * @scaler:        the scaler structure
+ * @out_fmt:       pixel format at this video path output
+ * @payload:       the output data frame payload size
+ * @out_frame:     the output pixel resolution
+ * @state:         the video path's state
+ * @fmt_flags:     flags determining supported pixel formats
+ * @id:                    CAMIF id, 0 - codec, 1 - preview
+ * @rotation:      current image rotation value
+ * @hflip:         apply horizontal flip if set
+ * @vflip:         apply vertical flip if set
+ */
+struct camif_vp {
+       wait_queue_head_t       irq_queue;
+       int                     irq;
+       struct camif_dev        *camif;
+       struct media_pad        pad;
+       struct video_device     vdev;
+       struct v4l2_ctrl_handler ctrl_handler;
+       struct v4l2_fh          *owner;
+       struct vb2_queue        vb_queue;
+       struct list_head        pending_buf_q;
+       struct list_head        active_buf_q;
+       unsigned int            active_buffers;
+       unsigned int            buf_index;
+       unsigned int            frame_sequence;
+       unsigned int            reqbufs_count;
+       struct camif_scaler     scaler;
+       const struct camif_fmt  *out_fmt;
+       unsigned int            payload;
+       struct camif_frame      out_frame;
+       unsigned int            state;
+       u16                     fmt_flags;
+       u8                      id;
+       u8                      rotation;
+       u8                      hflip;
+       u8                      vflip;
+       unsigned int            offset;
+};
+
+/* Video processing path enumeration */
+#define VP_CODEC       0
+#define VP_PREVIEW     1
+#define CAMIF_VP_NUM   2
+
+/**
+ * struct camif_dev - the CAMIF driver private data structure
+ * @media_dev:    top-level media device structure
+ * @v4l2_dev:    root v4l2_device
+ * @subdev:       camera interface ("catchcam") subdev
+ * @mbus_fmt:    camera input media bus format
+ * @camif_crop:   camera input interface crop rectangle
+ * @pads:        the camif subdev's media pads
+ * @stream_count: the camera interface streaming reference counter
+ * @sensor:       image sensor data structure
+ * @m_pipeline:          video entity pipeline description
+ * @ctrl_handler: v4l2 control handler (owned by @subdev)
+ * @test_pattern: test pattern controls
+ * @vp:           video path (DMA) description (codec/preview)
+ * @alloc_ctx:    memory buffer allocator context
+ * @variant:      variant information for this device
+ * @dev:         pointer to the CAMIF device struct
+ * @pdata:       a copy of the driver's platform data
+ * @clock:       clocks required for the CAMIF operation
+ * @lock:        mutex protecting this data structure
+ * @slock:       spinlock protecting CAMIF registers
+ * @io_base:     start address of the mmaped CAMIF registers
+ */
+struct camif_dev {
+       struct media_device             media_dev;
+       struct v4l2_device              v4l2_dev;
+       struct v4l2_subdev              subdev;
+       struct v4l2_mbus_framefmt       mbus_fmt;
+       struct v4l2_rect                camif_crop;
+       struct media_pad                pads[CAMIF_SD_PADS_NUM];
+       int                             stream_count;
+
+       struct cam_sensor {
+               struct v4l2_subdev      *sd;
+               short                   power_count;
+               short                   stream_count;
+       } sensor;
+       struct media_pipeline           *m_pipeline;
+
+       struct v4l2_ctrl_handler        ctrl_handler;
+       struct v4l2_ctrl                *ctrl_test_pattern;
+       struct {
+               struct v4l2_ctrl        *ctrl_colorfx;
+               struct v4l2_ctrl        *ctrl_colorfx_cbcr;
+       };
+       u8                              test_pattern;
+       u8                              colorfx;
+       u8                              colorfx_cb;
+       u8                              colorfx_cr;
+
+       struct camif_vp                 vp[CAMIF_VP_NUM];
+       struct vb2_alloc_ctx            *alloc_ctx;
+
+       const struct s3c_camif_variant  *variant;
+       struct device                   *dev;
+       struct s3c_camif_plat_data      pdata;
+       struct clk                      *clock[CLK_MAX_NUM];
+       struct mutex                    lock;
+       spinlock_t                      slock;
+       void __iomem                    *io_base;
+};
+
+/**
+ * struct camif_addr - Y/Cb/Cr DMA start address structure
+ * @y:  luminance plane dma address
+ * @cb:         Cb plane dma address
+ * @cr:         Cr plane dma address
+ */
+struct camif_addr {
+       dma_addr_t y;
+       dma_addr_t cb;
+       dma_addr_t cr;
+};
+
+/**
+ * struct camif_buffer - the camif video buffer structure
+ * @vb:    vb2 buffer
+ * @list:  list head for the buffers queue
+ * @paddr: DMA start addresses
+ * @index: an identifier of this buffer at the DMA engine
+ */
+struct camif_buffer {
+       struct vb2_buffer vb;
+       struct list_head list;
+       struct camif_addr paddr;
+       unsigned int index;
+};
+
+const struct camif_fmt *s3c_camif_find_format(struct camif_vp *vp,
+             const u32 *pixelformat, int index);
+int s3c_camif_register_video_node(struct camif_dev *camif, int idx);
+void s3c_camif_unregister_video_node(struct camif_dev *camif, int idx);
+irqreturn_t s3c_camif_irq_handler(int irq, void *priv);
+int s3c_camif_create_subdev(struct camif_dev *camif);
+void s3c_camif_unregister_subdev(struct camif_dev *camif);
+int s3c_camif_set_defaults(struct camif_dev *camif);
+int s3c_camif_get_scaler_config(struct camif_vp *vp,
+                               struct camif_scaler *scaler);
+
+static inline void camif_active_queue_add(struct camif_vp *vp,
+                                         struct camif_buffer *buf)
+{
+       list_add_tail(&buf->list, &vp->active_buf_q);
+       vp->active_buffers++;
+}
+
+static inline struct camif_buffer *camif_active_queue_pop(
+                                       struct camif_vp *vp)
+{
+       struct camif_buffer *buf = list_first_entry(&vp->active_buf_q,
+                                             struct camif_buffer, list);
+       list_del(&buf->list);
+       vp->active_buffers--;
+       return buf;
+}
+
+static inline struct camif_buffer *camif_active_queue_peek(
+                          struct camif_vp *vp, int index)
+{
+       struct camif_buffer *tmp, *buf;
+
+       if (WARN_ON(list_empty(&vp->active_buf_q)))
+               return NULL;
+
+       list_for_each_entry_safe(buf, tmp, &vp->active_buf_q, list) {
+               if (buf->index == index) {
+                       list_del(&buf->list);
+                       vp->active_buffers--;
+                       return buf;
+               }
+       }
+
+       return NULL;
+}
+
+static inline void camif_pending_queue_add(struct camif_vp *vp,
+                                          struct camif_buffer *buf)
+{
+       list_add_tail(&buf->list, &vp->pending_buf_q);
+}
+
+static inline struct camif_buffer *camif_pending_queue_pop(
+                                       struct camif_vp *vp)
+{
+       struct camif_buffer *buf = list_first_entry(&vp->pending_buf_q,
+                                             struct camif_buffer, list);
+       list_del(&buf->list);
+       return buf;
+}
+
+#endif /* CAMIF_CORE_H_ */
diff --git a/drivers/media/platform/s3c-camif/camif-regs.c b/drivers/media/platform/s3c-camif/camif-regs.c
new file mode 100644 (file)
index 0000000..1a3b4fc
--- /dev/null
@@ -0,0 +1,606 @@
+/*
+ * Samsung s3c24xx/s3c64xx SoC CAMIF driver
+ *
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ * Copyright (C) 2012 Tomasz Figa <tomasz.figa@gmail.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.
+*/
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/delay.h>
+#include "camif-regs.h"
+
+#define camif_write(_camif, _off, _val)        writel(_val, (_camif)->io_base + (_off))
+#define camif_read(_camif, _off)       readl((_camif)->io_base + (_off))
+
+void camif_hw_reset(struct camif_dev *camif)
+{
+       u32 cfg;
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CISRCFMT);
+       cfg |= CISRCFMT_ITU601_8BIT;
+       camif_write(camif, S3C_CAMIF_REG_CISRCFMT, cfg);
+
+       /* S/W reset */
+       cfg = camif_read(camif, S3C_CAMIF_REG_CIGCTRL);
+       cfg |= CIGCTRL_SWRST;
+       if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV)
+               cfg |= CIGCTRL_IRQ_LEVEL;
+       camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
+       udelay(10);
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CIGCTRL);
+       cfg &= ~CIGCTRL_SWRST;
+       camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
+       udelay(10);
+}
+
+void camif_hw_clear_pending_irq(struct camif_vp *vp)
+{
+       u32 cfg = camif_read(vp->camif, S3C_CAMIF_REG_CIGCTRL);
+       cfg |= CIGCTRL_IRQ_CLR(vp->id);
+       camif_write(vp->camif, S3C_CAMIF_REG_CIGCTRL, cfg);
+}
+
+/*
+ * Sets video test pattern (off, color bar, horizontal or vertical gradient).
+ * External sensor pixel clock must be active for the test pattern to work.
+ */
+void camif_hw_set_test_pattern(struct camif_dev *camif, unsigned int pattern)
+{
+       u32 cfg = camif_read(camif, S3C_CAMIF_REG_CIGCTRL);
+       cfg &= ~CIGCTRL_TESTPATTERN_MASK;
+       cfg |= (pattern << 27);
+       camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
+}
+
+void camif_hw_set_effect(struct camif_dev *camif, unsigned int effect,
+                       unsigned int cr, unsigned int cb)
+{
+       static const struct v4l2_control colorfx[] = {
+               { V4L2_COLORFX_NONE,            CIIMGEFF_FIN_BYPASS },
+               { V4L2_COLORFX_BW,              CIIMGEFF_FIN_ARBITRARY },
+               { V4L2_COLORFX_SEPIA,           CIIMGEFF_FIN_ARBITRARY },
+               { V4L2_COLORFX_NEGATIVE,        CIIMGEFF_FIN_NEGATIVE },
+               { V4L2_COLORFX_ART_FREEZE,      CIIMGEFF_FIN_ARTFREEZE },
+               { V4L2_COLORFX_EMBOSS,          CIIMGEFF_FIN_EMBOSSING },
+               { V4L2_COLORFX_SILHOUETTE,      CIIMGEFF_FIN_SILHOUETTE },
+               { V4L2_COLORFX_SET_CBCR,        CIIMGEFF_FIN_ARBITRARY },
+       };
+       unsigned int i, cfg;
+
+       for (i = 0; i < ARRAY_SIZE(colorfx); i++)
+               if (colorfx[i].id == effect)
+                       break;
+
+       if (i == ARRAY_SIZE(colorfx))
+               return;
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CIIMGEFF(camif->vp->offset));
+       /* Set effect */
+       cfg &= ~CIIMGEFF_FIN_MASK;
+       cfg |= colorfx[i].value;
+       /* Set both paths */
+       if (camif->variant->ip_revision >= S3C6400_CAMIF_IP_REV) {
+               if (effect == V4L2_COLORFX_NONE)
+                       cfg &= ~CIIMGEFF_IE_ENABLE_MASK;
+               else
+                       cfg |= CIIMGEFF_IE_ENABLE_MASK;
+       }
+       cfg &= ~CIIMGEFF_PAT_CBCR_MASK;
+       cfg |= cr | (cb << 13);
+       camif_write(camif, S3C_CAMIF_REG_CIIMGEFF(camif->vp->offset), cfg);
+}
+
+static const u32 src_pixfmt_map[8][2] = {
+       { V4L2_MBUS_FMT_YUYV8_2X8, CISRCFMT_ORDER422_YCBYCR },
+       { V4L2_MBUS_FMT_YVYU8_2X8, CISRCFMT_ORDER422_YCRYCB },
+       { V4L2_MBUS_FMT_UYVY8_2X8, CISRCFMT_ORDER422_CBYCRY },
+       { V4L2_MBUS_FMT_VYUY8_2X8, CISRCFMT_ORDER422_CRYCBY },
+};
+
+/* Set camera input pixel format and resolution */
+void camif_hw_set_source_format(struct camif_dev *camif)
+{
+       struct v4l2_mbus_framefmt *mf = &camif->mbus_fmt;
+       unsigned int i = ARRAY_SIZE(src_pixfmt_map);
+       u32 cfg;
+
+       while (i-- >= 0) {
+               if (src_pixfmt_map[i][0] == mf->code)
+                       break;
+       }
+
+       if (i == 0 && src_pixfmt_map[i][0] != mf->code) {
+               dev_err(camif->dev,
+                       "Unsupported pixel code, falling back to %#08x\n",
+                       src_pixfmt_map[i][0]);
+       }
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CISRCFMT);
+       cfg &= ~(CISRCFMT_ORDER422_MASK | CISRCFMT_SIZE_CAM_MASK);
+       cfg |= (mf->width << 16) | mf->height;
+       cfg |= src_pixfmt_map[i][1];
+       camif_write(camif, S3C_CAMIF_REG_CISRCFMT, cfg);
+}
+
+/* Set the camera host input window offsets (cropping) */
+void camif_hw_set_camera_crop(struct camif_dev *camif)
+{
+       struct v4l2_mbus_framefmt *mf = &camif->mbus_fmt;
+       struct v4l2_rect *crop = &camif->camif_crop;
+       u32 hoff2, voff2;
+       u32 cfg;
+
+       /* Note: s3c244x requirement: left = f_width - rect.width / 2 */
+       cfg = camif_read(camif, S3C_CAMIF_REG_CIWDOFST);
+       cfg &= ~(CIWDOFST_OFST_MASK | CIWDOFST_WINOFSEN);
+       cfg |= (crop->left << 16) | crop->top;
+       if (crop->left != 0 || crop->top != 0)
+               cfg |= CIWDOFST_WINOFSEN;
+       camif_write(camif, S3C_CAMIF_REG_CIWDOFST, cfg);
+
+       if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV) {
+               hoff2 = mf->width - crop->width - crop->left;
+               voff2 = mf->height - crop->height - crop->top;
+               cfg = (hoff2 << 16) | voff2;
+               camif_write(camif, S3C_CAMIF_REG_CIWDOFST2, cfg);
+       }
+}
+
+void camif_hw_clear_fifo_overflow(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       u32 cfg;
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CIWDOFST);
+       if (vp->id == 0)
+               cfg |= (CIWDOFST_CLROVCOFIY | CIWDOFST_CLROVCOFICB |
+                       CIWDOFST_CLROVCOFICR);
+       else
+               cfg |= (/* CIWDOFST_CLROVPRFIY | */ CIWDOFST_CLROVPRFICB |
+                       CIWDOFST_CLROVPRFICR);
+       camif_write(camif, S3C_CAMIF_REG_CIWDOFST, cfg);
+}
+
+/* Set video bus signals polarity */
+void camif_hw_set_camera_bus(struct camif_dev *camif)
+{
+       unsigned int flags = camif->pdata.sensor.flags;
+
+       u32 cfg = camif_read(camif, S3C_CAMIF_REG_CIGCTRL);
+
+       cfg &= ~(CIGCTRL_INVPOLPCLK | CIGCTRL_INVPOLVSYNC |
+                CIGCTRL_INVPOLHREF | CIGCTRL_INVPOLFIELD);
+
+       if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+               cfg |= CIGCTRL_INVPOLPCLK;
+
+       if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+               cfg |= CIGCTRL_INVPOLVSYNC;
+       /*
+        * HREF is normally high during frame active data
+        * transmission and low during horizontal synchronization
+        * period. Thus HREF active high means HSYNC active low.
+        */
+       if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+               cfg |= CIGCTRL_INVPOLHREF; /* HREF active low */
+
+       if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV) {
+               if (flags & V4L2_MBUS_FIELD_EVEN_LOW)
+                       cfg |= CIGCTRL_INVPOLFIELD;
+               cfg |= CIGCTRL_FIELDMODE;
+       }
+
+       pr_debug("Setting CIGCTRL to: %#x\n", cfg);
+
+       camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
+}
+
+void camif_hw_set_output_addr(struct camif_vp *vp,
+                             struct camif_addr *paddr, int i)
+{
+       struct camif_dev *camif = vp->camif;
+
+       camif_write(camif, S3C_CAMIF_REG_CIYSA(vp->id, i), paddr->y);
+       if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV
+               || vp->id == VP_CODEC) {
+               camif_write(camif, S3C_CAMIF_REG_CICBSA(vp->id, i),
+                                                               paddr->cb);
+               camif_write(camif, S3C_CAMIF_REG_CICRSA(vp->id, i),
+                                                               paddr->cr);
+       }
+
+       pr_debug("dst_buf[%d]: %#X, cb: %#X, cr: %#X\n",
+                i, paddr->y, paddr->cb, paddr->cr);
+}
+
+static void camif_hw_set_out_dma_size(struct camif_vp *vp)
+{
+       struct camif_frame *frame = &vp->out_frame;
+       u32 cfg;
+
+       cfg = camif_read(vp->camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset));
+       cfg &= ~CITRGFMT_TARGETSIZE_MASK;
+       cfg |= (frame->f_width << 16) | frame->f_height;
+       camif_write(vp->camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset), cfg);
+}
+
+static void camif_get_dma_burst(u32 width, u32 ybpp, u32 *mburst, u32 *rburst)
+{
+       unsigned int nwords = width * ybpp / 4;
+       unsigned int div, rem;
+
+       if (WARN_ON(width < 8 || (width * ybpp) & 7))
+               return;
+
+       for (div = 16; div >= 2; div /= 2) {
+               if (nwords < div)
+                       continue;
+
+               rem = nwords & (div - 1);
+               if (rem == 0) {
+                       *mburst = div;
+                       *rburst = div;
+                       break;
+               }
+               if (rem == div / 2 || rem == div / 4) {
+                       *mburst = div;
+                       *rburst = rem;
+                       break;
+               }
+       }
+}
+
+void camif_hw_set_output_dma(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       struct camif_frame *frame = &vp->out_frame;
+       const struct camif_fmt *fmt = vp->out_fmt;
+       unsigned int ymburst = 0, yrburst = 0;
+       u32 cfg;
+
+       camif_hw_set_out_dma_size(vp);
+
+       if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV) {
+               struct camif_dma_offset *offset = &frame->dma_offset;
+               /* Set the input dma offsets. */
+               cfg = S3C_CISS_OFFS_INITIAL(offset->initial);
+               cfg |= S3C_CISS_OFFS_LINE(offset->line);
+               camif_write(camif, S3C_CAMIF_REG_CISSY(vp->id), cfg);
+               camif_write(camif, S3C_CAMIF_REG_CISSCB(vp->id), cfg);
+               camif_write(camif, S3C_CAMIF_REG_CISSCR(vp->id), cfg);
+       }
+
+       /* Configure DMA burst values */
+       camif_get_dma_burst(frame->rect.width, fmt->ybpp, &ymburst, &yrburst);
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CICTRL(vp->id, vp->offset));
+       cfg &= ~CICTRL_BURST_MASK;
+
+       cfg |= CICTRL_YBURST1(ymburst) | CICTRL_YBURST2(yrburst);
+       cfg |= CICTRL_CBURST1(ymburst / 2) | CICTRL_CBURST2(yrburst / 2);
+
+       camif_write(camif, S3C_CAMIF_REG_CICTRL(vp->id, vp->offset), cfg);
+
+       pr_debug("ymburst: %u, yrburst: %u\n", ymburst, yrburst);
+}
+
+void camif_hw_set_input_path(struct camif_vp *vp)
+{
+       u32 cfg = camif_read(vp->camif, S3C_CAMIF_REG_MSCTRL(vp->id));
+       cfg &= ~MSCTRL_SEL_DMA_CAM;
+       camif_write(vp->camif, S3C_CAMIF_REG_MSCTRL(vp->id), cfg);
+}
+
+void camif_hw_set_target_format(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       struct camif_frame *frame = &vp->out_frame;
+       u32 cfg;
+
+       pr_debug("fw: %d, fh: %d color: %d\n", frame->f_width,
+                frame->f_height, vp->out_fmt->color);
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset));
+       cfg &= ~CITRGFMT_TARGETSIZE_MASK;
+
+       if (camif->variant->ip_revision == S3C244X_CAMIF_IP_REV) {
+               /* We currently support only YCbCr 4:2:2 at the camera input */
+               cfg |= CITRGFMT_IN422;
+               cfg &= ~CITRGFMT_OUT422;
+               if (vp->out_fmt->color == IMG_FMT_YCBCR422P)
+                       cfg |= CITRGFMT_OUT422;
+       } else {
+               cfg &= ~CITRGFMT_OUTFORMAT_MASK;
+               switch (vp->out_fmt->color) {
+               case IMG_FMT_RGB565...IMG_FMT_XRGB8888:
+                       cfg |= CITRGFMT_OUTFORMAT_RGB;
+                       break;
+               case IMG_FMT_YCBCR420...IMG_FMT_YCRCB420:
+                       cfg |= CITRGFMT_OUTFORMAT_YCBCR420;
+                       break;
+               case IMG_FMT_YCBCR422P:
+                       cfg |= CITRGFMT_OUTFORMAT_YCBCR422;
+                       break;
+               case IMG_FMT_YCBYCR422...IMG_FMT_CRYCBY422:
+                       cfg |= CITRGFMT_OUTFORMAT_YCBCR422I;
+                       break;
+               }
+       }
+
+       /* Rotation is only supported by s3c64xx */
+       if (vp->rotation == 90 || vp->rotation == 270)
+               cfg |= (frame->f_height << 16) | frame->f_width;
+       else
+               cfg |= (frame->f_width << 16) | frame->f_height;
+       camif_write(camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset), cfg);
+
+       /* Target area, output pixel width * height */
+       cfg = camif_read(camif, S3C_CAMIF_REG_CITAREA(vp->id, vp->offset));
+       cfg &= ~CITAREA_MASK;
+       cfg |= (frame->f_width * frame->f_height);
+       camif_write(camif, S3C_CAMIF_REG_CITAREA(vp->id, vp->offset), cfg);
+}
+
+void camif_hw_set_flip(struct camif_vp *vp)
+{
+       u32 cfg = camif_read(vp->camif,
+                               S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset));
+
+       cfg &= ~CITRGFMT_FLIP_MASK;
+
+       if (vp->hflip)
+               cfg |= CITRGFMT_FLIP_Y_MIRROR;
+       if (vp->vflip)
+               cfg |= CITRGFMT_FLIP_X_MIRROR;
+
+       camif_write(vp->camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset), cfg);
+}
+
+static void camif_hw_set_prescaler(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       struct camif_scaler *sc = &vp->scaler;
+       u32 cfg, shfactor, addr;
+
+       addr = S3C_CAMIF_REG_CISCPRERATIO(vp->id, vp->offset);
+
+       shfactor = 10 - (sc->h_shift + sc->v_shift);
+       cfg = shfactor << 28;
+
+       cfg |= (sc->pre_h_ratio << 16) | sc->pre_v_ratio;
+       camif_write(camif, addr, cfg);
+
+       cfg = (sc->pre_dst_width << 16) | sc->pre_dst_height;
+       camif_write(camif, S3C_CAMIF_REG_CISCPREDST(vp->id, vp->offset), cfg);
+}
+
+void camif_s3c244x_hw_set_scaler(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       struct camif_scaler *scaler = &vp->scaler;
+       unsigned int color = vp->out_fmt->color;
+       u32 cfg;
+
+       camif_hw_set_prescaler(vp);
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset));
+
+       cfg &= ~(CISCCTRL_SCALEUP_MASK | CISCCTRL_SCALERBYPASS |
+                CISCCTRL_MAIN_RATIO_MASK | CIPRSCCTRL_RGB_FORMAT_24BIT);
+
+       if (scaler->enable) {
+               if (scaler->scaleup_h) {
+                       if (vp->id == VP_CODEC)
+                               cfg |= CISCCTRL_SCALEUP_H;
+                       else
+                               cfg |= CIPRSCCTRL_SCALEUP_H;
+               }
+               if (scaler->scaleup_v) {
+                       if (vp->id == VP_CODEC)
+                               cfg |= CISCCTRL_SCALEUP_V;
+                       else
+                               cfg |= CIPRSCCTRL_SCALEUP_V;
+               }
+       } else {
+               if (vp->id == VP_CODEC)
+                       cfg |= CISCCTRL_SCALERBYPASS;
+       }
+
+       cfg |= ((scaler->main_h_ratio & 0x1ff) << 16);
+       cfg |= scaler->main_v_ratio & 0x1ff;
+
+       if (vp->id == VP_PREVIEW) {
+               if (color == IMG_FMT_XRGB8888)
+                       cfg |= CIPRSCCTRL_RGB_FORMAT_24BIT;
+               cfg |= CIPRSCCTRL_SAMPLE;
+       }
+
+       camif_write(camif, S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset), cfg);
+
+       pr_debug("main: h_ratio: %#x, v_ratio: %#x",
+                scaler->main_h_ratio, scaler->main_v_ratio);
+}
+
+void camif_s3c64xx_hw_set_scaler(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       struct camif_scaler *scaler = &vp->scaler;
+       unsigned int color = vp->out_fmt->color;
+       u32 cfg;
+
+       camif_hw_set_prescaler(vp);
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset));
+
+       cfg &= ~(CISCCTRL_CSCR2Y_WIDE | CISCCTRL_CSCY2R_WIDE
+               | CISCCTRL_SCALEUP_H | CISCCTRL_SCALEUP_V
+               | CISCCTRL_SCALERBYPASS | CISCCTRL_ONE2ONE
+               | CISCCTRL_INRGB_FMT_MASK | CISCCTRL_OUTRGB_FMT_MASK
+               | CISCCTRL_INTERLACE | CISCCTRL_EXTRGB_EXTENSION
+               | CISCCTRL_MAIN_RATIO_MASK);
+
+       cfg |= (CISCCTRL_CSCR2Y_WIDE | CISCCTRL_CSCY2R_WIDE);
+
+       if (!scaler->enable) {
+               cfg |= CISCCTRL_SCALERBYPASS;
+       } else {
+               if (scaler->scaleup_h)
+                       cfg |= CISCCTRL_SCALEUP_H;
+               if (scaler->scaleup_v)
+                       cfg |= CISCCTRL_SCALEUP_V;
+               if (scaler->copy)
+                       cfg |= CISCCTRL_ONE2ONE;
+       }
+
+       switch (color) {
+       case IMG_FMT_RGB666:
+               cfg |= CISCCTRL_OUTRGB_FMT_RGB666;
+               break;
+       case IMG_FMT_XRGB8888:
+               cfg |= CISCCTRL_OUTRGB_FMT_RGB888;
+               break;
+       }
+
+       cfg |= (scaler->main_h_ratio & 0x1ff) << 16;
+       cfg |= scaler->main_v_ratio & 0x1ff;
+
+       camif_write(camif, S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset), cfg);
+
+       pr_debug("main: h_ratio: %#x, v_ratio: %#x",
+                scaler->main_h_ratio, scaler->main_v_ratio);
+}
+
+void camif_hw_set_scaler(struct camif_vp *vp)
+{
+       unsigned int ip_rev = vp->camif->variant->ip_revision;
+
+       if (ip_rev == S3C244X_CAMIF_IP_REV)
+               camif_s3c244x_hw_set_scaler(vp);
+       else
+               camif_s3c64xx_hw_set_scaler(vp);
+}
+
+void camif_hw_enable_scaler(struct camif_vp *vp, bool on)
+{
+       u32 addr = S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset);
+       u32 cfg;
+
+       cfg = camif_read(vp->camif, addr);
+       if (on)
+               cfg |= CISCCTRL_SCALERSTART;
+       else
+               cfg &= ~CISCCTRL_SCALERSTART;
+       camif_write(vp->camif, addr, cfg);
+}
+
+void camif_hw_set_lastirq(struct camif_vp *vp, int enable)
+{
+       u32 addr = S3C_CAMIF_REG_CICTRL(vp->id, vp->offset);
+       u32 cfg;
+
+       cfg = camif_read(vp->camif, addr);
+       if (enable)
+               cfg |= CICTRL_LASTIRQ_ENABLE;
+       else
+               cfg &= ~CICTRL_LASTIRQ_ENABLE;
+       camif_write(vp->camif, addr, cfg);
+}
+
+void camif_hw_enable_capture(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       u32 cfg;
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CIIMGCPT(vp->offset));
+       camif->stream_count++;
+
+       if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV)
+               cfg |= CIIMGCPT_CPT_FREN_ENABLE(vp->id);
+
+       if (vp->scaler.enable)
+               cfg |= CIIMGCPT_IMGCPTEN_SC(vp->id);
+
+       if (camif->stream_count == 1)
+               cfg |= CIIMGCPT_IMGCPTEN;
+
+       camif_write(camif, S3C_CAMIF_REG_CIIMGCPT(vp->offset), cfg);
+
+       pr_debug("CIIMGCPT: %#x, camif->stream_count: %d\n",
+                cfg, camif->stream_count);
+}
+
+void camif_hw_disable_capture(struct camif_vp *vp)
+{
+       struct camif_dev *camif = vp->camif;
+       u32 cfg;
+
+       cfg = camif_read(camif, S3C_CAMIF_REG_CIIMGCPT(vp->offset));
+       cfg &= ~CIIMGCPT_IMGCPTEN_SC(vp->id);
+
+       if (WARN_ON(--(camif->stream_count) < 0))
+               camif->stream_count = 0;
+
+       if (camif->stream_count == 0)
+               cfg &= ~CIIMGCPT_IMGCPTEN;
+
+       pr_debug("CIIMGCPT: %#x, camif->stream_count: %d\n",
+                cfg, camif->stream_count);
+
+       camif_write(camif, S3C_CAMIF_REG_CIIMGCPT(vp->offset), cfg);
+}
+
+void camif_hw_dump_regs(struct camif_dev *camif, const char *label)
+{
+       struct {
+               u32 offset;
+               const char * const name;
+       } registers[] = {
+               { S3C_CAMIF_REG_CISRCFMT,               "CISRCFMT" },
+               { S3C_CAMIF_REG_CIWDOFST,               "CIWDOFST" },
+               { S3C_CAMIF_REG_CIGCTRL,                "CIGCTRL" },
+               { S3C_CAMIF_REG_CIWDOFST2,              "CIWDOFST2" },
+               { S3C_CAMIF_REG_CIYSA(0, 0),            "CICOYSA0" },
+               { S3C_CAMIF_REG_CICBSA(0, 0),           "CICOCBSA0" },
+               { S3C_CAMIF_REG_CICRSA(0, 0),           "CICOCRSA0" },
+               { S3C_CAMIF_REG_CIYSA(0, 1),            "CICOYSA1" },
+               { S3C_CAMIF_REG_CICBSA(0, 1),           "CICOCBSA1" },
+               { S3C_CAMIF_REG_CICRSA(0, 1),           "CICOCRSA1" },
+               { S3C_CAMIF_REG_CIYSA(0, 2),            "CICOYSA2" },
+               { S3C_CAMIF_REG_CICBSA(0, 2),           "CICOCBSA2" },
+               { S3C_CAMIF_REG_CICRSA(0, 2),           "CICOCRSA2" },
+               { S3C_CAMIF_REG_CIYSA(0, 3),            "CICOYSA3" },
+               { S3C_CAMIF_REG_CICBSA(0, 3),           "CICOCBSA3" },
+               { S3C_CAMIF_REG_CICRSA(0, 3),           "CICOCRSA3" },
+               { S3C_CAMIF_REG_CIYSA(1, 0),            "CIPRYSA0" },
+               { S3C_CAMIF_REG_CIYSA(1, 1),            "CIPRYSA1" },
+               { S3C_CAMIF_REG_CIYSA(1, 2),            "CIPRYSA2" },
+               { S3C_CAMIF_REG_CIYSA(1, 3),            "CIPRYSA3" },
+               { S3C_CAMIF_REG_CITRGFMT(0, 0),         "CICOTRGFMT" },
+               { S3C_CAMIF_REG_CITRGFMT(1, 0),         "CIPRTRGFMT" },
+               { S3C_CAMIF_REG_CICTRL(0, 0),           "CICOCTRL" },
+               { S3C_CAMIF_REG_CICTRL(1, 0),           "CIPRCTRL" },
+               { S3C_CAMIF_REG_CISCPREDST(0, 0),       "CICOSCPREDST" },
+               { S3C_CAMIF_REG_CISCPREDST(1, 0),       "CIPRSCPREDST" },
+               { S3C_CAMIF_REG_CISCPRERATIO(0, 0),     "CICOSCPRERATIO" },
+               { S3C_CAMIF_REG_CISCPRERATIO(1, 0),     "CIPRSCPRERATIO" },
+               { S3C_CAMIF_REG_CISCCTRL(0, 0),         "CICOSCCTRL" },
+               { S3C_CAMIF_REG_CISCCTRL(1, 0),         "CIPRSCCTRL" },
+               { S3C_CAMIF_REG_CITAREA(0, 0),          "CICOTAREA" },
+               { S3C_CAMIF_REG_CITAREA(1, 0),          "CIPRTAREA" },
+               { S3C_CAMIF_REG_CISTATUS(0, 0),         "CICOSTATUS" },
+               { S3C_CAMIF_REG_CISTATUS(1, 0),         "CIPRSTATUS" },
+               { S3C_CAMIF_REG_CIIMGCPT(0),            "CIIMGCPT" },
+       };
+       u32 i;
+
+       pr_info("--- %s ---\n", label);
+       for (i = 0; i < ARRAY_SIZE(registers); i++) {
+               u32 cfg = readl(camif->io_base + registers[i].offset);
+               printk(KERN_INFO "%s:\t0x%08x\n", registers[i].name, cfg);
+       }
+}
diff --git a/drivers/media/platform/s3c-camif/camif-regs.h b/drivers/media/platform/s3c-camif/camif-regs.h
new file mode 100644 (file)
index 0000000..af2d472
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Register definition file for s3c24xx/s3c64xx SoC CAMIF driver
+ *
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ * Copyright (C) 2012 Tomasz Figa <tomasz.figa@gmail.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 CAMIF_REGS_H_
+#define CAMIF_REGS_H_
+
+#include "camif-core.h"
+#include <media/s3c_camif.h>
+
+/*
+ * The id argument indicates the processing path:
+ * id = 0 - codec (FIMC C), 1 - preview (FIMC P).
+ */
+
+/* Camera input format */
+#define S3C_CAMIF_REG_CISRCFMT                 0x00
+#define  CISRCFMT_ITU601_8BIT                  (1 << 31)
+#define  CISRCFMT_ITU656_8BIT                  (0 << 31)
+#define  CISRCFMT_ORDER422_YCBYCR              (0 << 14)
+#define  CISRCFMT_ORDER422_YCRYCB              (1 << 14)
+#define  CISRCFMT_ORDER422_CBYCRY              (2 << 14)
+#define  CISRCFMT_ORDER422_CRYCBY              (3 << 14)
+#define  CISRCFMT_ORDER422_MASK                        (3 << 14)
+#define  CISRCFMT_SIZE_CAM_MASK                        (0x1fff << 16 | 0x1fff)
+
+/* Window offset */
+#define S3C_CAMIF_REG_CIWDOFST                 0x04
+#define  CIWDOFST_WINOFSEN                     (1 << 31)
+#define  CIWDOFST_CLROVCOFIY                   (1 << 30)
+#define  CIWDOFST_CLROVRLB_PR                  (1 << 28)
+/* #define  CIWDOFST_CLROVPRFIY                        (1 << 27) */
+#define  CIWDOFST_CLROVCOFICB                  (1 << 15)
+#define  CIWDOFST_CLROVCOFICR                  (1 << 14)
+#define  CIWDOFST_CLROVPRFICB                  (1 << 13)
+#define  CIWDOFST_CLROVPRFICR                  (1 << 12)
+#define  CIWDOFST_OFST_MASK                    (0x7ff << 16 | 0x7ff)
+
+/* Window offset 2 */
+#define S3C_CAMIF_REG_CIWDOFST2                        0x14
+#define  CIWDOFST2_OFST2_MASK                  (0xfff << 16 | 0xfff)
+
+/* Global control */
+#define S3C_CAMIF_REG_CIGCTRL                  0x08
+#define  CIGCTRL_SWRST                         (1 << 31)
+#define  CIGCTRL_CAMRST                                (1 << 30)
+#define  CIGCTRL_TESTPATTERN_NORMAL            (0 << 27)
+#define  CIGCTRL_TESTPATTERN_COLOR_BAR         (1 << 27)
+#define  CIGCTRL_TESTPATTERN_HOR_INC           (2 << 27)
+#define  CIGCTRL_TESTPATTERN_VER_INC           (3 << 27)
+#define  CIGCTRL_TESTPATTERN_MASK              (3 << 27)
+#define  CIGCTRL_INVPOLPCLK                    (1 << 26)
+#define  CIGCTRL_INVPOLVSYNC                   (1 << 25)
+#define  CIGCTRL_INVPOLHREF                    (1 << 24)
+#define  CIGCTRL_IRQ_OVFEN                     (1 << 22)
+#define  CIGCTRL_HREF_MASK                     (1 << 21)
+#define  CIGCTRL_IRQ_LEVEL                     (1 << 20)
+/* IRQ_CLR_C, IRQ_CLR_P */
+#define  CIGCTRL_IRQ_CLR(id)                   (1 << (19 - (id)))
+#define  CIGCTRL_FIELDMODE                     (1 << 2)
+#define  CIGCTRL_INVPOLFIELD                   (1 << 1)
+#define  CIGCTRL_CAM_INTERLACE                 (1 << 0)
+
+/* Y DMA output frame start address. n = 0..3. */
+#define S3C_CAMIF_REG_CIYSA(id, n)             (0x18 + (id) * 0x54 + (n) * 4)
+/* Cb plane output DMA start address. n = 0..3. Only codec path. */
+#define S3C_CAMIF_REG_CICBSA(id, n)            (0x28 + (id) * 0x54 + (n) * 4)
+/* Cr plane output DMA start address. n = 0..3. Only codec path. */
+#define S3C_CAMIF_REG_CICRSA(id, n)            (0x38 + (id) * 0x54 + (n) * 4)
+
+/* CICOTRGFMT, CIPRTRGFMT - Target format */
+#define S3C_CAMIF_REG_CITRGFMT(id, _offs)      (0x48 + (id) * (0x34 + (_offs)))
+#define  CITRGFMT_IN422                                (1 << 31) /* only for s3c24xx */
+#define  CITRGFMT_OUT422                       (1 << 30) /* only for s3c24xx */
+#define  CITRGFMT_OUTFORMAT_YCBCR420           (0 << 29) /* only for s3c6410 */
+#define  CITRGFMT_OUTFORMAT_YCBCR422           (1 << 29) /* only for s3c6410 */
+#define  CITRGFMT_OUTFORMAT_YCBCR422I          (2 << 29) /* only for s3c6410 */
+#define  CITRGFMT_OUTFORMAT_RGB                        (3 << 29) /* only for s3c6410 */
+#define  CITRGFMT_OUTFORMAT_MASK               (3 << 29) /* only for s3c6410 */
+#define  CITRGFMT_TARGETHSIZE(x)               ((x) << 16)
+#define  CITRGFMT_FLIP_NORMAL                  (0 << 14)
+#define  CITRGFMT_FLIP_X_MIRROR                        (1 << 14)
+#define  CITRGFMT_FLIP_Y_MIRROR                        (2 << 14)
+#define  CITRGFMT_FLIP_180                     (3 << 14)
+#define  CITRGFMT_FLIP_MASK                    (3 << 14)
+/* Preview path only */
+#define  CITRGFMT_ROT90_PR                     (1 << 13)
+#define  CITRGFMT_TARGETVSIZE(x)               ((x) << 0)
+#define  CITRGFMT_TARGETSIZE_MASK              ((0x1fff << 16) | 0x1fff)
+
+/* CICOCTRL, CIPRCTRL. Output DMA control. */
+#define S3C_CAMIF_REG_CICTRL(id, _offs)                (0x4c + (id) * (0x34 + (_offs)))
+#define  CICTRL_BURST_MASK                     (0xfffff << 4)
+/* xBURSTn - 5-bits width */
+#define  CICTRL_YBURST1(x)                     ((x) << 19)
+#define  CICTRL_YBURST2(x)                     ((x) << 14)
+#define  CICTRL_RGBBURST1(x)                   ((x) << 19)
+#define  CICTRL_RGBBURST2(x)                   ((x) << 14)
+#define  CICTRL_CBURST1(x)                     ((x) << 9)
+#define  CICTRL_CBURST2(x)                     ((x) << 4)
+#define  CICTRL_LASTIRQ_ENABLE                 (1 << 2)
+#define  CICTRL_ORDER422_MASK                  (3 << 0)
+
+/* CICOSCPRERATIO, CIPRSCPRERATIO. Pre-scaler control 1. */
+#define S3C_CAMIF_REG_CISCPRERATIO(id, _offs)  (0x50 + (id) * (0x34 + (_offs)))
+
+/* CICOSCPREDST, CIPRSCPREDST. Pre-scaler control 2. */
+#define S3C_CAMIF_REG_CISCPREDST(id, _offs)    (0x54 + (id) * (0x34 + (_offs)))
+
+/* CICOSCCTRL, CIPRSCCTRL. Main scaler control. */
+#define S3C_CAMIF_REG_CISCCTRL(id, _offs)      (0x58 + (id) * (0x34 + (_offs)))
+#define  CISCCTRL_SCALERBYPASS                 (1 << 31)
+/* s3c244x preview path only, s3c64xx both */
+#define  CIPRSCCTRL_SAMPLE                     (1 << 31)
+/* 0 - 16-bit RGB, 1 - 24-bit RGB */
+#define  CIPRSCCTRL_RGB_FORMAT_24BIT           (1 << 30) /* only for s3c244x */
+#define  CIPRSCCTRL_SCALEUP_H                  (1 << 29) /* only for s3c244x */
+#define  CIPRSCCTRL_SCALEUP_V                  (1 << 28) /* only for s3c244x */
+/* s3c64xx */
+#define  CISCCTRL_SCALEUP_H                    (1 << 30)
+#define  CISCCTRL_SCALEUP_V                    (1 << 29)
+#define  CISCCTRL_SCALEUP_MASK                 (0x3 << 29)
+#define  CISCCTRL_CSCR2Y_WIDE                  (1 << 28)
+#define  CISCCTRL_CSCY2R_WIDE                  (1 << 27)
+#define  CISCCTRL_LCDPATHEN_FIFO               (1 << 26)
+#define  CISCCTRL_INTERLACE                    (1 << 25)
+#define  CISCCTRL_SCALERSTART                  (1 << 15)
+#define  CISCCTRL_INRGB_FMT_RGB565             (0 << 13)
+#define  CISCCTRL_INRGB_FMT_RGB666             (1 << 13)
+#define  CISCCTRL_INRGB_FMT_RGB888             (2 << 13)
+#define  CISCCTRL_INRGB_FMT_MASK               (3 << 13)
+#define  CISCCTRL_OUTRGB_FMT_RGB565            (0 << 11)
+#define  CISCCTRL_OUTRGB_FMT_RGB666            (1 << 11)
+#define  CISCCTRL_OUTRGB_FMT_RGB888            (2 << 11)
+#define  CISCCTRL_OUTRGB_FMT_MASK              (3 << 11)
+#define  CISCCTRL_EXTRGB_EXTENSION             (1 << 10)
+#define  CISCCTRL_ONE2ONE                      (1 << 9)
+#define  CISCCTRL_MAIN_RATIO_MASK              (0x1ff << 16 | 0x1ff)
+
+/* CICOTAREA, CIPRTAREA. Target area for DMA (Hsize x Vsize). */
+#define S3C_CAMIF_REG_CITAREA(id, _offs)       (0x5c + (id) * (0x34 + (_offs)))
+#define CITAREA_MASK                           0xfffffff
+
+/* Codec (id = 0) or preview (id = 1) path status. */
+#define S3C_CAMIF_REG_CISTATUS(id, _offs)      (0x64 + (id) * (0x34 + (_offs)))
+#define  CISTATUS_OVFIY_STATUS                 (1 << 31)
+#define  CISTATUS_OVFICB_STATUS                        (1 << 30)
+#define  CISTATUS_OVFICR_STATUS                        (1 << 29)
+#define  CISTATUS_OVF_MASK                     (0x7 << 29)
+#define  CIPRSTATUS_OVF_MASK                   (0x3 << 30)
+#define  CISTATUS_VSYNC_STATUS                 (1 << 28)
+#define  CISTATUS_FRAMECNT_MASK                        (3 << 26)
+#define  CISTATUS_FRAMECNT(__reg)              (((__reg) >> 26) & 0x3)
+#define  CISTATUS_WINOFSTEN_STATUS             (1 << 25)
+#define  CISTATUS_IMGCPTEN_STATUS              (1 << 22)
+#define  CISTATUS_IMGCPTENSC_STATUS            (1 << 21)
+#define  CISTATUS_VSYNC_A_STATUS               (1 << 20)
+#define  CISTATUS_FRAMEEND_STATUS              (1 << 19) /* 17 on s3c64xx */
+
+/* Image capture enable */
+#define S3C_CAMIF_REG_CIIMGCPT(_offs)          (0xa0 + (_offs))
+#define  CIIMGCPT_IMGCPTEN                     (1 << 31)
+#define  CIIMGCPT_IMGCPTEN_SC(id)              (1 << (30 - (id)))
+/* Frame control: 1 - one-shot, 0 - free run */
+#define  CIIMGCPT_CPT_FREN_ENABLE(id)          (1 << (25 - (id)))
+#define  CIIMGCPT_CPT_FRMOD_ENABLE             (0 << 18)
+#define  CIIMGCPT_CPT_FRMOD_CNT                        (1 << 18)
+
+/* Capture sequence */
+#define S3C_CAMIF_REG_CICPTSEQ                 0xc4
+
+/* Image effects */
+#define S3C_CAMIF_REG_CIIMGEFF(_offs)          (0xb0 + (_offs))
+#define  CIIMGEFF_IE_ENABLE(id)                        (1 << (30 + (id)))
+#define  CIIMGEFF_IE_ENABLE_MASK               (3 << 30)
+/* Image effect: 1 - after scaler, 0 - before scaler */
+#define  CIIMGEFF_IE_AFTER_SC                  (1 << 29)
+#define  CIIMGEFF_FIN_MASK                     (7 << 26)
+#define  CIIMGEFF_FIN_BYPASS                   (0 << 26)
+#define  CIIMGEFF_FIN_ARBITRARY                        (1 << 26)
+#define  CIIMGEFF_FIN_NEGATIVE                 (2 << 26)
+#define  CIIMGEFF_FIN_ARTFREEZE                        (3 << 26)
+#define  CIIMGEFF_FIN_EMBOSSING                        (4 << 26)
+#define  CIIMGEFF_FIN_SILHOUETTE               (5 << 26)
+#define  CIIMGEFF_PAT_CBCR_MASK                        ((0xff << 13) | 0xff)
+#define  CIIMGEFF_PAT_CB(x)                    ((x) << 13)
+#define  CIIMGEFF_PAT_CR(x)                    (x)
+
+/* MSCOY0SA, MSPRY0SA. Y/Cb/Cr frame start address for input DMA. */
+#define S3C_CAMIF_REG_MSY0SA(id)               (0xd4 + ((id) * 0x2c))
+#define S3C_CAMIF_REG_MSCB0SA(id)              (0xd8 + ((id) * 0x2c))
+#define S3C_CAMIF_REG_MSCR0SA(id)              (0xdc + ((id) * 0x2c))
+
+/* MSCOY0END, MSCOY0END. Y/Cb/Cr frame end address for input DMA. */
+#define S3C_CAMIF_REG_MSY0END(id)              (0xe0 + ((id) * 0x2c))
+#define S3C_CAMIF_REG_MSCB0END(id)             (0xe4 + ((id) * 0x2c))
+#define S3C_CAMIF_REG_MSCR0END(id)             (0xe8 + ((id) * 0x2c))
+
+/* MSPRYOFF, MSPRYOFF. Y/Cb/Cr offset. n: 0 - codec, 1 - preview. */
+#define S3C_CAMIF_REG_MSYOFF(id)               (0x118 + ((id) * 0x2c))
+#define S3C_CAMIF_REG_MSCBOFF(id)              (0x11c + ((id) * 0x2c))
+#define S3C_CAMIF_REG_MSCROFF(id)              (0x120 + ((id) * 0x2c))
+
+/* Real input DMA data size. n = 0 - codec, 1 - preview. */
+#define S3C_CAMIF_REG_MSWIDTH(id)              (0xf8 + (id) * 0x2c)
+#define  AUTOLOAD_ENABLE                       (1 << 31)
+#define  ADDR_CH_DIS                           (1 << 30)
+#define  MSHEIGHT(x)                           (((x) & 0x3ff) << 16)
+#define  MSWIDTH(x)                            ((x) & 0x3ff)
+
+/* Input DMA control. n = 0 - codec, 1 - preview */
+#define S3C_CAMIF_REG_MSCTRL(id)               (0xfc + (id) * 0x2c)
+#define  MSCTRL_ORDER422_M_YCBYCR              (0 << 4)
+#define  MSCTRL_ORDER422_M_YCRYCB              (1 << 4)
+#define  MSCTRL_ORDER422_M_CBYCRY              (2 << 4)
+#define  MSCTRL_ORDER422_M_CRYCBY              (3 << 4)
+/* 0 - camera, 1 - DMA */
+#define  MSCTRL_SEL_DMA_CAM                    (1 << 3)
+#define  MSCTRL_INFORMAT_M_YCBCR420            (0 << 1)
+#define  MSCTRL_INFORMAT_M_YCBCR422            (1 << 1)
+#define  MSCTRL_INFORMAT_M_YCBCR422I           (2 << 1)
+#define  MSCTRL_INFORMAT_M_RGB                 (3 << 1)
+#define  MSCTRL_ENVID_M                                (1 << 0)
+
+/* CICOSCOSY, CIPRSCOSY. Scan line Y/Cb/Cr offset. */
+#define S3C_CAMIF_REG_CISSY(id)                        (0x12c + (id) * 0x0c)
+#define S3C_CAMIF_REG_CISSCB(id)               (0x130 + (id) * 0x0c)
+#define S3C_CAMIF_REG_CISSCR(id)               (0x134 + (id) * 0x0c)
+#define S3C_CISS_OFFS_INITIAL(x)               ((x) << 16)
+#define S3C_CISS_OFFS_LINE(x)                  ((x) << 0)
+
+/* ------------------------------------------------------------------ */
+
+void camif_hw_reset(struct camif_dev *camif);
+void camif_hw_clear_pending_irq(struct camif_vp *vp);
+void camif_hw_clear_fifo_overflow(struct camif_vp *vp);
+void camif_hw_set_lastirq(struct camif_vp *vp, int enable);
+void camif_hw_set_input_path(struct camif_vp *vp);
+void camif_hw_enable_scaler(struct camif_vp *vp, bool on);
+void camif_hw_enable_capture(struct camif_vp *vp);
+void camif_hw_disable_capture(struct camif_vp *vp);
+void camif_hw_set_camera_bus(struct camif_dev *camif);
+void camif_hw_set_source_format(struct camif_dev *camif);
+void camif_hw_set_camera_crop(struct camif_dev *camif);
+void camif_hw_set_scaler(struct camif_vp *vp);
+void camif_hw_set_flip(struct camif_vp *vp);
+void camif_hw_set_output_dma(struct camif_vp *vp);
+void camif_hw_set_target_format(struct camif_vp *vp);
+void camif_hw_set_test_pattern(struct camif_dev *camif, unsigned int pattern);
+void camif_hw_set_effect(struct camif_dev *camif, unsigned int effect,
+                       unsigned int cr, unsigned int cb);
+void camif_hw_set_output_addr(struct camif_vp *vp, struct camif_addr *paddr,
+                             int index);
+void camif_hw_dump_regs(struct camif_dev *camif, const char *label);
+
+static inline u32 camif_hw_get_status(struct camif_vp *vp)
+{
+       return readl(vp->camif->io_base + S3C_CAMIF_REG_CISTATUS(vp->id,
+                                                               vp->offset));
+}
+
+#endif /* CAMIF_REGS_H_ */
index 891ee873c62b8c281cf83f74cf1b29b1925a0f55..fdb6740248a73f58bd2c7ab42c72f03991d907f0 100644 (file)
@@ -1230,6 +1230,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
        return vb2_qbuf(&fimc->vid_cap.vbq, buf);
 }
 
+static int fimc_cap_expbuf(struct file *file, void *priv,
+                         struct v4l2_exportbuffer *eb)
+{
+       struct fimc_dev *fimc = video_drvdata(file);
+
+       return vb2_expbuf(&fimc->vid_cap.vbq, eb);
+}
+
 static int fimc_cap_dqbuf(struct file *file, void *priv,
                           struct v4l2_buffer *buf)
 {
@@ -1354,6 +1362,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
 
        .vidioc_qbuf                    = fimc_cap_qbuf,
        .vidioc_dqbuf                   = fimc_cap_dqbuf,
+       .vidioc_expbuf                  = fimc_cap_expbuf,
 
        .vidioc_prepare_buf             = fimc_cap_prepare_buf,
        .vidioc_create_bufs             = fimc_cap_create_bufs,
@@ -1729,7 +1738,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
        q = &fimc->vid_cap.vbq;
        memset(q, 0, sizeof(*q));
        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-       q->io_modes = VB2_MMAP | VB2_USERPTR;
+       q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
        q->drv_priv = fimc->vid_cap.ctx;
        q->ops = &fimc_capture_qops;
        q->mem_ops = &vb2_dma_contig_memops;
index 62afed3162eaec518d74cd0a72b5c26a8725987a..1d21da4bd24be130dbcdd2b15032ff198390804a 100644 (file)
@@ -105,7 +105,7 @@ static void fimc_device_run(void *priv)
        struct fimc_frame *sf, *df;
        struct fimc_dev *fimc;
        unsigned long flags;
-       u32 ret;
+       int ret;
 
        if (WARN(!ctx, "Null context\n"))
                return;
@@ -439,6 +439,15 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh,
        return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
 }
 
+static int fimc_m2m_expbuf(struct file *file, void *fh,
+                           struct v4l2_exportbuffer *eb)
+{
+       struct fimc_ctx *ctx = fh_to_ctx(fh);
+
+       return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
+}
+
+
 static int fimc_m2m_streamon(struct file *file, void *fh,
                             enum v4l2_buf_type type)
 {
@@ -607,6 +616,7 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
        .vidioc_querybuf                = fimc_m2m_querybuf,
        .vidioc_qbuf                    = fimc_m2m_qbuf,
        .vidioc_dqbuf                   = fimc_m2m_dqbuf,
+       .vidioc_expbuf                  = fimc_m2m_expbuf,
        .vidioc_streamon                = fimc_m2m_streamon,
        .vidioc_streamoff               = fimc_m2m_streamoff,
        .vidioc_g_crop                  = fimc_m2m_g_crop,
@@ -622,7 +632,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
        int ret;
 
        src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-       src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+       src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
        src_vq->drv_priv = ctx;
        src_vq->ops = &fimc_qops;
        src_vq->mem_ops = &vb2_dma_contig_memops;
@@ -633,7 +643,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
                return ret;
 
        dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-       dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+       dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
        dst_vq->drv_priv = ctx;
        dst_vq->ops = &fimc_qops;
        dst_vq->mem_ops = &vb2_dma_contig_memops;
index 0531ab70a94c42e512165d4bd3cfb5f117973d19..1bd5678cfeb9d13f4bfd4b1dc0f7ffccac5ce33b 100644 (file)
@@ -213,7 +213,7 @@ static int fimc_pipeline_close(struct fimc_pipeline *p)
  * @pipeline: video pipeline structure
  * @on: passed as the s_stream call argument
  */
-int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
+static int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
 {
        int i, ret;
 
@@ -547,7 +547,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
                if (ret)
                        break;
 
-               v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
+               v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]\n",
                          source->name, flags ? '=' : '-', sink->name);
 
                if (flags == 0 || sensor == NULL)
index eb6a70b0f8213285a888ee867e3346d8ca9c5770..6dad9a74f61c8bb0778a3ce12c11f0134e1a62ab 100644 (file)
@@ -636,6 +636,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
        return -EINVAL;
 }
 
+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+       struct v4l2_exportbuffer *eb)
+{
+       struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+
+       if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+               return vb2_expbuf(&ctx->vq_src, eb);
+       if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               return vb2_expbuf(&ctx->vq_dst, eb);
+       return -EINVAL;
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
                           enum v4l2_buf_type type)
@@ -813,6 +826,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
        .vidioc_querybuf = vidioc_querybuf,
        .vidioc_qbuf = vidioc_qbuf,
        .vidioc_dqbuf = vidioc_dqbuf,
+       .vidioc_expbuf = vidioc_expbuf,
        .vidioc_streamon = vidioc_streamon,
        .vidioc_streamoff = vidioc_streamoff,
        .vidioc_g_crop = vidioc_g_crop,
index 2af6d522f4acf3b94b142281c22edd2ce7c53c44..f92f6ddd739fc1f4cbf982ca41e9ab9a7005530d 100644 (file)
@@ -1165,6 +1165,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
        return ret;
 }
 
+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+       struct v4l2_exportbuffer *eb)
+{
+       struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+
+       if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+               return vb2_expbuf(&ctx->vq_src, eb);
+       if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+               return vb2_expbuf(&ctx->vq_dst, eb);
+       return -EINVAL;
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
                           enum v4l2_buf_type type)
@@ -1542,7 +1555,7 @@ int vidioc_encoder_cmd(struct file *file, void *priv,
 }
 
 static int vidioc_subscribe_event(struct v4l2_fh *fh,
-                                       struct v4l2_event_subscription *sub)
+                                 const struct v4l2_event_subscription *sub)
 {
        switch (sub->type) {
        case V4L2_EVENT_EOS:
@@ -1568,6 +1581,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = {
        .vidioc_querybuf = vidioc_querybuf,
        .vidioc_qbuf = vidioc_qbuf,
        .vidioc_dqbuf = vidioc_dqbuf,
+       .vidioc_expbuf = vidioc_expbuf,
        .vidioc_streamon = vidioc_streamon,
        .vidioc_streamoff = vidioc_streamoff,
        .vidioc_s_parm = vidioc_s_parm,
index 367db755228932f410c6157e06f67d8ac00b477f..2895333866fcfcbda0e74ab905ac921681f17845 100644 (file)
@@ -28,7 +28,7 @@ static struct s5p_mfc_pm *pm;
 static struct s5p_mfc_dev *p_dev;
 
 #ifdef CLK_DEBUG
-atomic_t clk_ref;
+static atomic_t clk_ref;
 #endif
 
 int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
index 0c1cd895ff660453dfff91f5ac40feea5d67535d..7379e77bf4e1daf1b89ae7a3b66ba24322c18942 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/videodev2.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/timer.h>
 #include <media/videobuf2-dma-contig.h>
 
@@ -698,6 +697,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
        return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
 }
 
+static int mxr_expbuf(struct file *file, void *priv,
+       struct v4l2_exportbuffer *eb)
+{
+       struct mxr_layer *layer = video_drvdata(file);
+
+       mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
+       return vb2_expbuf(&layer->vb_queue, eb);
+}
+
 static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
        struct mxr_layer *layer = video_drvdata(file);
@@ -725,6 +733,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
        .vidioc_querybuf = mxr_querybuf,
        .vidioc_qbuf = mxr_qbuf,
        .vidioc_dqbuf = mxr_dqbuf,
+       .vidioc_expbuf = mxr_expbuf,
        /* Streaming control */
        .vidioc_streamon = mxr_streamon,
        .vidioc_streamoff = mxr_streamoff,
@@ -1093,7 +1102,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
 
        layer->vb_queue = (struct vb2_queue) {
                .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-               .io_modes = VB2_MMAP | VB2_USERPTR,
+               .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF,
                .drv_priv = layer,
                .buf_struct_size = sizeof(struct mxr_buffer),
                .ops = &mxr_video_qops,
index 9afe1e7bde748a6b238ed45d99da4d6bdb1b7ecb..cb6791e62bd46fd26274f802100f497fa9bfc678 100644 (file)
@@ -19,6 +19,7 @@ config MX1_VIDEO
 
 config VIDEO_MX1
        tristate "i.MX1/i.MXL CMOS Sensor Interface driver"
+       depends on BROKEN
        depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA
        select FIQ
        select VIDEOBUF_DMA_CONTIG
index d3f0b84e2d7086e24b4e75a863e34d23464cda15..4e3735679f172fa3daf9620e3364a26987649da3 100644 (file)
@@ -645,11 +645,17 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
                               size_t count, loff_t *ppos)
 {
        struct soc_camera_device *icd = file->private_data;
-       int err = -EINVAL;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+       dev_dbg(icd->pdev, "read called, buf %p\n", buf);
+
+       if (ici->ops->init_videobuf2 && icd->vb2_vidq.io_modes & VB2_READ)
+               return vb2_read(&icd->vb2_vidq, buf, count, ppos,
+                               file->f_flags & O_NONBLOCK);
 
        dev_err(icd->pdev, "camera device read not implemented\n");
 
-       return err;
+       return -EINVAL;
 }
 
 static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1048,10 +1054,8 @@ static void scan_add_host(struct soc_camera_host *ici)
 
        list_for_each_entry(icd, &devices, list) {
                if (icd->iface == ici->nr) {
-                       int ret;
-
                        icd->parent = ici->v4l2_dev.dev;
-                       ret = soc_camera_probe(icd);
+                       soc_camera_probe(icd);
                }
        }
 
index b366b050a3dd487473345d1ddaee013b2740513f..0d59b9db83cb90b4d2ec1f38482111cdadbb77f5 100644 (file)
@@ -39,7 +39,6 @@
 /* Wake up at about 30 fps */
 #define WAKE_NUMERATOR 30
 #define WAKE_DENOMINATOR 1001
-#define BUFFER_TIMEOUT     msecs_to_jiffies(500)  /* 0.5 seconds */
 
 #define MAX_WIDTH 1920
 #define MAX_HEIGHT 1200
@@ -352,11 +351,6 @@ static void precalculate_bars(struct vivi_dev *dev)
        }
 }
 
-#define TSTAMP_MIN_Y   24
-#define TSTAMP_MAX_Y   (TSTAMP_MIN_Y + 15)
-#define TSTAMP_INPUT_X 10
-#define TSTAMP_MIN_X   (54 + TSTAMP_INPUT_X)
-
 /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
 static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd)
 {
@@ -1308,7 +1302,7 @@ static int __init vivi_create_instance(int inst)
        /* initialize queue */
        q = &dev->vb_vidq;
        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+       q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
        q->drv_priv = dev;
        q->buf_struct_size = sizeof(struct vivi_buffer);
        q->ops = &vivi_video_qops;
index 12c70e876f5863587359e5da742139e8a78a6ebd..a739ad492e7b3dbbe9976f00ee27b3ec27e77f0d 100644 (file)
@@ -82,7 +82,7 @@ static struct radio_isa_card *rtrack_alloc(void)
 #define AIMS_BIT_VOL_UP                (1 << 6)        /* active low */
 #define AIMS_BIT_VOL_DN                (1 << 7)        /* active low */
 
-void rtrack_set_pins(void *handle, u8 pins)
+static void rtrack_set_pins(void *handle, u8 pins)
 {
        struct radio_isa_card *isa = handle;
        struct rtrack *rt = container_of(isa, struct rtrack, isa);
index 697a421c99406faa84df2906d41e3d4492c8bd48..643d80ac28fb1269b70942d2a53ccb7303c266b7 100644 (file)
@@ -645,7 +645,8 @@ static int __init cadet_init(void)
        set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
        video_set_drvdata(&dev->vdev, dev);
 
-       if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
+       res = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
+       if (res < 0)
                goto err_hdl;
        v4l2_info(v4l2_dev, "ADS Cadet Radio Card at 0x%x\n", dev->io);
        return 0;
index 3c0067de4324281537d951cf8e216eae140c04db..84b7b9f4385e7b9d9af85c810793ed5e4ef4a416 100644 (file)
@@ -191,7 +191,7 @@ static bool radio_isa_valid_io(const struct radio_isa_driver *drv, int io)
        return false;
 }
 
-struct radio_isa_card *radio_isa_alloc(struct radio_isa_driver *drv,
+static struct radio_isa_card *radio_isa_alloc(struct radio_isa_driver *drv,
                                struct device *pdev)
 {
        struct v4l2_device *v4l2_dev;
@@ -207,8 +207,9 @@ struct radio_isa_card *radio_isa_alloc(struct radio_isa_driver *drv,
        return isa;
 }
 
-int radio_isa_common_probe(struct radio_isa_card *isa, struct device *pdev,
-                               int radio_nr, unsigned region_size)
+static int radio_isa_common_probe(struct radio_isa_card *isa,
+                                 struct device *pdev,
+                                 int radio_nr, unsigned region_size)
 {
        const struct radio_isa_driver *drv = isa->drv;
        const struct radio_isa_ops *ops = drv->ops;
@@ -287,7 +288,8 @@ err_dev_reg:
        return res;
 }
 
-int radio_isa_common_remove(struct radio_isa_card *isa, unsigned region_size)
+static int radio_isa_common_remove(struct radio_isa_card *isa,
+                                  unsigned region_size)
 {
        const struct radio_isa_ops *ops = isa->drv->ops;
 
index 227dcdb54df358235111f42518686b404317b76a..c260a2a354b1d0ab7eabaa3c0166c44df1682c67 100644 (file)
@@ -64,7 +64,7 @@ bool pnp_attached;
 #define FMI_BIT_VOL_SW         (1 << 3)
 #define FMI_BIT_TUN_STRQ       (1 << 4)
 
-void fmi_set_pins(void *handle, u8 pins)
+static void fmi_set_pins(void *handle, u8 pins)
 {
        struct fmi *fmi = handle;
        u8 bits = FMI_BIT_TUN_STRQ;
index d0c905310071e9cb0eba764bef1cc5787720fbd8..36aec575e0ecd37e3ad7ddab10735684ad1c951b 100644 (file)
@@ -145,7 +145,7 @@ struct tea5764_device {
 };
 
 /* I2C code related */
-int tea5764_i2c_read(struct tea5764_device *radio)
+static int tea5764_i2c_read(struct tea5764_device *radio)
 {
        int i;
        u16 *p = (u16 *) &radio->regs;
@@ -165,7 +165,7 @@ int tea5764_i2c_read(struct tea5764_device *radio)
        return 0;
 }
 
-int tea5764_i2c_write(struct tea5764_device *radio)
+static int tea5764_i2c_write(struct tea5764_device *radio)
 {
        struct tea5764_write_regs wr;
        struct tea5764_regs *r = &radio->regs;
index e3079c142c5f87af79ee9e11a4268b7ae46c5283..bd61b3bd0ca316a05d339b12a77d02c45c1a8cd6 100644 (file)
@@ -1769,7 +1769,7 @@ exit:
 }
 
 /* si4713_ioctl - deal with private ioctls (only rnl for now) */
-long si4713_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+static long si4713_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
        struct si4713_device *sdev = to_si4713_device(sd);
        struct si4713_rnl *rnl = arg;
index d84ad9dad323c25bea0e7b0972c1e3f72295ff28..aac0f025f7678c582a08fa5a8592f53091f6124b 100644 (file)
@@ -60,7 +60,7 @@
 #define fmdbg(format, ...) \
        printk(KERN_DEBUG "fmdrv: " format, ## __VA_ARGS__)
 #else /* DEBUG */
-#define fmdbg(format, ...)
+#define fmdbg(format, ...) do {} while(0)
 #endif
 enum {
        FM_MODE_OFF,
index bf867a6b5ea0b5c745bf6684a75183e25b354843..602ef7ac8c243a62249acb0e9ead0ff7f6768f13 100644 (file)
@@ -742,7 +742,7 @@ static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *fmdev)
                if ((meta_data & FM_RDS_STATUS_ERR_MASK) != 0)
                        break;
 
-               if (blk_idx < FM_RDS_BLK_IDX_A || blk_idx > FM_RDS_BLK_IDX_D) {
+               if (blk_idx > FM_RDS_BLK_IDX_D) {
                        fmdbg("Block sequence mismatch\n");
                        rds->last_blk_idx = -1;
                        break;
index 3dd9fc097c473f5974034fdce141079e242e915e..ebf09a3927deea0f34070d54aa6e3c65b7bd1742 100644 (file)
@@ -305,7 +305,7 @@ int fm_rx_set_volume(struct fmdev *fmdev, u16 vol_to_set)
        if (fmdev->curr_fmmode != FM_MODE_RX)
                return -EPERM;
 
-       if (vol_to_set < FM_RX_VOLUME_MIN || vol_to_set > FM_RX_VOLUME_MAX) {
+       if (vol_to_set > FM_RX_VOLUME_MAX) {
                fmerr("Volume is not within(%d-%d) range\n",
                           FM_RX_VOLUME_MIN, FM_RX_VOLUME_MAX);
                return -EINVAL;
index 49bb356ed14cabb56a2af7c5b9df9dfcb3cd1674..2d6fb26a017094a1fa23828b7ce5c546a2cdad80 100644 (file)
@@ -784,7 +784,7 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote)
 
        rdev->priv = ati_remote;
        rdev->driver_type = RC_DRIVER_SCANCODE;
-       rdev->allowed_protos = RC_TYPE_OTHER;
+       rdev->allowed_protos = RC_BIT_OTHER;
        rdev->driver_name = "ati_remote";
 
        rdev->open = ati_remote_rc_open;
index d05ac15b5de48673cafbd9825afa8925c3a3c5e7..22231dd4f62b9432039bc41fdf954c86d60415b0 100644 (file)
@@ -329,7 +329,7 @@ static int ene_rx_get_sample_reg(struct ene_device *dev)
 }
 
 /* Sense current received carrier */
-void ene_rx_sense_carrier(struct ene_device *dev)
+static void ene_rx_sense_carrier(struct ene_device *dev)
 {
        DEFINE_IR_RAW_EVENT(ev);
 
@@ -1003,7 +1003,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
        dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
        rdev = rc_allocate_device();
        if (!dev || !rdev)
-               goto error1;
+               goto failure;
 
        /* validate resources */
        error = -ENODEV;
@@ -1014,10 +1014,10 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
 
        if (!pnp_port_valid(pnp_dev, 0) ||
            pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE)
-               goto error;
+               goto failure;
 
        if (!pnp_irq_valid(pnp_dev, 0))
-               goto error;
+               goto failure;
 
        spin_lock_init(&dev->hw_lock);
 
@@ -1033,7 +1033,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
        /* detect hardware version and features */
        error = ene_hw_detect(dev);
        if (error)
-               goto error;
+               goto failure;
 
        if (!dev->hw_learning_and_tx_capable && txsim) {
                dev->hw_learning_and_tx_capable = true;
@@ -1046,7 +1046,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
                learning_mode_force = false;
 
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->priv = dev;
        rdev->open = ene_open;
        rdev->close = ene_close;
@@ -1078,30 +1078,27 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
        /* claim the resources */
        error = -EBUSY;
        if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
-               dev->hw_io = -1;
-               dev->irq = -1;
-               goto error;
+               goto failure;
        }
 
        dev->irq = pnp_irq(pnp_dev, 0);
        if (request_irq(dev->irq, ene_isr,
                        IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) {
-               dev->irq = -1;
-               goto error;
+               goto failure2;
        }
 
        error = rc_register_device(rdev);
        if (error < 0)
-               goto error;
+               goto failure3;
 
        pr_notice("driver has been successfully loaded\n");
        return 0;
-error:
-       if (dev && dev->irq >= 0)
-               free_irq(dev->irq, dev);
-       if (dev && dev->hw_io >= 0)
-               release_region(dev->hw_io, ENE_IO_SIZE);
-error1:
+
+failure3:
+       free_irq(dev->irq, dev);
+failure2:
+       release_region(dev->hw_io, ENE_IO_SIZE);
+failure:
        rc_free_device(rdev);
        kfree(dev);
        return error;
index 52fd7696b1ba8c7e5bccc9321fd8bd7f4a8fd105..936c3f79b62cba500b8e53ba4adffb899bfda007 100644 (file)
@@ -541,7 +541,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
        /* Set up the rc device */
        rdev->priv = fintek;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->open = fintek_open;
        rdev->close = fintek_close;
        rdev->input_name = FINTEK_DESCRIPTION;
@@ -684,12 +684,12 @@ static struct pnp_driver fintek_driver = {
        .shutdown       = fintek_shutdown,
 };
 
-int fintek_init(void)
+static int fintek_init(void)
 {
        return pnp_register_driver(&fintek_driver);
 }
 
-void fintek_exit(void)
+static void fintek_exit(void)
 {
        pnp_unregister_driver(&fintek_driver);
 }
index 04cb272db16a37fb11e2cd2cdeadb75b3d7b3760..ba1a1eb356cf765d47d48b0e829f37b0133b5259 100644 (file)
@@ -95,7 +95,7 @@ static int __devinit gpio_ir_recv_probe(struct platform_device *pdev)
        if (pdata->allowed_protos)
                rcdev->allowed_protos = pdata->allowed_protos;
        else
-               rcdev->allowed_protos = RC_TYPE_ALL;
+               rcdev->allowed_protos = RC_BIT_ALL;
        rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
 
        gpio_dev->rcdev = rcdev;
index 51d7057aca0443414f8325e119a1da81a2e03840..5a9163da63c36c2fbf8527996d9b24134d5ba79e 100644 (file)
@@ -499,7 +499,7 @@ static int __devinit iguanair_probe(struct usb_interface *intf,
        usb_to_input_id(ir->udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_TYPE_ALL;
+       rc->allowed_protos = RC_BIT_ALL;
        rc->priv = ir;
        rc->open = iguanair_open;
        rc->close = iguanair_close;
index 5dd0386604f0514d7421fe0b47f3b9097d6554df..8f6a28921ed413c718c0efea9ea70e437d2ac9d7 100644 (file)
@@ -1001,7 +1001,7 @@ static void imon_touch_display_timeout(unsigned long data)
  * it is not, so we must acquire it prior to calling send_packet, which
  * requires that the lock is held.
  */
-static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
+static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type)
 {
        int retval;
        struct imon_context *ictx = rc->priv;
@@ -1010,31 +1010,27 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
        unsigned char ir_proto_packet[] = {
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
 
-       if (rc_type && !(rc_type & rc->allowed_protos))
+       if (*rc_type && !(*rc_type & rc->allowed_protos))
                dev_warn(dev, "Looks like you're trying to use an IR protocol "
                         "this device does not support\n");
 
-       switch (rc_type) {
-       case RC_TYPE_RC6:
+       if (*rc_type & RC_BIT_RC6_MCE) {
                dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
                ir_proto_packet[0] = 0x01;
-               break;
-       case RC_TYPE_UNKNOWN:
-       case RC_TYPE_OTHER:
+               *rc_type = RC_BIT_RC6_MCE;
+       } else if (*rc_type & RC_BIT_OTHER) {
                dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
                if (!pad_stabilize)
                        dev_dbg(dev, "PAD stabilize functionality disabled\n");
                /* ir_proto_packet[0] = 0x00; // already the default */
-               rc_type = RC_TYPE_OTHER;
-               break;
-       default:
+               *rc_type = RC_BIT_OTHER;
+       } else {
                dev_warn(dev, "Unsupported IR protocol specified, overriding "
                         "to iMON IR protocol\n");
                if (!pad_stabilize)
                        dev_dbg(dev, "PAD stabilize functionality disabled\n");
                /* ir_proto_packet[0] = 0x00; // already the default */
-               rc_type = RC_TYPE_OTHER;
-               break;
+               *rc_type = RC_BIT_OTHER;
        }
 
        memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
@@ -1048,7 +1044,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
        if (retval)
                goto out;
 
-       ictx->rc_type = rc_type;
+       ictx->rc_type = *rc_type;
        ictx->pad_mouse = false;
 
 out:
@@ -1323,7 +1319,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
                rel_x = buf[2];
                rel_y = buf[3];
 
-               if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
+               if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) {
                        if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
                                dir = stabilize((int)rel_x, (int)rel_y,
                                                timeout, threshold);
@@ -1390,7 +1386,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
                buf[0] = 0x01;
                buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
 
-               if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
+               if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) {
                        dir = stabilize((int)rel_x, (int)rel_y,
                                        timeout, threshold);
                        if (!dir) {
@@ -1511,7 +1507,7 @@ static void imon_incoming_packet(struct imon_context *ictx,
                kc = imon_panel_key_lookup(scancode);
        } else {
                scancode = be32_to_cpu(*((u32 *)buf));
-               if (ictx->rc_type == RC_TYPE_RC6) {
+               if (ictx->rc_type == RC_BIT_RC6_MCE) {
                        ktype = IMON_KEY_IMON;
                        if (buf[0] == 0x80)
                                ktype = IMON_KEY_MCE;
@@ -1744,7 +1740,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
 {
        u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
        u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
-       u64 allowed_protos = RC_TYPE_OTHER;
+       u64 allowed_protos = RC_BIT_OTHER;
 
        switch (ffdc_cfg_byte) {
        /* iMON Knob, no display, iMON IR + vol knob */
@@ -1775,13 +1771,13 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
        case 0x9e:
                dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
-               allowed_protos = RC_TYPE_RC6;
+               allowed_protos = RC_BIT_RC6_MCE;
                break;
        /* iMON LCD, MCE IR */
        case 0x9f:
                dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
                detected_display_type = IMON_DISPLAY_TYPE_LCD;
-               allowed_protos = RC_TYPE_RC6;
+               allowed_protos = RC_BIT_RC6_MCE;
                break;
        default:
                dev_info(ictx->dev, "Unknown 0xffdc device, "
@@ -1789,7 +1785,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
                /* We don't know which one it is, allow user to set the
                 * RC6 one from userspace if OTHER wasn't correct. */
-               allowed_protos |= RC_TYPE_RC6;
+               allowed_protos |= RC_BIT_RC6_MCE;
                break;
        }
 
@@ -1875,7 +1871,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
 
        rdev->priv = ictx;
        rdev->driver_type = RC_DRIVER_SCANCODE;
-       rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */
+       rdev->allowed_protos = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
        rdev->change_protocol = imon_ir_change_protocol;
        rdev->driver_name = MOD_NAME;
 
@@ -1893,7 +1889,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
 
        imon_set_display_type(ictx);
 
-       if (ictx->rc_type == RC_TYPE_RC6)
+       if (ictx->rc_type == RC_BIT_RC6_MCE)
                rdev->map_name = RC_MAP_IMON_MCE;
        else
                rdev->map_name = RC_MAP_IMON_PAD;
index 035668e27f6b7798000428b4d2351c4908b93acc..69edffb9fe9af29056e74c843b5149d629071cb1 100644 (file)
@@ -47,7 +47,7 @@ static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev)
 {
        struct jvc_dec *data = &dev->raw->jvc;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_JVC))
+       if (!(dev->raw->enabled_protocols & RC_BIT_JVC))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -174,7 +174,7 @@ out:
 }
 
 static struct ir_raw_handler jvc_handler = {
-       .protocols      = RC_TYPE_JVC,
+       .protocols      = RC_BIT_JVC,
        .decode         = ir_jvc_decode,
 };
 
index 870c93052fd0a0a97dc2138f1f5694d52507feba..9945e5e7f61a6d58d94105c6f5a6a3c9555d93fb 100644 (file)
@@ -35,7 +35,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
        struct lirc_codec *lirc = &dev->raw->lirc;
        int sample;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_LIRC))
+       if (!(dev->raw->enabled_protocols & RC_BIT_LIRC))
                return 0;
 
        if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
@@ -408,7 +408,7 @@ static int ir_lirc_unregister(struct rc_dev *dev)
 }
 
 static struct ir_raw_handler lirc_handler = {
-       .protocols      = RC_TYPE_LIRC,
+       .protocols      = RC_BIT_LIRC,
        .decode         = ir_lirc_decode,
        .raw_register   = ir_lirc_register,
        .raw_unregister = ir_lirc_unregister,
index 3784ebf80ec7d9e162b95aab58434ef40d9d21c8..33fafa4cf7cb472643a5fa682b78d326e28aea6a 100644 (file)
@@ -216,7 +216,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u32 scancode;
        unsigned long delay;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_MCE_KBD))
+       if (!(dev->raw->enabled_protocols & RC_BIT_MCE_KBD))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -422,7 +422,7 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
 }
 
 static struct ir_raw_handler mce_kbd_handler = {
-       .protocols      = RC_TYPE_MCE_KBD,
+       .protocols      = RC_BIT_MCE_KBD,
        .decode         = ir_mce_kbd_decode,
        .raw_register   = ir_mce_kbd_register,
        .raw_unregister = ir_mce_kbd_unregister,
index 2ca509e6e16b6c73cc09b0bc84616b8b1b1beafe..a47ee36349694aeef38c0e64a2b1a6d27440db25 100644 (file)
@@ -52,7 +52,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u8 address, not_address, command, not_command;
        bool send_32bits = false;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_NEC))
+       if (!(dev->raw->enabled_protocols & RC_BIT_NEC))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -201,7 +201,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
 }
 
 static struct ir_raw_handler nec_handler = {
-       .protocols      = RC_TYPE_NEC,
+       .protocols      = RC_BIT_NEC,
        .decode         = ir_nec_decode,
 };
 
index 9ab663a507a4b7e13b216b9604d47f3692840ea5..5b4d1ddeac4ec30cffa5c78f97f9049bdca75dcc 100644 (file)
@@ -52,8 +52,8 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u8 toggle;
        u32 scancode;
 
-        if (!(dev->raw->enabled_protocols & RC_TYPE_RC5))
-                return 0;
+       if (!(dev->raw->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X)))
+               return 0;
 
        if (!is_timing_event(ev)) {
                if (ev.reset)
@@ -128,6 +128,10 @@ again:
                if (data->wanted_bits == RC5X_NBITS) {
                        /* RC5X */
                        u8 xdata, command, system;
+                       if (!(dev->raw->enabled_protocols & RC_BIT_RC5X)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        xdata    = (data->bits & 0x0003F) >> 0;
                        command  = (data->bits & 0x00FC0) >> 6;
                        system   = (data->bits & 0x1F000) >> 12;
@@ -141,6 +145,10 @@ again:
                } else {
                        /* RC5 */
                        u8 command, system;
+                       if (!(dev->raw->enabled_protocols & RC_BIT_RC5)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        command  = (data->bits & 0x0003F) >> 0;
                        system   = (data->bits & 0x007C0) >> 6;
                        toggle   = (data->bits & 0x00800) ? 1 : 0;
@@ -164,7 +172,7 @@ out:
 }
 
 static struct ir_raw_handler rc5_handler = {
-       .protocols      = RC_TYPE_RC5,
+       .protocols      = RC_BIT_RC5 | RC_BIT_RC5X,
        .decode         = ir_rc5_decode,
 };
 
index ec8d4a2e2c5a1d215920ab69f797c7bc39fa5fce..fd807a8308d8e4ff917dbf74bb7bbca60a519320 100644 (file)
@@ -48,8 +48,8 @@ static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u8 toggle, command, system;
        u32 scancode;
 
-        if (!(dev->raw->enabled_protocols & RC_TYPE_RC5_SZ))
-                return 0;
+       if (!(dev->raw->enabled_protocols & RC_BIT_RC5_SZ))
+               return 0;
 
        if (!is_timing_event(ev)) {
                if (ev.reset)
@@ -128,7 +128,7 @@ out:
 }
 
 static struct ir_raw_handler rc5_sz_handler = {
-       .protocols      = RC_TYPE_RC5_SZ,
+       .protocols      = RC_BIT_RC5_SZ,
        .decode         = ir_rc5_sz_decode,
 };
 
index 4cfdd7fa4bbd56b7d04f130b78020f8977ebaec6..e19072ffb36ca4b873e11b70507b559fc9035a35 100644 (file)
@@ -89,7 +89,9 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u32 scancode;
        u8 toggle;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_RC6))
+       if (!(dev->raw->enabled_protocols &
+             (RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 |
+              RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE)))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -271,7 +273,9 @@ out:
 }
 
 static struct ir_raw_handler rc6_handler = {
-       .protocols      = RC_TYPE_RC6,
+       .protocols      = RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 |
+                         RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 |
+                         RC_BIT_RC6_MCE,
        .decode         = ir_rc6_decode,
 };
 
index 82e6c1e282d5e6a72784f1fa57489553d4d82e9b..9e76c7b40af2f63430d69f25299307164b7daf17 100644 (file)
@@ -479,18 +479,7 @@ struct platform_driver lirc_rx51_platform_driver = {
                .owner  = THIS_MODULE,
        },
 };
-
-static int __init lirc_rx51_init(void)
-{
-       return platform_driver_register(&lirc_rx51_platform_driver);
-}
-module_init(lirc_rx51_init);
-
-static void __exit lirc_rx51_exit(void)
-{
-       platform_driver_unregister(&lirc_rx51_platform_driver);
-}
-module_exit(lirc_rx51_exit);
+module_platform_driver(lirc_rx51_platform_driver);
 
 MODULE_DESCRIPTION("LIRC TX driver for Nokia RX51");
 MODULE_AUTHOR("Nokia Corporation");
index 7e54ec57bcf9cd3fec378d36dd32b4ed6a800240..7e69a3b653700105c6e4a6c7c775655f83d57e86 100644 (file)
@@ -58,7 +58,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u32 scancode;
        u8 address, command, not_command;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_SANYO))
+       if (!(dev->raw->enabled_protocols & RC_BIT_SANYO))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -179,7 +179,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
 }
 
 static struct ir_raw_handler sanyo_handler = {
-       .protocols      = RC_TYPE_SANYO,
+       .protocols      = RC_BIT_SANYO,
        .decode         = ir_sanyo_decode,
 };
 
index dab98b37621a06f5b19f88f00b1bef51c03954f1..fb914342cf4db3f2f0f56035ed0fbb78de0872aa 100644 (file)
@@ -45,7 +45,8 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
        u32 scancode;
        u8 device, subdevice, function;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_SONY))
+       if (!(dev->raw->enabled_protocols &
+             (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20)))
                return 0;
 
        if (!is_timing_event(ev)) {
@@ -123,16 +124,28 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
 
                switch (data->count) {
                case 12:
+                       if (!(dev->raw->enabled_protocols & RC_BIT_SONY12)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        device    = bitrev8((data->bits <<  3) & 0xF8);
                        subdevice = 0;
                        function  = bitrev8((data->bits >>  4) & 0xFE);
                        break;
                case 15:
+                       if (!(dev->raw->enabled_protocols & RC_BIT_SONY15)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        device    = bitrev8((data->bits >>  0) & 0xFF);
                        subdevice = 0;
                        function  = bitrev8((data->bits >>  7) & 0xFE);
                        break;
                case 20:
+                       if (!(dev->raw->enabled_protocols & RC_BIT_SONY20)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        device    = bitrev8((data->bits >>  5) & 0xF8);
                        subdevice = bitrev8((data->bits >>  0) & 0xFF);
                        function  = bitrev8((data->bits >> 12) & 0xFE);
@@ -157,7 +170,7 @@ out:
 }
 
 static struct ir_raw_handler sony_handler = {
-       .protocols      = RC_TYPE_SONY,
+       .protocols      = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20,
        .decode         = ir_sony_decode,
 };
 
index 24c77a42fc3645c2297688878396ae992ab9dc6b..5e5a7f2b8184cc992fab2bf0e3e90cb09c65c154 100644 (file)
@@ -1563,7 +1563,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
        /* set up ir-core props */
        rdev->priv = itdev;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->open = ite_open;
        rdev->close = ite_close;
        rdev->s_idle = ite_s_idle;
@@ -1708,12 +1708,12 @@ static struct pnp_driver ite_driver = {
        .shutdown       = ite_shutdown,
 };
 
-int ite_init(void)
+static int ite_init(void)
 {
        return pnp_register_driver(&ite_driver);
 }
 
-void ite_exit(void)
+static void ite_exit(void)
 {
        pnp_unregister_driver(&ite_driver);
 }
index 124c7228ba8cb4e69faf664af4acadad22da111c..f0da960560b010e6fb05edd8643b4ff746745894 100644 (file)
@@ -121,7 +121,7 @@ static struct rc_map_list imon_mce_map = {
                .scan    = imon_mce,
                .size    = ARRAY_SIZE(imon_mce),
                /* its RC6, but w/a hardware decoder */
-               .rc_type = RC_TYPE_RC6,
+               .rc_type = RC_TYPE_RC6_MCE,
                .name    = RC_MAP_IMON_MCE,
        }
 };
index 753e43ec787ba10d09f35fbd4d5a33457319477a..ef4006fe4de0a6ca48d7bb3b6fa059bfa5af59fd 100644 (file)
@@ -97,7 +97,7 @@ static struct rc_map_list rc6_mce_map = {
        .map = {
                .scan    = rc6_mce,
                .size    = ARRAY_SIZE(rc6_mce),
-               .rc_type = RC_TYPE_RC6,
+               .rc_type = RC_TYPE_RC6_MCE,
                .name    = RC_MAP_RC6_MCE,
        }
 };
index 850547fe711c25131ca84b748b35de2c35b8b5ae..b2146cd99fd8a74f65a57c7b11886b27764f8272 100644 (file)
@@ -1205,7 +1205,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
        rc->dev.parent = dev;
        rc->priv = ir;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_TYPE_ALL;
+       rc->allowed_protos = RC_BIT_ALL;
        rc->timeout = MS_TO_NS(100);
        if (!ir->flags.no_tx) {
                rc->s_tx_mask = mceusb_set_tx_mask;
index 2ea913a44ae887b8cfe48503e68c707201ae2a88..e4ea89a11eed451efd967b36a41a4fbbf5a7edf0 100644 (file)
@@ -472,6 +472,7 @@ static void nvt_enable_wake(struct nvt_dev *nvt)
        nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IREN);
 }
 
+#if 0 /* Currently unused */
 /* rx carrier detect only works in learning mode, must be called w/nvt_lock */
 static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt)
 {
@@ -504,7 +505,7 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt)
 
        return carrier;
 }
-
+#endif
 /*
  * set carrier frequency
  *
@@ -620,7 +621,6 @@ static void nvt_dump_rx_buf(struct nvt_dev *nvt)
 static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
 {
        DEFINE_IR_RAW_EVENT(rawir);
-       u32 carrier;
        u8 sample;
        int i;
 
@@ -629,9 +629,6 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
        if (debug)
                nvt_dump_rx_buf(nvt);
 
-       if (nvt->carrier_detect_enabled)
-               carrier = nvt_rx_carrier_detect(nvt);
-
        nvt_dbg_verbose("Processing buffer of len %d", nvt->pkts);
 
        init_ir_raw_event(&rawir);
@@ -1045,7 +1042,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
        /* Set up the rc device */
        rdev->priv = nvt;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->open = nvt_open;
        rdev->close = nvt_close;
        rdev->tx_ir = nvt_tx_ir;
@@ -1220,12 +1217,12 @@ static struct pnp_driver nvt_driver = {
        .shutdown       = nvt_shutdown,
 };
 
-int nvt_init(void)
+static int nvt_init(void)
 {
        return pnp_register_driver(&nvt_driver);
 }
 
-void nvt_exit(void)
+static void nvt_exit(void)
 {
        pnp_unregister_driver(&nvt_driver);
 }
index 0d5e0872a2ea2f43b2d9fd31f18ffeac78361118..7c3674ff5ea2a06073820bb1b19d2b7ec0097ef9 100644 (file)
@@ -103,7 +103,6 @@ struct nvt_dev {
 
        /* rx settings */
        bool learning_enabled;
-       bool carrier_detect_enabled;
 
        /* track cir wake state */
        u8 wake_state;
index f9be68132c67069e9f30eca7acade491d2770d41..53d02827a4724f8e5dfeb1eeea19895f42b7fbba 100644 (file)
@@ -195,7 +195,7 @@ static int __init loop_init(void)
        rc->map_name            = RC_MAP_EMPTY;
        rc->priv                = &loopdev;
        rc->driver_type         = RC_DRIVER_IR_RAW;
-       rc->allowed_protos      = RC_TYPE_ALL;
+       rc->allowed_protos      = RC_BIT_ALL;
        rc->timeout             = 100 * 1000 * 1000; /* 100 ms */
        rc->min_timeout         = 1;
        rc->max_timeout         = UINT_MAX;
index cabc19c105152937dab25fd0b04052f7d053a63f..601d1ac1c688b2608e8b96cbecae27f877c4b4b6 100644 (file)
@@ -725,25 +725,36 @@ static struct class ir_input_class = {
        .devnode        = ir_devnode,
 };
 
+/*
+ * These are the protocol textual descriptions that are
+ * used by the sysfs protocols file. Note that the order
+ * of the entries is relevant.
+ */
 static struct {
        u64     type;
        char    *name;
 } proto_names[] = {
-       { RC_TYPE_UNKNOWN,      "unknown"       },
-       { RC_TYPE_RC5,          "rc-5"          },
-       { RC_TYPE_NEC,          "nec"           },
-       { RC_TYPE_RC6,          "rc-6"          },
-       { RC_TYPE_JVC,          "jvc"           },
-       { RC_TYPE_SONY,         "sony"          },
-       { RC_TYPE_RC5_SZ,       "rc-5-sz"       },
-       { RC_TYPE_SANYO,        "sanyo"         },
-       { RC_TYPE_MCE_KBD,      "mce_kbd"       },
-       { RC_TYPE_LIRC,         "lirc"          },
-       { RC_TYPE_OTHER,        "other"         },
+       { RC_BIT_NONE,          "none"          },
+       { RC_BIT_OTHER,         "other"         },
+       { RC_BIT_UNKNOWN,       "unknown"       },
+       { RC_BIT_RC5 |
+         RC_BIT_RC5X,          "rc-5"          },
+       { RC_BIT_NEC,           "nec"           },
+       { RC_BIT_RC6_0 |
+         RC_BIT_RC6_6A_20 |
+         RC_BIT_RC6_6A_24 |
+         RC_BIT_RC6_6A_32 |
+         RC_BIT_RC6_MCE,       "rc-6"          },
+       { RC_BIT_JVC,           "jvc"           },
+       { RC_BIT_SONY12 |
+         RC_BIT_SONY15 |
+         RC_BIT_SONY20,        "sony"          },
+       { RC_BIT_RC5_SZ,        "rc-5-sz"       },
+       { RC_BIT_SANYO,         "sanyo"         },
+       { RC_BIT_MCE_KBD,       "mce_kbd"       },
+       { RC_BIT_LIRC,          "lirc"          },
 };
 
-#define PROTO_NONE     "none"
-
 /**
  * show_protocols() - shows the current IR protocol(s)
  * @device:    the device descriptor
@@ -790,6 +801,9 @@ static ssize_t show_protocols(struct device *device,
                        tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
                else if (allowed & proto_names[i].type)
                        tmp += sprintf(tmp, "%s ", proto_names[i].name);
+
+               if (allowed & proto_names[i].type)
+                       allowed &= ~proto_names[i].type;
        }
 
        if (tmp != buf)
@@ -867,26 +881,20 @@ static ssize_t store_protocols(struct device *device,
                        disable = false;
                }
 
-               if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
-                       tmp += sizeof(PROTO_NONE);
-                       mask = 0;
-                       count++;
-               } else {
-                       for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
-                               if (!strcasecmp(tmp, proto_names[i].name)) {
-                                       tmp += strlen(proto_names[i].name);
-                                       mask = proto_names[i].type;
-                                       break;
-                               }
-                       }
-                       if (i == ARRAY_SIZE(proto_names)) {
-                               IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
-                               ret = -EINVAL;
-                               goto out;
+               for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+                       if (!strcasecmp(tmp, proto_names[i].name)) {
+                               mask = proto_names[i].type;
+                               break;
                        }
-                       count++;
                }
 
+               if (i == ARRAY_SIZE(proto_names)) {
+                       IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
+                       return -EINVAL;
+               }
+
+               count++;
+
                if (enable)
                        type |= mask;
                else if (disable)
@@ -902,7 +910,7 @@ static ssize_t store_protocols(struct device *device,
        }
 
        if (dev->change_protocol) {
-               rc = dev->change_protocol(dev, type);
+               rc = dev->change_protocol(dev, &type);
                if (rc < 0) {
                        IR_dprintk(1, "Error setting protocols to 0x%llx\n",
                                   (long long)type);
@@ -1117,7 +1125,8 @@ int rc_register_device(struct rc_dev *dev)
        }
 
        if (dev->change_protocol) {
-               rc = dev->change_protocol(dev, rc_map->rc_type);
+               u64 rc_type = (1 << rc_map->rc_type);
+               rc = dev->change_protocol(dev, &rc_type);
                if (rc < 0)
                        goto out_raw;
        }
index 9f5a17bb5ef5df9d09e09519a2424dbac2e0e158..a8887aba9fafe9483267f9122d0b8e39929b5c8c 100644 (file)
@@ -1082,7 +1082,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
        rc->dev.parent = dev;
        rc->priv = rr3;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_TYPE_ALL;
+       rc->allowed_protos = RC_BIT_ALL;
        rc->timeout = US_TO_NS(2750);
        rc->tx_ir = redrat3_transmit_ir;
        rc->s_tx_carrier = redrat3_set_tx_carrier;
index d6f4bfe09391e92b68981499d99bb2e076060b98..c720f12f661e5121c7ad0e5d9ba77e13f43d5013 100644 (file)
@@ -322,7 +322,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
        rdev->dev.parent = dev;
        rdev->priv = sz;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->driver_name = DRIVER_NAME;
        rdev->map_name = RC_MAP_STREAMZAP;
 
index fef05235234a7b232197429e771522fa5adad882..f0921b5483ebdd34bd967d8f03434c2d843e86b8 100644 (file)
@@ -316,7 +316,7 @@ static int __devinit ttusbir_probe(struct usb_interface *intf,
        usb_to_input_id(tt->udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_TYPE_ALL;
+       rc->allowed_protos = RC_BIT_ALL;
        rc->priv = tt;
        rc->driver_name = DRIVER_NAME;
        rc->map_name = RC_MAP_TT_1500;
index 7c9b5f33113b225405a33a30edd2098c4f6ffa52..7f3c476dde05fb712cbb0fbbbc55c36e3150aba4 100644 (file)
@@ -7,6 +7,7 @@
  *  with minor modifications.
  *
  *  Original Author: David Härdeman <david@hardeman.nu>
+ *     Copyright (C) 2012 Sean Young <sean@mess.org>
  *     Copyright (C) 2009 - 2011 David Härdeman <david@hardeman.nu>
  *
  *  Dedicated to my daughter Matilda, without whose loving attention this
@@ -22,9 +23,7 @@
  *    o IR Receive
  *    o IR Transmit
  *    o Wake-On-CIR functionality
- *
- *  To do:
- *    o Learning
+ *    o Carrier detection
  *
  *  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
 #define WBCIR_REGSEL_MASK      0x20
 /* Starting address of selected register in WBCIR_REG_WCEIR_INDEX */
 #define WBCIR_REG_ADDR0                0x00
+/* Enable carrier counter */
+#define WBCIR_CNTR_EN          0x01
+/* Reset carrier counter */
+#define WBCIR_CNTR_R           0x02
+/* Invert TX */
+#define WBCIR_IRTX_INV         0x04
 
 /* Valid banks for the SP3 UART */
 enum wbcir_bank {
@@ -184,7 +189,7 @@ enum wbcir_txstate {
 };
 
 /* Misc */
-#define WBCIR_NAME     "winbond-cir"
+#define WBCIR_NAME     "Winbond CIR"
 #define WBCIR_ID_FAMILY          0xF1 /* Family ID for the WPCD376I    */
 #define        WBCIR_ID_CHIP            0x04 /* Chip ID for the WPCD376I       */
 #define INVALID_SCANCODE   0x7FFFFFFF /* Invalid with all protos       */
@@ -207,7 +212,8 @@ struct wbcir_data {
        /* RX state */
        enum wbcir_rxstate rxstate;
        struct led_trigger *rxtrigger;
-       struct ir_raw_event rxev;
+       int carrier_report_enabled;
+       u32 pulse_duration;
 
        /* TX state */
        enum wbcir_txstate txstate;
@@ -329,6 +335,30 @@ wbcir_to_rc6cells(u8 val)
  *
  *****************************************************************************/
 
+static void
+wbcir_carrier_report(struct wbcir_data *data)
+{
+       unsigned counter = inb(data->ebase + WBCIR_REG_ECEIR_CNT_LO) |
+                       inb(data->ebase + WBCIR_REG_ECEIR_CNT_HI) << 8;
+
+       if (counter > 0 && counter < 0xffff) {
+               DEFINE_IR_RAW_EVENT(ev);
+
+               ev.carrier_report = 1;
+               ev.carrier = DIV_ROUND_CLOSEST(counter * 1000000u,
+                                               data->pulse_duration);
+
+               ir_raw_event_store(data->dev, &ev);
+       }
+
+       /* reset and restart the counter */
+       data->pulse_duration = 0;
+       wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_R,
+                                               WBCIR_CNTR_EN | WBCIR_CNTR_R);
+       wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_EN,
+                                               WBCIR_CNTR_EN | WBCIR_CNTR_R);
+}
+
 static void
 wbcir_idle_rx(struct rc_dev *dev, bool idle)
 {
@@ -339,9 +369,16 @@ wbcir_idle_rx(struct rc_dev *dev, bool idle)
                led_trigger_event(data->rxtrigger, LED_FULL);
        }
 
-       if (idle && data->rxstate != WBCIR_RXSTATE_INACTIVE)
+       if (idle && data->rxstate != WBCIR_RXSTATE_INACTIVE) {
+               data->rxstate = WBCIR_RXSTATE_INACTIVE;
+               led_trigger_event(data->rxtrigger, LED_OFF);
+
+               if (data->carrier_report_enabled)
+                       wbcir_carrier_report(data);
+
                /* Tell hardware to go idle by setting RXINACTIVE */
                outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR);
+       }
 }
 
 static void
@@ -349,21 +386,22 @@ wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device)
 {
        u8 irdata;
        DEFINE_IR_RAW_EVENT(rawir);
+       unsigned duration;
 
        /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */
        while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) {
                irdata = inb(data->sbase + WBCIR_REG_SP3_RXDATA);
                if (data->rxstate == WBCIR_RXSTATE_ERROR)
                        continue;
+
+               duration = ((irdata & 0x7F) + 1) * 2;
                rawir.pulse = irdata & 0x80 ? false : true;
-               rawir.duration = US_TO_NS(((irdata & 0x7F) + 1) * 10);
-               ir_raw_event_store_with_filter(data->dev, &rawir);
-       }
+               rawir.duration = US_TO_NS(duration);
 
-       /* Check if we should go idle */
-       if (data->dev->idle) {
-               led_trigger_event(data->rxtrigger, LED_OFF);
-               data->rxstate = WBCIR_RXSTATE_INACTIVE;
+               if (rawir.pulse)
+                       data->pulse_duration += duration;
+
+               ir_raw_event_store_with_filter(data->dev, &rawir);
        }
 
        ir_raw_event_handle(data->dev);
@@ -491,6 +529,33 @@ wbcir_irq_handler(int irqno, void *cookie)
  *
  *****************************************************************************/
 
+static int
+wbcir_set_carrier_report(struct rc_dev *dev, int enable)
+{
+       struct wbcir_data *data = dev->priv;
+       unsigned long flags;
+
+       spin_lock_irqsave(&data->spinlock, flags);
+
+       if (data->carrier_report_enabled == enable) {
+               spin_unlock_irqrestore(&data->spinlock, flags);
+               return 0;
+       }
+
+       data->pulse_duration = 0;
+       wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL, WBCIR_CNTR_R,
+                                               WBCIR_CNTR_EN | WBCIR_CNTR_R);
+
+       if (enable && data->dev->idle)
+               wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CCTL,
+                               WBCIR_CNTR_EN, WBCIR_CNTR_EN | WBCIR_CNTR_R);
+
+       data->carrier_report_enabled = enable;
+       spin_unlock_irqrestore(&data->spinlock, flags);
+
+       return 0;
+}
+
 static int
 wbcir_txcarrier(struct rc_dev *dev, u32 carrier)
 {
@@ -837,7 +902,7 @@ wbcir_init_hw(struct wbcir_data *data)
 
        /* Set IRTX_INV */
        if (invert)
-               outb(0x04, data->ebase + WBCIR_REG_ECEIR_CCTL);
+               outb(WBCIR_IRTX_INV, data->ebase + WBCIR_REG_ECEIR_CCTL);
        else
                outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL);
 
@@ -866,8 +931,8 @@ wbcir_init_hw(struct wbcir_data *data)
        /* prescaler 1.0, tx/rx fifo lvl 16 */
        outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
 
-       /* Set baud divisor to sample every 10 us */
-       outb(0x0F, data->sbase + WBCIR_REG_SP3_BGDL);
+       /* Set baud divisor to sample every 2 ns */
+       outb(0x03, data->sbase + WBCIR_REG_SP3_BGDL);
        outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
 
        /* Set CEIR mode */
@@ -876,9 +941,12 @@ wbcir_init_hw(struct wbcir_data *data)
        inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
        inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
 
-       /* Disable RX demod, enable run-length enc/dec, set freq span */
+       /*
+        * Disable RX demod, enable run-length enc/dec, set freq span and
+        * enable over-sampling
+        */
        wbcir_select_bank(data, WBCIR_BANK_7);
-       outb(0x90, data->sbase + WBCIR_REG_SP3_RCCFG);
+       outb(0xd0, data->sbase + WBCIR_REG_SP3_RCCFG);
 
        /* Disable timer */
        wbcir_select_bank(data, WBCIR_BANK_4);
@@ -915,9 +983,8 @@ wbcir_init_hw(struct wbcir_data *data)
 
        /* Clear RX state */
        data->rxstate = WBCIR_RXSTATE_INACTIVE;
-       data->rxev.duration = 0;
        ir_raw_event_reset(data->dev);
-       ir_raw_event_handle(data->dev);
+       ir_raw_event_set_idle(data->dev, true);
 
        /* Clear TX state */
        if (data->txstate == WBCIR_TXSTATE_ACTIVE) {
@@ -1007,7 +1074,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
        }
 
        data->dev->driver_type = RC_DRIVER_IR_RAW;
-       data->dev->driver_name = WBCIR_NAME;
+       data->dev->driver_name = DRVNAME;
        data->dev->input_name = WBCIR_NAME;
        data->dev->input_phys = "wbcir/cir0";
        data->dev->input_id.bustype = BUS_HOST;
@@ -1016,13 +1083,15 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
        data->dev->input_id.version = WBCIR_ID_CHIP;
        data->dev->map_name = RC_MAP_RC6_MCE;
        data->dev->s_idle = wbcir_idle_rx;
+       data->dev->s_carrier_report = wbcir_set_carrier_report;
        data->dev->s_tx_mask = wbcir_txmask;
        data->dev->s_tx_carrier = wbcir_txcarrier;
        data->dev->tx_ir = wbcir_tx;
        data->dev->priv = data;
        data->dev->dev.parent = &device->dev;
        data->dev->timeout = MS_TO_NS(100);
-       data->dev->allowed_protos = RC_TYPE_ALL;
+       data->dev->rx_resolution = US_TO_NS(2);
+       data->dev->allowed_protos = RC_BIT_ALL;
 
        if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) {
                dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
index aff39ae457a0d1c469ea8ff1e9a4e81136347a17..81f38aae9c66f6ba2893eb1ff5ea7f6c092be96d 100644 (file)
@@ -35,8 +35,6 @@
  * Currently it blind writes bunch of static registers from the
  * fc2580_freq_regs_lut[] when fc2580_set_params() is called. Add some
  * logic to reduce unneeded register writes.
- * There is also don't-care registers, initialized with value 0xff, and those
- * are also written to the chip currently (yes, not wise).
  */
 
 /* write multiple registers */
@@ -111,6 +109,17 @@ static int fc2580_rd_reg(struct fc2580_priv *priv, u8 reg, u8 *val)
        return fc2580_rd_regs(priv, reg, val, 1);
 }
 
+/* write single register conditionally only when value differs from 0xff
+ * XXX: This is special routine meant only for writing fc2580_freq_regs_lut[]
+ * values. Do not use for the other purposes. */
+static int fc2580_wr_reg_ff(struct fc2580_priv *priv, u8 reg, u8 val)
+{
+       if (val == 0xff)
+               return 0;
+       else
+               return fc2580_wr_regs(priv, reg, &val, 1);
+}
+
 static int fc2580_set_params(struct dvb_frontend *fe)
 {
        struct fc2580_priv *priv = fe->tuner_priv;
@@ -213,99 +222,99 @@ static int fc2580_set_params(struct dvb_frontend *fe)
        if (i == ARRAY_SIZE(fc2580_freq_regs_lut))
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x25, fc2580_freq_regs_lut[i].r25_val);
+       ret = fc2580_wr_reg_ff(priv, 0x25, fc2580_freq_regs_lut[i].r25_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x27, fc2580_freq_regs_lut[i].r27_val);
+       ret = fc2580_wr_reg_ff(priv, 0x27, fc2580_freq_regs_lut[i].r27_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x28, fc2580_freq_regs_lut[i].r28_val);
+       ret = fc2580_wr_reg_ff(priv, 0x28, fc2580_freq_regs_lut[i].r28_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x29, fc2580_freq_regs_lut[i].r29_val);
+       ret = fc2580_wr_reg_ff(priv, 0x29, fc2580_freq_regs_lut[i].r29_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x2b, fc2580_freq_regs_lut[i].r2b_val);
+       ret = fc2580_wr_reg_ff(priv, 0x2b, fc2580_freq_regs_lut[i].r2b_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x2c, fc2580_freq_regs_lut[i].r2c_val);
+       ret = fc2580_wr_reg_ff(priv, 0x2c, fc2580_freq_regs_lut[i].r2c_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x2d, fc2580_freq_regs_lut[i].r2d_val);
+       ret = fc2580_wr_reg_ff(priv, 0x2d, fc2580_freq_regs_lut[i].r2d_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x30, fc2580_freq_regs_lut[i].r30_val);
+       ret = fc2580_wr_reg_ff(priv, 0x30, fc2580_freq_regs_lut[i].r30_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x44, fc2580_freq_regs_lut[i].r44_val);
+       ret = fc2580_wr_reg_ff(priv, 0x44, fc2580_freq_regs_lut[i].r44_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x50, fc2580_freq_regs_lut[i].r50_val);
+       ret = fc2580_wr_reg_ff(priv, 0x50, fc2580_freq_regs_lut[i].r50_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x53, fc2580_freq_regs_lut[i].r53_val);
+       ret = fc2580_wr_reg_ff(priv, 0x53, fc2580_freq_regs_lut[i].r53_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x5f, fc2580_freq_regs_lut[i].r5f_val);
+       ret = fc2580_wr_reg_ff(priv, 0x5f, fc2580_freq_regs_lut[i].r5f_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x61, fc2580_freq_regs_lut[i].r61_val);
+       ret = fc2580_wr_reg_ff(priv, 0x61, fc2580_freq_regs_lut[i].r61_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x62, fc2580_freq_regs_lut[i].r62_val);
+       ret = fc2580_wr_reg_ff(priv, 0x62, fc2580_freq_regs_lut[i].r62_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x63, fc2580_freq_regs_lut[i].r63_val);
+       ret = fc2580_wr_reg_ff(priv, 0x63, fc2580_freq_regs_lut[i].r63_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x67, fc2580_freq_regs_lut[i].r67_val);
+       ret = fc2580_wr_reg_ff(priv, 0x67, fc2580_freq_regs_lut[i].r67_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x68, fc2580_freq_regs_lut[i].r68_val);
+       ret = fc2580_wr_reg_ff(priv, 0x68, fc2580_freq_regs_lut[i].r68_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x69, fc2580_freq_regs_lut[i].r69_val);
+       ret = fc2580_wr_reg_ff(priv, 0x69, fc2580_freq_regs_lut[i].r69_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x6a, fc2580_freq_regs_lut[i].r6a_val);
+       ret = fc2580_wr_reg_ff(priv, 0x6a, fc2580_freq_regs_lut[i].r6a_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x6b, fc2580_freq_regs_lut[i].r6b_val);
+       ret = fc2580_wr_reg_ff(priv, 0x6b, fc2580_freq_regs_lut[i].r6b_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x6c, fc2580_freq_regs_lut[i].r6c_val);
+       ret = fc2580_wr_reg_ff(priv, 0x6c, fc2580_freq_regs_lut[i].r6c_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x6d, fc2580_freq_regs_lut[i].r6d_val);
+       ret = fc2580_wr_reg_ff(priv, 0x6d, fc2580_freq_regs_lut[i].r6d_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x6e, fc2580_freq_regs_lut[i].r6e_val);
+       ret = fc2580_wr_reg_ff(priv, 0x6e, fc2580_freq_regs_lut[i].r6e_val);
        if (ret < 0)
                goto err;
 
-       ret = fc2580_wr_reg(priv, 0x6f, fc2580_freq_regs_lut[i].r6f_val);
+       ret = fc2580_wr_reg_ff(priv, 0x6f, fc2580_freq_regs_lut[i].r6f_val);
        if (ret < 0)
                goto err;
 
index ba84936aafd6f8bda6e043d7328fa81fd39a6f52..95ed46f2cd2600b036f1ac2299757e0b616a3da1 100644 (file)
@@ -161,7 +161,7 @@ static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
        return 0;
 }
 
-int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
+static int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
 {
        u32 remainder;
        u32 q, f = 0;
index 389668474070cb045ceeabbf67c856a0d6980126..83a6240f64d3d17b1a486bb7dbddac50864ee490 100644 (file)
@@ -136,7 +136,7 @@ static int tua9001_set_params(struct dvb_frontend *fe)
 {
        struct tua9001_priv *priv = fe->tuner_priv;
        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i;
+       int ret = 0, i;
        u16 val;
        u32 frequency;
        struct reg_val data[2];
index 4937712278f67757ba114a0f5bfbc9227fc00ab6..5c0fd787cc8f3035e8ab60954ba5a9a5bc8585e2 100644 (file)
@@ -934,7 +934,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
        int                        rc = 0, is_retry = 0;
        u16                        hwmodel;
        v4l2_std_id                std0;
-       u8                         hw_major, hw_minor, fw_major, fw_minor;
+       u8                         hw_major = 0, hw_minor = 0, fw_major = 0, fw_minor = 0;
 
        dprintk(1, "%s called\n", __func__);
 
index 448361c6a13eea6e74adefab2ec9d50d448fe7a3..0cb7c28dcb1787e661fffe919ab6851e4a939c6a 100644 (file)
@@ -25,7 +25,7 @@
 #include "media/tuner.h"
 #include "media/v4l2-common.h"
 
-void hvr950q_cs5340_audio(void *priv, int enable)
+static void hvr950q_cs5340_audio(void *priv, int enable)
 {
        /* Because the HVR-950q shares an i2s bus between the cs5340 and the
           au8522, we need to hold cs5340 in reset when using the au8522 */
index b328f6550d0b28714ff7339e08844e5491c8b407..9a6f15613a3832d7c17754938098ed7f815458aa 100644 (file)
@@ -272,7 +272,6 @@ static void au0828_restart_dvb_streaming(struct work_struct *work)
        struct au0828_dev *dev = container_of(work, struct au0828_dev,
                                              restart_streaming);
        struct au0828_dvb *dvb = &dev->dvb;
-       int ret;
 
        if (dev->urb_streaming == 0)
                return;
@@ -282,7 +281,7 @@ static void au0828_restart_dvb_streaming(struct work_struct *work)
        mutex_lock(&dvb->lock);
 
        /* Stop transport */
-       ret = stop_urb_transfer(dev);
+       stop_urb_transfer(dev);
        au0828_write(dev, 0x608, 0x00);
        au0828_write(dev, 0x609, 0x00);
        au0828_write(dev, 0x60a, 0x00);
@@ -293,7 +292,7 @@ static void au0828_restart_dvb_streaming(struct work_struct *work)
        au0828_write(dev, 0x609, 0x72);
        au0828_write(dev, 0x60a, 0x71);
        au0828_write(dev, 0x60b, 0x01);
-       ret = start_urb_transfer(dev);
+       start_urb_transfer(dev);
 
        mutex_unlock(&dvb->lock);
 }
index 87058557057133f9d209e842c60f000e02f93fba..45387aab10c7ca5633c66c8616c4beb978039594 100644 (file)
@@ -158,7 +158,7 @@ static void au0828_irq_callback(struct urb *urb)
 /*
  * Stop and Deallocate URBs
  */
-void au0828_uninit_isoc(struct au0828_dev *dev)
+static void au0828_uninit_isoc(struct au0828_dev *dev)
 {
        struct urb *urb;
        int i;
@@ -197,9 +197,9 @@ void au0828_uninit_isoc(struct au0828_dev *dev)
 /*
  * Allocate URBs and start IRQ
  */
-int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
-                    int num_bufs, int max_pkt_size,
-                    int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
+static int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
+                           int num_bufs, int max_pkt_size,
+                           int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
 {
        struct au0828_dmaqueue *dma_q = &dev->vidq;
        int i;
@@ -783,7 +783,7 @@ static int au0828_i2s_init(struct au0828_dev *dev)
  * Auvitek au0828 analog stream enable
  * Please set interface0 to AS5 before enable the stream
  */
-int au0828_analog_stream_enable(struct au0828_dev *d)
+static int au0828_analog_stream_enable(struct au0828_dev *d)
 {
        dprintk(1, "au0828_analog_stream_enable called\n");
        au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
@@ -810,7 +810,7 @@ int au0828_analog_stream_disable(struct au0828_dev *d)
        return 0;
 }
 
-void au0828_analog_stream_reset(struct au0828_dev *dev)
+static void au0828_analog_stream_reset(struct au0828_dev *dev)
 {
        dprintk(1, "au0828_analog_stream_reset called\n");
        au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
@@ -913,7 +913,7 @@ static int get_ressource(struct au0828_fh *fh)
 /* This function ensures that video frames continue to be delivered even if
    the ITU-656 input isn't receiving any data (thereby preventing applications
    such as tvtime from hanging) */
-void au0828_vid_buffer_timeout(unsigned long data)
+static void au0828_vid_buffer_timeout(unsigned long data)
 {
        struct au0828_dev *dev = (struct au0828_dev *) data;
        struct au0828_dmaqueue *dma_q = &dev->vidq;
@@ -937,7 +937,7 @@ void au0828_vid_buffer_timeout(unsigned long data)
        spin_unlock_irqrestore(&dev->slock, flags);
 }
 
-void au0828_vbi_buffer_timeout(unsigned long data)
+static void au0828_vbi_buffer_timeout(unsigned long data)
 {
        struct au0828_dev *dev = (struct au0828_dev *) data;
        struct au0828_dmaqueue *dma_q = &dev->vbiq;
index 447148eff9588658f954ba5e3d90cdbe6c1fbc76..7222079137406313589bb4119ca5e01b6fe1946f 100644 (file)
@@ -1068,12 +1068,12 @@ int cx231xx_unmute_audio(struct cx231xx *dev)
 }
 EXPORT_SYMBOL_GPL(cx231xx_unmute_audio);
 
-int stopAudioFirmware(struct cx231xx *dev)
+static int stopAudioFirmware(struct cx231xx *dev)
 {
        return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x03);
 }
 
-int restartAudioFirmware(struct cx231xx *dev)
+static int restartAudioFirmware(struct cx231xx *dev)
 {
        return vid_blk_write_byte(dev, DL_CTL_CONTROL, 0x13);
 }
@@ -2631,11 +2631,6 @@ int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
                        rc = cx231xx_stop_stream(dev, ep_mask);
        }
 
-       if (dev->mode == CX231XX_ANALOG_MODE)
-               ;/* do any in Analog mode */
-       else
-               ;/* do any in digital mode */
-
        return rc;
 }
 EXPORT_SYMBOL_GPL(cx231xx_capture_start);
index b84ebc54d91bce2279e1f1f7b8a8b09d4d0ff12d..bbed1e40eeda6cab07fb712d20c4414094760238 100644 (file)
@@ -686,7 +686,7 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg)
 }
 EXPORT_SYMBOL_GPL(cx231xx_tuner_callback);
 
-void cx231xx_reset_out(struct cx231xx *dev)
+static void cx231xx_reset_out(struct cx231xx *dev)
 {
        cx231xx_set_gpio_value(dev, CX23417_RESET, 1);
        msleep(200);
@@ -694,11 +694,13 @@ void cx231xx_reset_out(struct cx231xx *dev)
        msleep(200);
        cx231xx_set_gpio_value(dev, CX23417_RESET, 1);
 }
-void cx231xx_enable_OSC(struct cx231xx *dev)
+
+static void cx231xx_enable_OSC(struct cx231xx *dev)
 {
        cx231xx_set_gpio_value(dev, CX23417_OSC_EN, 1);
 }
-void cx231xx_sleep_s5h1432(struct cx231xx *dev)
+
+static void cx231xx_sleep_s5h1432(struct cx231xx *dev)
 {
        cx231xx_set_gpio_value(dev, SLEEP_S5H1432, 0);
 }
index 781feed406f72747bb510cb8e4f2eed70afadd77..96a5a09653994657df3c9602559a3e3102aa9e3a 100644 (file)
@@ -72,8 +72,8 @@ static inline bool is_tuner(struct cx231xx *dev, struct cx231xx_i2c *bus,
 /*
  * cx231xx_i2c_send_bytes()
  */
-int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
-                          const struct i2c_msg *msg)
+static int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
+                                 const struct i2c_msg *msg)
 {
        struct cx231xx_i2c *bus = i2c_adap->algo_data;
        struct cx231xx *dev = bus->dev;
index 96176e9db5a28faa01086e1aca1c364b401efe15..0f7b42446826b5922a2deea2b9ebb6a5f1ffbd79 100644 (file)
@@ -99,7 +99,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
        /* The i2c micro-controller only outputs the cmd part of NEC protocol */
        dev->init_data.rc_dev->scanmask = 0xff;
        dev->init_data.rc_dev->driver_name = "cx231xx";
-       dev->init_data.type = RC_TYPE_NEC;
+       dev->init_data.type = RC_BIT_NEC;
        info.addr = 0x30;
 
        /* Load and bind ir-kbd-i2c */
index 3d7526e28d426f8ca119f4d3b1326abd469b7622..943d93423705a0e1c5d404db966219ff528ebb15 100644 (file)
@@ -1306,7 +1306,7 @@ static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
        if (!rc->map_name)
                rc->map_name = RC_MAP_EMPTY;
 
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query = af9015_rc_query;
        rc->interval = 500;
 
index ea27eaff4e34fdc77d9739d82b4620698a58fca7..61ae7f9d0b27329b5cd493f70be4bb6855fde0b8 100644 (file)
@@ -1023,10 +1023,10 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
                switch (tmp) {
                case 0: /* NEC */
                default:
-                       rc->allowed_protos = RC_TYPE_NEC;
+                       rc->allowed_protos = RC_BIT_NEC;
                        break;
                case 1: /* RC6 */
-                       rc->allowed_protos = RC_TYPE_RC6;
+                       rc->allowed_protos = RC_BIT_RC6_MCE;
                        break;
                }
 
index ec540140c81037ffb0317a3d726fbd30e58fa94e..d05c5b563dac69485af3ea1ca4b219c39c08e990 100644 (file)
@@ -1048,7 +1048,7 @@ static int anysee_rc_query(struct dvb_usb_device *d)
 
 static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
 {
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query          = anysee_rc_query;
        rc->interval       = 250;  /* windows driver uses 500ms */
 
@@ -1170,7 +1170,7 @@ static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
        struct dvb_usb_device *d = ci->data;
        struct anysee_state *state = d_to_priv(d);
        int ret;
-       u8 tmp;
+       u8 tmp = 0;
 
        ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
        if (ret)
index 54f1221d930df3c5eb0d554c4d56da63cc06583d..d75dbf27e99e21b5ef4065c41f466b3b1645c57d 100644 (file)
@@ -826,7 +826,7 @@ static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
 {
        pr_debug("Getting az6007 Remote Control properties\n");
 
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query          = az6007_rc_query;
        rc->interval       = 400;
 
index bae16a1189d66deed84242f0c7fd26be398f77b7..059291b892b81c2e250da9e7b2ea64266db95f0c 100644 (file)
@@ -137,7 +137,7 @@ struct dvb_usb_driver_info {
 struct dvb_usb_rc {
        const char *map_name;
        u64 allowed_protos;
-       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
        int (*query) (struct dvb_usb_device *d);
        unsigned int interval;
        const enum rc_driver_type driver_type;
index ba51f65204de833cb9965f5f0764f85c8ce9166e..671b4fa232b4a9f9e74fdc1d59f55f99d16c518b 100644 (file)
@@ -224,7 +224,7 @@ static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
        dvb_dmx_swfilter_raw(&adap->demux, buf, len);
 }
 
-int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
+static int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
 {
        dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
                        adap->id);
@@ -236,7 +236,7 @@ int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
        return usb_urb_initv2(&adap->stream, &adap->props->stream);
 }
 
-int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
+static int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
 {
        dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
                        adap->id);
@@ -368,7 +368,7 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
        return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
 }
 
-int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
+static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
 {
        int ret;
        struct dvb_usb_device *d = adap_to_d(adap);
@@ -440,7 +440,7 @@ err_dvb_register_adapter:
        return ret;
 }
 
-int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
+static int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
 {
        dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
                        adap->id);
@@ -456,7 +456,7 @@ int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
        return 0;
 }
 
-int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff)
+static int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
        int ret;
 
@@ -553,7 +553,7 @@ err:
        return ret;
 }
 
-int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
+static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
 {
        int ret, i, count_registered = 0;
        struct dvb_usb_device *d = adap_to_d(adap);
@@ -622,7 +622,7 @@ err:
        return ret;
 }
 
-int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
+static int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
 {
        int i;
        dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
index 695f9106bc54c1b8b55028d9b1d1c458386928f3..47204280b8b3d1f5b557417a27d32430bccb2c21 100644 (file)
@@ -659,13 +659,19 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
                it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x1);
                it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x0f);
                it913x_wr_reg(d, DEV_0, EP0_TX_NAK, 0x1b);
-               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x2f);
+               if (st->proprietary_ir == false) /* Enable endpoint 3 */
+                       it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x3f);
+               else
+                       it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x2f);
                it913x_wr_reg(d, DEV_0, EP4_TX_LEN_LSB,
                                        ep_size & 0xff);
                it913x_wr_reg(d, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8);
                ret = it913x_wr_reg(d, DEV_0, EP4_MAX_PKT, pkt_size);
        } else if (adap->id == 1 && adap->fe[0]) {
-               it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x6f);
+               if (st->proprietary_ir == false)
+                       it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x7f);
+               else
+                       it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x6f);
                it913x_wr_reg(d, DEV_0, EP5_TX_LEN_LSB,
                                        ep_size & 0xff);
                it913x_wr_reg(d, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8);
@@ -698,7 +704,7 @@ static int it913x_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
                return 0;
        }
 
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query = it913x_rc_query;
        rc->interval = 250;
 
index c41d9d9ec7b54df963ede5ad9deb6d9534e50620..6427ac359f21abda6447a38471c1c560d511dec0 100644 (file)
@@ -799,7 +799,7 @@ static const char fw_c_rs2000[] = LME2510_C_RS2000;
 static const char fw_lg[] = LME2510_LG;
 static const char fw_s0194[] = LME2510_S0194;
 
-const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
+static const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
 {
        struct lme2510_state *st = d->priv;
        struct usb_device *udev = d->udev;
@@ -1253,7 +1253,7 @@ static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
 static int lme2510_get_rc_config(struct dvb_usb_device *d,
        struct dvb_usb_rc *rc)
 {
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        return 0;
 }
 
index 093f1acce403e7fa35ddea58914dd386ee32f426..a4c302d0aa37011472e3dbc047b2041d4ddf8eb3 100644 (file)
@@ -1197,7 +1197,7 @@ static int rtl2831u_get_rc_config(struct dvb_usb_device *d,
                struct dvb_usb_rc *rc)
 {
        rc->map_name = RC_MAP_EMPTY;
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query = rtl2831u_rc_query;
        rc->interval = 400;
 
@@ -1269,7 +1269,7 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
                struct dvb_usb_rc *rc)
 {
        rc->map_name = RC_MAP_EMPTY;
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query = rtl2832u_rc_query;
        rc->interval = 400;
 
@@ -1338,6 +1338,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
                &rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) },
        { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK,
                &rtl2832u_props, "NOXON DAB/DAB+ USB dongle", NULL) },
+       { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK_REV2,
+               &rtl2832u_props, "NOXON DAB/DAB+ USB dongle (rev 2)", NULL) },
        { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TREKSTOR_TERRES_2_0,
                &rtl2832u_props, "Trekstor DVB-T Stick Terres 2.0", NULL) },
        { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1101,
index 5989b65903779b08bb70c54251bf186ed47846c4..7346f85f3f2f161cc101605bf88e02883b2c6df6 100644 (file)
@@ -112,7 +112,7 @@ int usb_urb_submitv2(struct usb_data_stream *stream,
        return 0;
 }
 
-int usb_urb_free_urbs(struct usb_data_stream *stream)
+static int usb_urb_free_urbs(struct usb_data_stream *stream)
 {
        int i;
 
@@ -205,7 +205,7 @@ static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
        return 0;
 }
 
-int usb_free_stream_buffers(struct usb_data_stream *stream)
+static int usb_free_stream_buffers(struct usb_data_stream *stream)
 {
        if (stream->state & USB_STATE_URB_BUF) {
                while (stream->buf_num) {
@@ -223,8 +223,8 @@ int usb_free_stream_buffers(struct usb_data_stream *stream)
        return 0;
 }
 
-int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
-               unsigned long size)
+static int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
+                                   unsigned long size)
 {
        stream->buf_num = 0;
        stream->buf_size = size;
index 5e45ae6054275139da2299adf7925440ed14eb73..91e0119e8a8702908badd7aecb8c14738f0a4719 100644 (file)
@@ -298,7 +298,8 @@ struct stb6100_config az6027_stb6100_config = {
 
 
 /* check for mutex FIXME */
-int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+static int az6027_usb_in_op(struct dvb_usb_device *d, u8 req,
+                           u16 value, u16 index, u8 *b, int blen)
 {
        int ret = -1;
        if (mutex_lock_interruptible(&d->usb_mutex))
@@ -1051,10 +1052,10 @@ static struct i2c_algorithm az6027_i2c_algo = {
        .functionality = az6027_i2c_func,
 };
 
-int az6027_identify_state(struct usb_device *udev,
-                         struct dvb_usb_device_properties *props,
-                         struct dvb_usb_device_description **desc,
-                         int *cold)
+static int az6027_identify_state(struct usb_device *udev,
+                                struct dvb_usb_device_properties *props,
+                                struct dvb_usb_device_description **desc,
+                                int *cold)
 {
        u8 *b;
        s16 ret;
index 7de125c0b36f4576f951ea8e90a87d7c308f0857..637b6123f391e9bce0fce074314e270e4e9e9238 100644 (file)
@@ -64,7 +64,7 @@ extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
 extern struct i2c_algorithm dib0700_i2c_algo;
 extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
                        struct dvb_usb_device_description **desc, int *cold);
-extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
+extern int dib0700_change_protocol(struct rc_dev *dev, u64 *rc_type);
 extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
 
 extern int dib0700_device_count;
index ef87229de6af5d791060b00cd82188bcebbc8c20..19b5ed2825d719d656066b26af8aea2250151960 100644 (file)
@@ -605,7 +605,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
        return ret;
 }
 
-int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
+int dib0700_change_protocol(struct rc_dev *rc, u64 *rc_type)
 {
        struct dvb_usb_device *d = rc->priv;
        struct dib0700_state *st = d->priv;
@@ -621,17 +621,19 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
        st->buf[2] = 0;
 
        /* Set the IR mode */
-       if (rc_type == RC_TYPE_RC5)
+       if (*rc_type & RC_BIT_RC5) {
                new_proto = 1;
-       else if (rc_type == RC_TYPE_NEC)
+               *rc_type = RC_BIT_RC5;
+       } else if (*rc_type & RC_BIT_NEC) {
                new_proto = 0;
-       else if (rc_type == RC_TYPE_RC6) {
+               *rc_type = RC_BIT_NEC;
+       } else if (*rc_type & RC_BIT_RC6_MCE) {
                if (st->fw_version < 0x10200) {
                        ret = -EINVAL;
                        goto out;
                }
-
                new_proto = 2;
+               *rc_type = RC_BIT_RC6_MCE;
        } else {
                ret = -EINVAL;
                goto out;
@@ -645,7 +647,7 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
                goto out;
        }
 
-       d->props.rc.core.protocol = rc_type;
+       d->props.rc.core.protocol = *rc_type;
 
 out:
        mutex_unlock(&d->usb_mutex);
@@ -707,7 +709,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
                 purb->actual_length);
 
        switch (d->props.rc.core.protocol) {
-       case RC_TYPE_NEC:
+       case RC_BIT_NEC:
                toggle = 0;
 
                /* NEC protocol sends repeat code as 0 0 0 FF */
index 510001da6e836a0c1e6ca0bdc492fa1532e63ccc..11798426fa88505d3202a59e6e0b74992afd3698 100644 (file)
@@ -518,7 +518,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
 
        d->last_event = 0;
        switch (d->props.rc.core.protocol) {
-       case RC_TYPE_NEC:
+       case RC_BIT_NEC:
                /* NEC protocol sends repeat code as 0 0 0 FF */
                if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
                    (key[3] == 0xff))
@@ -3658,9 +3658,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_interval      = DEFAULT_RC_INTERVAL,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -3698,9 +3698,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_interval      = DEFAULT_RC_INTERVAL,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -3763,9 +3763,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_interval      = DEFAULT_RC_INTERVAL,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -3808,9 +3808,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -3890,9 +3890,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -3936,9 +3936,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -3987,9 +3987,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4055,9 +4055,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4106,9 +4106,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_NEC_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4177,9 +4177,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4215,9 +4215,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4295,9 +4295,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4341,9 +4341,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_NEC_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4394,9 +4394,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4433,9 +4433,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4472,9 +4472,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4511,9 +4511,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4550,9 +4550,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4589,9 +4589,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4644,9 +4644,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4681,9 +4681,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4721,9 +4721,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4761,9 +4761,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@@ -4802,9 +4802,9 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        },
index aab0f99bc892bc764530e9966b87561eede5974f..ce4c4e3b58bb7516f9bdff338d1b6b8ed2d0332e 100644 (file)
@@ -202,7 +202,7 @@ struct dvb_rc {
        u64 protocol;
        u64 allowed_protos;
        enum rc_driver_type driver_type;
-       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
        char *module_name;
        int (*rc_query) (struct dvb_usb_device *d);
        int rc_interval;
index 02e878577c3dcb33f2cb18f0cfe9b6361a73b452..d1ddfa13de86d8a474796e0af2da49bdcb8eaa78 100644 (file)
@@ -927,7 +927,7 @@ static struct dvb_usb_device_properties pctv452e_properties = {
 
        .rc.core = {
                .rc_codes       = RC_MAP_DIB0700_RC5_TABLE,
-               .allowed_protos = RC_TYPE_UNKNOWN,
+               .allowed_protos = RC_BIT_UNKNOWN,
                .rc_query       = pctv452e_rc_query,
                .rc_interval    = 100,
        },
@@ -980,7 +980,7 @@ static struct dvb_usb_device_properties tt_connect_s2_3600_properties = {
 
        .rc.core = {
                .rc_codes       = RC_MAP_TT_1500,
-               .allowed_protos = RC_TYPE_UNKNOWN,
+               .allowed_protos = RC_BIT_UNKNOWN,
                .rc_query       = pctv452e_rc_query,
                .rc_interval    = 100,
        },
index 7a8c8c18590fdcb16c561cff57ea6d2abc6f875e..40832a1aef6c71c0df2eaf51ffdea327bafe18da 100644 (file)
@@ -732,7 +732,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = {
                .rc_codes    = RC_MAP_TECHNISAT_USB2,
                .module_name = "technisat-usb2",
                .rc_query    = technisat_usb2_rc_query,
-               .allowed_protos = RC_TYPE_ALL,
+               .allowed_protos = RC_BIT_ALL,
                .driver_type    = RC_DRIVER_IR_RAW,
        }
 };
index 6a50cdea3bcee539a79ccecd9a211c13309b803d..bcdac225ebe10a2cd3c67c8496fdddb92fe9d5f2 100644 (file)
@@ -741,7 +741,7 @@ static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
                .rc_interval      = 150, /* Less than IR_KEYPRESS_TIMEOUT */
                .rc_codes         = RC_MAP_TT_1500,
                .rc_query         = tt3650_rc_query,
-               .allowed_protos   = RC_TYPE_UNKNOWN,
+               .allowed_protos   = RC_BIT_UNKNOWN,
        },
 
        .num_adapters = 1,
index 07c673a6e7643068cb49c8ab3f01e9b299b2b060..22cf9f96cb9e68098476d06b0018d6f7baf868be 100644 (file)
@@ -56,7 +56,7 @@ static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
 }
 
 int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
-                           u16 index, u8 *b, int blen)
+                    u16 index, u8 *b, int blen)
 {
        int ret;
 
@@ -67,8 +67,8 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
        return ret;
 }
 
-int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
-                                     u16 index, u8 *b, int blen)
+static int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req,
+                                     u16 value, u16 index, u8 *b, int blen)
 {
        int ret;
        deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
@@ -86,7 +86,7 @@ int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
                return 0;
 }
 
-int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
                             u16 index, u8 *b, int blen)
 {
        int ret;
index 16a84f9f46d8421e9c902a2b9886a950f1e6bc4d..619bffbab3bc050f2cb2f1f1929bd5da1bdd91a8 100644 (file)
@@ -1979,6 +1979,15 @@ struct em28xx_board em28xx_boards[] = {
                                EM28XX_I2C_CLK_WAIT_ENABLE |
                                EM28XX_I2C_FREQ_400_KHZ,
        },
+       [EM2884_BOARD_TERRATEC_HTC_USB_XS] = {
+               .name         = "Terratec Cinergy HTC USB XS",
+               .has_dvb      = 1,
+               .ir_codes     = RC_MAP_NEC_TERRATEC_CINERGY_XS,
+               .tuner_type   = TUNER_ABSENT,
+               .i2c_speed    = EM2874_I2C_SECONDARY_BUS_SELECT |
+                               EM28XX_I2C_CLK_WAIT_ENABLE |
+                               EM28XX_I2C_FREQ_400_KHZ,
+       },
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -2057,9 +2066,9 @@ struct usb_device_id em28xx_id_table[] = {
        { USB_DEVICE(0x0ccd, 0x0043),
                        .driver_info = EM2870_BOARD_TERRATEC_XS },
        { USB_DEVICE(0x0ccd, 0x008e),   /* Cinergy HTC USB XS Rev. 1 */
-                       .driver_info = EM2884_BOARD_TERRATEC_H5 },
+                       .driver_info = EM2884_BOARD_TERRATEC_HTC_USB_XS },
        { USB_DEVICE(0x0ccd, 0x00ac),   /* Cinergy HTC USB XS Rev. 2 */
-                       .driver_info = EM2884_BOARD_TERRATEC_H5 },
+                       .driver_info = EM2884_BOARD_TERRATEC_HTC_USB_XS },
        { USB_DEVICE(0x0ccd, 0x10a2),   /* H5 Rev. 1 */
                        .driver_info = EM2884_BOARD_TERRATEC_H5 },
        { USB_DEVICE(0x0ccd, 0x10ad),   /* H5 Rev. 2 */
@@ -3297,7 +3306,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
 
        dev->num_alt = interface->num_altsetting;
 
-       if ((card[nr] >= 0) && (card[nr] < em28xx_bcount))
+       if ((unsigned)card[nr] < em28xx_bcount)
                dev->model = card[nr];
 
        /* save our data pointer in this interface device */
index 13ae821949e9f5f3007aaf77554e63e1551cc28e..63f2e7070c005d8ed05af171bd1d80c6006295f4 100644 (file)
@@ -331,7 +331,7 @@ static struct drxk_config hauppauge_930c_drxk = {
        .load_firmware_sync = true,
 };
 
-struct drxk_config terratec_htc_stick_drxk = {
+static struct drxk_config terratec_htc_stick_drxk = {
        .adr = 0x29,
        .single_master = 1,
        .no_i2c_bridge = 1,
@@ -520,7 +520,10 @@ static void terratec_htc_stick_init(struct em28xx *dev)
                { -1,                   -1,     -1,     -1},
        };
 
-       /* Init the analog decoder? */
+       /*
+        * Init the analog decoder (not yet supported), but
+        * it's probably still a good idea.
+        */
        struct {
                unsigned char r[4];
                int len;
@@ -547,6 +550,64 @@ static void terratec_htc_stick_init(struct em28xx *dev)
        em28xx_gpio_set(dev, terratec_htc_stick_end);
 };
 
+static void terratec_htc_usb_xs_init(struct em28xx *dev)
+{
+       int i;
+
+       struct em28xx_reg_seq terratec_htc_usb_xs_init[] = {
+               {EM28XX_R08_GPIO,       0xff,   0xff,   10},
+               {EM2874_R80_GPIO,       0xb2,   0xff,   100},
+               {EM2874_R80_GPIO,       0xb2,   0xff,   50},
+               {EM2874_R80_GPIO,       0xb6,   0xff,   100},
+               { -1,                   -1,     -1,     -1},
+       };
+       struct em28xx_reg_seq terratec_htc_usb_xs_end[] = {
+               {EM2874_R80_GPIO,       0xa6,   0xff,   100},
+               {EM2874_R80_GPIO,       0xa6,   0xff,   50},
+               {EM2874_R80_GPIO,       0xe6,   0xff,   100},
+               { -1,                   -1,     -1,     -1},
+       };
+
+       /*
+        * Init the analog decoder (not yet supported), but
+        * it's probably still a good idea.
+        */
+       struct {
+               unsigned char r[4];
+               int len;
+       } regs[] = {
+               {{ 0x06, 0x02, 0x00, 0x31 }, 4},
+               {{ 0x01, 0x02 }, 2},
+               {{ 0x01, 0x02, 0x00, 0xc6 }, 4},
+               {{ 0x01, 0x00 }, 2},
+               {{ 0x01, 0x00, 0xff, 0xaf }, 4},
+               {{ 0x01, 0x00, 0x03, 0xa0 }, 4},
+               {{ 0x01, 0x00 }, 2},
+               {{ 0x01, 0x00, 0x73, 0xaf }, 4},
+               {{ 0x04, 0x00 }, 2},
+               {{ 0x00, 0x04 }, 2},
+               {{ 0x00, 0x04, 0x00, 0x0a }, 4},
+               {{ 0x04, 0x14 }, 2},
+               {{ 0x04, 0x14, 0x00, 0x00 }, 4},
+       };
+
+       em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
+
+       em28xx_gpio_set(dev, terratec_htc_usb_xs_init);
+
+       em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
+       msleep(10);
+       em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
+       msleep(10);
+
+       dev->i2c_client.addr = 0x82 >> 1;
+
+       for (i = 0; i < ARRAY_SIZE(regs); i++)
+               i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
+
+       em28xx_gpio_set(dev, terratec_htc_usb_xs_end);
+};
+
 static void pctv_520e_init(struct em28xx *dev)
 {
        /*
@@ -1147,6 +1208,25 @@ static int em28xx_dvb_init(struct em28xx *dev)
                        goto out_free;
                }
 
+               /* Attach the demodulator. */
+               if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
+                               &dev->i2c_adap,
+                               &em28xx_cxd2820r_tda18271_config)) {
+                       result = -EINVAL;
+                       goto out_free;
+               }
+               break;
+       case EM2884_BOARD_TERRATEC_HTC_USB_XS:
+               terratec_htc_usb_xs_init(dev);
+
+               /* attach demodulator */
+               dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
+                                       &dev->i2c_adap);
+               if (!dvb->fe[0]) {
+                       result = -EINVAL;
+                       goto out_free;
+               }
+
                /* Attach the demodulator. */
                if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
                                &dev->i2c_adap,
index 97d36b4f19db95094bda60d549888e6e564315cf..660bf803c9e4b8df04defd0c0a0758280e30a69b 100644 (file)
@@ -345,7 +345,7 @@ static void em28xx_ir_stop(struct rc_dev *rc)
        cancel_delayed_work_sync(&ir->work);
 }
 
-static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
+static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
 {
        int rc = 0;
        struct em28xx_IR *ir = rc_dev->priv;
@@ -354,14 +354,16 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
 
        /* Adjust xclk based o IR table for RC5/NEC tables */
 
-       if (rc_type == RC_TYPE_RC5) {
+       if (*rc_type & RC_BIT_RC5) {
                dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
                ir->full_code = 1;
-       } else if (rc_type == RC_TYPE_NEC) {
+               *rc_type = RC_BIT_RC5;
+       } else if (*rc_type & RC_BIT_NEC) {
                dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
                ir_config = EM2874_IR_NEC;
                ir->full_code = 1;
-       } else if (rc_type != RC_TYPE_UNKNOWN)
+               *rc_type = RC_BIT_NEC;
+       } else if (*rc_type != RC_BIT_UNKNOWN)
                rc = -EINVAL;
 
        em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
@@ -524,6 +526,7 @@ static int em28xx_ir_init(struct em28xx *dev)
        struct em28xx_IR *ir;
        struct rc_dev *rc;
        int err = -ENOMEM;
+       u64 rc_type;
 
        if (dev->board.ir_codes == NULL) {
                /* No remote control support */
@@ -546,14 +549,15 @@ static int em28xx_ir_init(struct em28xx *dev)
         * em2874 supports more protocols. For now, let's just announce
         * the two protocols that were already tested
         */
-       rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
        rc->priv = ir;
        rc->change_protocol = em28xx_ir_change_protocol;
        rc->open = em28xx_ir_start;
        rc->close = em28xx_ir_stop;
 
        /* By default, keep protocol field untouched */
-       err = em28xx_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
+       rc_type = RC_BIT_UNKNOWN;
+       err = em28xx_ir_change_protocol(rc, &rc_type);
        if (err)
                goto err_out_free;
 
index 8757523e686363d79252878a6bb6d8d64d79cb39..86e90d86da6d51547ae73b5f5a4d3197e488ccbb 100644 (file)
 #define EM2874_BOARD_MAXMEDIA_UB425_TC            84
 #define EM2884_BOARD_PCTV_510E                    85
 #define EM2884_BOARD_PCTV_520E                    86
+#define EM2884_BOARD_TERRATEC_HTC_USB_XS         87
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
index a2b934146ebf9245da1a972b36addc89eb7b026c..e0a431bb0d4207aa5b7910b9b483af31d9d381e1 100644 (file)
@@ -1586,8 +1586,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
        struct gspca_dev *gspca_dev = video_drvdata(file);
        struct gspca_frame *frame;
 
-       if (v4l2_buf->index < 0
-           || v4l2_buf->index >= gspca_dev->nframes)
+       if (v4l2_buf->index >= gspca_dev->nframes)
                return -EINVAL;
 
        frame = &gspca_dev->frame[v4l2_buf->index];
index e3eab82cd4e5d31097b064e654e18a9079d8ee43..352317d7acdbacb7bc423f954bc05738790fe9ec 100644 (file)
@@ -32,7 +32,7 @@ do {                                                          \
 #define D_USBO 0x00
 #define D_V4L2 0x0100
 #else
-#define PDEBUG(level, fmt, ...)
+#define PDEBUG(level, fmt, ...) do {} while(0)
 #endif
 
 #define GSPCA_MAX_FRAMES 16    /* maximum number of video frame buffers */
index b897aa86f315665645808efa95be5b11d3ac2171..1ba29fe7fada3603fa6b93ca80bd9fdf8738202e 100644 (file)
@@ -114,7 +114,7 @@ static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
 }
 
 /* Responses are one byte only */
-static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
+static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char *response)
 {
        int retval;
 
@@ -123,7 +123,7 @@ static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
        retval = usb_bulk_msg(gspca_dev->dev,
        usb_rcvbulkpipe(gspca_dev->dev, 0x84),
                                gspca_dev->usb_buf, 1, NULL, 500);
-       response = gspca_dev->usb_buf[0];
+       *response = gspca_dev->usb_buf[0];
        if (retval < 0) {
                pr_err("read command [%02x] error %d\n",
                       gspca_dev->usb_buf[0], retval);
@@ -260,7 +260,7 @@ static int jlj_start(struct gspca_dev *gspca_dev)
                if (start_commands[i].delay)
                        msleep(start_commands[i].delay);
                if (start_commands[i].ack_wanted)
-                       jlj_read1(gspca_dev, response);
+                       jlj_read1(gspca_dev, &response);
        }
        setcamquality(gspca_dev, v4l2_ctrl_g_ctrl(sd->jpegqual));
        msleep(2);
index cc8ec3f7e8dc59df40952cc0dfdaf810c86e4ffd..c8e1572eb5024cba1f12af7ece1f4ca24bf8a8d5 100644 (file)
@@ -73,6 +73,12 @@ static
                        DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2548")
                }
+       }, {
+               .ident = "Fujitsu-Siemens Amilo Pi 2530",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 2530")
+               }
        }, {
                .ident = "MSI GX700",
                .matches = {
index 2d5c6d8343a01c475291b3435de77cec7112ff35..4f5869a98082201e2ef39d8bb3f009b0972826a4 100644 (file)
  * Register page 0:
  *
  * Address     Description
- * 0x02                Red balance control
- * 0x03                Green balance control
- * 0x04        Blue balance control
- *                  Valus are inverted (0=max, 255=min).
+ * 0x01                Red balance control
+ * 0x02                Green balance control
+ * 0x03                Blue balance control
  *                  The Windows driver uses a quadratic approach to map
  *                  the settable values (0-200) on register values:
- *                  min=0x80, default=0x40, max=0x20
- * 0x0f-0x20   Colors, saturation and exposure control
+ *                  min=0x20, default=0x40, max=0x80
+ * 0x0f-0x20   Color and saturation control
  * 0xa2-0xab   Brightness, contrast and gamma control
  * 0xb6                Sharpness control (bits 0-4)
  *
  *
  * Page | Register   | Function
  * -----+------------+---------------------------------------------------
+ *  0   | 0x01       | setredbalance()
+ *  0   | 0x03       | setbluebalance()
  *  0   | 0x0f..0x20 | setcolors()
  *  0   | 0xa2..0xab | setbrightcont()
  *  0   | 0xb6       | setsharpness()
- *  0   | 0xc5       | setredbalance()
  *  0   | 0xc6       | setwhitebalance()
- *  0   | 0xc7       | setbluebalance()
  *  0   | 0xdc       | setbrightcont(), setcolors()
  *  3   | 0x02       | setexposure()
  *  3   | 0x10, 0x12 | setgain()
 /* Include pac common sof detection functions */
 #include "pac_common.h"
 
-#define PAC7302_GAIN_DEFAULT      15
-#define PAC7302_GAIN_KNEE         42
-#define PAC7302_EXPOSURE_DEFAULT  66 /* 33 ms / 30 fps */
-#define PAC7302_EXPOSURE_KNEE    133 /* 66 ms / 15 fps */
+#define PAC7302_RGB_BALANCE_MIN                  0
+#define PAC7302_RGB_BALANCE_MAX                200
+#define PAC7302_RGB_BALANCE_DEFAULT    100
+#define PAC7302_GAIN_DEFAULT            15
+#define PAC7302_GAIN_KNEE               42
+#define PAC7302_EXPOSURE_DEFAULT        66 /* 33 ms / 30 fps */
+#define PAC7302_EXPOSURE_KNEE          133 /* 66 ms / 15 fps */
 
 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
                "Thomas Kaiser thomas@kaiser-linux.li");
@@ -439,12 +441,31 @@ static void setwhitebalance(struct gspca_dev *gspca_dev)
        reg_w(gspca_dev, 0xdc, 0x01);
 }
 
+static u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
+{
+       const unsigned int k = 1000;    /* precision factor */
+       unsigned int norm;
+
+       /* Normed value [0...k] */
+       norm = k * (rgb_ctrl_val - PAC7302_RGB_BALANCE_MIN)
+                   / (PAC7302_RGB_BALANCE_MAX - PAC7302_RGB_BALANCE_MIN);
+       /* Qudratic apporach improves control at small (register) values: */
+       return 64 * norm * norm / (k*k)  +  32 * norm / k  +  32;
+       /* Y = 64*X*X + 32*X + 32
+        * => register values 0x20-0x80; Windows driver uses these limits */
+
+       /* NOTE: for full value range (0x00-0xff) use
+        *         Y = 254*X*X + X
+        *         => 254 * norm * norm / (k*k)  +  1 * norm / k        */
+}
+
 static void setredbalance(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
 
-       reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
-       reg_w(gspca_dev, 0xc5, sd->red_balance->val);
+       reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
+       reg_w(gspca_dev, 0x01,
+             rgbbalance_ctrl_to_reg_value(sd->red_balance->val));
 
        reg_w(gspca_dev, 0xdc, 0x01);
 }
@@ -454,7 +475,8 @@ static void setbluebalance(struct gspca_dev *gspca_dev)
        struct sd *sd = (struct sd *) gspca_dev;
 
        reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
-       reg_w(gspca_dev, 0xc7, sd->blue_balance->val);
+       reg_w(gspca_dev, 0x03,
+             rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
 
        reg_w(gspca_dev, 0xdc, 0x01);
 }
@@ -643,9 +665,15 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
                                        V4L2_CID_WHITE_BALANCE_TEMPERATURE,
                                        0, 255, 1, 55);
        sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
-                                       V4L2_CID_RED_BALANCE, 0, 3, 1, 1);
+                                       V4L2_CID_RED_BALANCE,
+                                       PAC7302_RGB_BALANCE_MIN,
+                                       PAC7302_RGB_BALANCE_MAX,
+                                       1, PAC7302_RGB_BALANCE_DEFAULT);
        sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
-                                       V4L2_CID_BLUE_BALANCE, 0, 3, 1, 1);
+                                       V4L2_CID_BLUE_BALANCE,
+                                       PAC7302_RGB_BALANCE_MIN,
+                                       PAC7302_RGB_BALANCE_MAX,
+                                       1, PAC7302_RGB_BALANCE_DEFAULT);
 
        gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
                                        V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
index fd1f8d2d3b0b4f52b6640b4f540ac1cf3226898f..70511d5f953857492aca04655cdf079836a998dc 100644 (file)
@@ -1449,6 +1449,7 @@ static const struct usb_device_id device_table[] = {
        {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
        {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
 #endif
+       {USB_DEVICE(0x0c45, 0x6027), SB(OV7630, 101)}, /* Genius Eye 310 */
        {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
        {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
        {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)},
index 304f43ef59eb16a8778d2adbc43baf4743187a9b..84dc26fe80eed741866e2aaece3aa77f60414986 100644 (file)
@@ -401,12 +401,14 @@ static int hdpvr_probe(struct usb_interface *interface,
        client = hdpvr_register_ir_rx_i2c(dev);
        if (!client) {
                v4l2_err(&dev->v4l2_dev, "i2c IR RX device register failed\n");
+               retval = -ENODEV;
                goto reg_fail;
        }
 
        client = hdpvr_register_ir_tx_i2c(dev);
        if (!client) {
                v4l2_err(&dev->v4l2_dev, "i2c IR TX device register failed\n");
+               retval = -ENODEV;
                goto reg_fail;
        }
 #endif
index 82e819fa91c0814047074b867ae2bca713570b75..031cf024304c356e8573f13119505de49b71e1a8 100644 (file)
@@ -55,7 +55,7 @@ struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
        /* Our default information for ir-kbd-i2c.c to use */
        init_data->ir_codes = RC_MAP_HAUPPAUGE;
        init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-       init_data->type = RC_TYPE_RC5;
+       init_data->type = RC_BIT_RC5;
        init_data->name = "HD-PVR";
        init_data->polling_interval = 405; /* ms, duplicated from Windows */
        hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
index fb828ba1dbbe8044e09cf33a5b3269ef09417254..299751a8b06bc323bb347217235bf6486b2e6488 100644 (file)
@@ -3563,9 +3563,9 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
                                     enum pvr2_v4l_type index,int v)
 {
        switch (index) {
-       case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
-       case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
-       case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
+       case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;break;
+       case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;break;
+       case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;break;
        default: break;
        }
 }
index 885ce11f222d779e5320e2dc43494bc6b7011cd0..9ab596c78a4e35a0f23af1a5f4422741bbcc71d7 100644 (file)
@@ -581,7 +581,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
        case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */
                init_data->ir_codes              = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
-               init_data->type                  = RC_TYPE_RC5;
+               init_data->type                  = RC_BIT_RC5;
                init_data->name                  = hdw->hdw_desc->description;
                init_data->polling_interval      = 100; /* ms From ir-kbd-i2c */
                /* IR Receiver */
@@ -596,7 +596,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
        case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */
                init_data->ir_codes              = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-               init_data->type                  = RC_TYPE_RC5;
+               init_data->type                  = RC_BIT_RC5;
                init_data->name                  = hdw->hdw_desc->description;
                /* IR Receiver */
                info.addr          = 0x71;
index db249cad3cd975f1be344057d5d6cab7fda344f6..6930676051e74fb0efda27771520ca0dd913b7fc 100644 (file)
@@ -196,7 +196,7 @@ static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std)
        return ret;
 }
 
-int pvr2_s_std(struct file *file, void *priv, v4l2_std_id *std)
+static int pvr2_s_std(struct file *file, void *priv, v4l2_std_id *std)
 {
        struct pvr2_v4l2_fh *fh = file->private_data;
        struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
@@ -365,7 +365,7 @@ static int pvr2_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
                        vt->audmode);
 }
 
-int pvr2_s_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
+static int pvr2_s_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
 {
        struct pvr2_v4l2_fh *fh = file->private_data;
        struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
index 1f506fde97d0a52433a7477f6ac843cc60af1f2f..3a1618580ed6c6a774713fb44e8c6fcab8d31c5c 100644 (file)
@@ -179,6 +179,8 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int pixfmt,
                return -EINVAL;
        if (frames < 4)
                frames = 4;
+       else if (size > PSZ_QCIF && frames > 15)
+               frames = 15;
        else if (frames > 25)
                frames = 25;
        frames = frames2frames[frames];
index 42e36bac4d72a93add64b485652fc957bf0a30a3..5210239cbaeefcc9b92cd548bfbe1c010fd6b89d 100644 (file)
@@ -155,7 +155,7 @@ static struct video_device pwc_template = {
 /***************************************************************************/
 /* Private functions */
 
-struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev)
+static struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev)
 {
        unsigned long flags = 0;
        struct pwc_frame_buf *buf = NULL;
@@ -1000,7 +1000,11 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
        pdev->vb_queue.ops = &pwc_vb_queue_ops;
        pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
-       vb2_queue_init(&pdev->vb_queue);
+       rc = vb2_queue_init(&pdev->vb_queue);
+       if (rc < 0) {
+               PWC_ERROR("Oops, could not initialize vb2 queue.\n");
+               goto err_free_mem;
+       }
 
        /* Init video_device structure */
        memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
index 2191f6ddf9e7536883a6b7e7973ceeba30b0ef61..8ebec0d7bf59509bd19ea1756528e1e9407fbe45 100644 (file)
@@ -1651,7 +1651,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
        int is_ntsc = 0;
 #define NUM_FRAME_ENUMS 4
        int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
-       if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS)
+       if (fe->index >= NUM_FRAME_ENUMS)
                return -EINVAL;
        switch (fe->width) {
        case 640:
index 3c76e62d820da4ac3ccffe8f8f4cbe6b3229451d..5afbd9a4b55c985f2cbf3b118060767ebebb4f9c 100644 (file)
@@ -4,7 +4,8 @@
 
 config SMS_USB_DRV
        tristate "Siano SMS1xxx based MDTV receiver"
-       depends on DVB_CORE && RC_CORE && HAS_DMA
+       depends on DVB_CORE && HAS_DMA
+       select MEDIA_COMMON_OPTIONS
        ---help---
          Choose if you would like to have Siano's support for USB interface
 
index 5bfc8e2f018f20fb07389b7fadf8902c7073714e..73605864fffadb98ce9e780cf8499bee83a1704c 100644 (file)
@@ -2481,11 +2481,13 @@ sn9c102_vidioc_enum_framesizes(struct sn9c102_device* cam, void __user * arg)
                if (frmsize.pixel_format != V4L2_PIX_FMT_SN9C10X &&
                    frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
                        return -EINVAL;
+               break;
        case BRIDGE_SN9C105:
        case BRIDGE_SN9C120:
                if (frmsize.pixel_format != V4L2_PIX_FMT_JPEG &&
                    frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
                        return -EINVAL;
+               break;
        }
 
        frmsize.type = V4L2_FRMSIZE_TYPE_STEPWISE;
index 176ac937306be7e63b6362ae55f071adde7f00c0..850cf285ada8d97e2f2348da39f139d041d6404b 100644 (file)
@@ -116,7 +116,7 @@ static int stk1160_i2c_read_reg(struct stk1160 *dev, u8 addr,
        if (rc < 0)
                return rc;
 
-       stk1160_read_reg(dev, STK1160_SBUSR_RD, value);
+       rc = stk1160_read_reg(dev, STK1160_SBUSR_RD, value);
        if (rc < 0)
                return rc;
 
index 8bdfb0275313929d0698817eedb5143ecec72ec0..fa3671de02aa66081019f9d102339a0c6873f972 100644 (file)
@@ -475,7 +475,11 @@ int stk1160_alloc_isoc(struct stk1160 *dev)
                if (!dev->isoc_ctl.transfer_buffer[i]) {
                        stk1160_err("cannot alloc %d bytes for tx[%d] buffer\n",
                                sb_size, i);
-                       goto free_i_bufs;
+
+                       /* Not enough transfer buffers, so just give up */
+                       if (i < STK1160_MIN_BUFS)
+                               goto free_i_bufs;
+                       goto nomore_tx_bufs;
                }
                memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
 
@@ -506,13 +510,28 @@ int stk1160_alloc_isoc(struct stk1160 *dev)
                }
        }
 
-       stk1160_dbg("urbs allocated\n");
+       stk1160_dbg("%d urbs allocated\n", num_bufs);
 
        /* At last we can say we have some buffers */
        dev->isoc_ctl.num_bufs = num_bufs;
 
        return 0;
 
+nomore_tx_bufs:
+       /*
+        * Failed to allocate desired buffer count. However, we may have
+        * enough to work fine, so we just free the extra urb,
+        * store the allocated count and keep going, fingers crossed!
+        */
+       usb_free_urb(dev->isoc_ctl.urb[i]);
+       dev->isoc_ctl.urb[i] = NULL;
+
+       stk1160_warn("%d urbs allocated. Trying to continue...\n", i - 1);
+
+       dev->isoc_ctl.num_bufs = i - 1;
+
+       return 0;
+
 free_i_bufs:
        /* Save the allocated buffers so far, so we can properly free them */
        dev->isoc_ctl.num_bufs = i+1;
index 68c8707d36abed789d196ccd3e8a5d528b0b78ac..05b05b160e1e9abdd886bf49702bc35c8b3a52dc 100644 (file)
 #define STK1160_VERSION                "0.9.5"
 #define STK1160_VERSION_NUM    0x000905
 
-/* TODO: Decide on number of packets for each buffer */
+/* Decide on number of packets for each buffer */
 #define STK1160_NUM_PACKETS 64
 
 /* Number of buffers for isoc transfers */
-#define STK1160_NUM_BUFS 16 /* TODO */
+#define STK1160_NUM_BUFS 16
+#define STK1160_MIN_BUFS 1
 
 /* TODO: This endpoint address should be retrieved */
 #define STK1160_EP_VIDEO 0x82
index 86a0fc56c330f93076dfbd6c0984dd4d6e3b1023..5d3c032d733cf6e92ca7b345de95862204cd3d91 100644 (file)
@@ -54,10 +54,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jaime Velasco Juan <jsagarribay@gmail.com> and Nicolas VIVIEN");
 MODULE_DESCRIPTION("Syntek DC1125 webcam driver");
 
-
-/* bool for webcam LED management */
-int first_init = 1;
-
 /* Some cameras have audio interfaces, we aren't interested in those */
 static struct usb_device_id stkwebcam_table[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(0x174f, 0xa311, 0xff, 0xff, 0xff) },
@@ -554,6 +550,7 @@ static void stk_free_buffers(struct stk_camera *dev)
 
 static int v4l_stk_open(struct file *fp)
 {
+       static int first_init = 1; /* webcam LED management */
        struct stk_camera *dev;
        struct video_device *vdev;
 
index 30fcb117e89899a25208428061900d22eefb829c..ca4994a5190ce4fbb5f11a918869ca78963c7021 100644 (file)
@@ -1,6 +1,7 @@
 #include "pd-common.h"
 #include <linux/kernel.h>
 #include <linux/usb.h>
+#include <linux/time.h>
 #include <linux/dvb/dmx.h>
 #include <linux/delay.h>
 #include <linux/gfp.h>
index 1f448ac7a496c160d567b1b6c2eeb5b4eabff288..3082bfa9b2c5d60fdc38a383344f915564b86e2f 100644 (file)
@@ -888,7 +888,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *in)
 {
        struct front_face *front = fh;
 
-       if (in->index < 0 || in->index >= POSEIDON_INPUTS)
+       if (in->index >= POSEIDON_INPUTS)
                return -EINVAL;
        strcpy(in->name, pd_inputs[in->index].name);
        in->type  = V4L2_INPUT_TYPE_TUNER;
@@ -923,7 +923,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
        struct poseidon *pd = front->pd;
        s32 ret, cmd_status;
 
-       if (i < 0 || i >= POSEIDON_INPUTS)
+       if (i >= POSEIDON_INPUTS)
                return -EINVAL;
        ret = send_set_req(pd, SGNL_SRC_SEL,
                        pd_inputs[i].tlg_src, &cmd_status);
index dffbd4bd47b15d92ffff672189aa2f18e90be4f0..8a6bbf1d80e1a484956bf655c9a1df75752a3b63 100644 (file)
@@ -109,12 +109,12 @@ static int tm6000_ir_config(struct tm6000_IR *ir)
         */
 
        switch (ir->rc_type) {
-       case RC_TYPE_NEC:
+       case RC_BIT_NEC:
                leader = 900;   /* ms */
                pulse  = 700;   /* ms - the actual value would be 562 */
                break;
        default:
-       case RC_TYPE_RC5:
+       case RC_BIT_RC5:
                leader = 900;   /* ms - from the NEC decoding */
                pulse  = 1780;  /* ms - The actual value would be 1776 */
                break;
@@ -122,12 +122,12 @@ static int tm6000_ir_config(struct tm6000_IR *ir)
 
        pulse = ir_clock_mhz * pulse;
        leader = ir_clock_mhz * leader;
-       if (ir->rc_type == RC_TYPE_NEC)
+       if (ir->rc_type == RC_BIT_NEC)
                leader = leader | 0x8000;
 
        dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n",
                __func__,
-               (ir->rc_type == RC_TYPE_NEC) ? "NEC" : "RC-5",
+               (ir->rc_type == RC_BIT_NEC) ? "NEC" : "RC-5",
                ir_clock_mhz, leader, pulse);
 
        /* Remote WAKEUP = enable, normal mode, from IR decoder output */
@@ -297,7 +297,7 @@ static void tm6000_ir_stop(struct rc_dev *rc)
        cancel_delayed_work_sync(&ir->work);
 }
 
-static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
+static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_type)
 {
        struct tm6000_IR *ir = rc->priv;
 
@@ -306,10 +306,10 @@ static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
 
        dprintk(2, "%s\n",__func__);
 
-       if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC))
+       if ((rc->rc_map.scan) && (*rc_type == RC_BIT_NEC))
                ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff);
 
-       ir->rc_type = rc_type;
+       ir->rc_type = *rc_type;
 
        tm6000_ir_config(ir);
        /* TODO */
@@ -398,6 +398,7 @@ int tm6000_ir_init(struct tm6000_core *dev)
        struct tm6000_IR *ir;
        struct rc_dev *rc;
        int err = -ENOMEM;
+       u64 rc_type;
 
        if (!enable_ir)
                return -ENODEV;
@@ -421,7 +422,7 @@ int tm6000_ir_init(struct tm6000_core *dev)
        ir->rc = rc;
 
        /* input setup */
-       rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
        /* Neded, in order to support NEC remotes with 24 or 32 bits */
        rc->scanmask = 0xffff;
        rc->priv = ir;
@@ -444,7 +445,8 @@ int tm6000_ir_init(struct tm6000_core *dev)
        usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
        strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
-       tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
+       rc_type = RC_BIT_UNKNOWN;
+       tm6000_ir_change_protocol(rc, &rc_type);
 
        rc->input_name = ir->name;
        rc->input_phys = ir->phys;
index 4342cd4f5c8a7ad76cef1730348fb9ece2b1ada0..f656fd7a39a27de037923320ea605c0fe14c1e83 100644 (file)
@@ -1802,6 +1802,7 @@ int tm6000_v4l2_register(struct tm6000_core *dev)
                if (!dev->radio_dev) {
                        printk(KERN_INFO "%s: can't register radio device\n",
                               dev->name);
+                       ret = -ENXIO;
                        return ret; /* FIXME release resource */
                }
 
index 43cf61fe4943a2b2f88fc0de7cd20f78ba5041bc..8a25876d72c601eaca1b820319129810daf9f313 100644 (file)
@@ -167,7 +167,7 @@ enum {
 
 /* This macro restricts an int variable to an inclusive range */
 #define RESTRICT_TO_RANGE(v, mi, ma) \
-       { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
+       { if (((int)v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
 
 /*
  * We use macros to do YUV -> RGB conversion because this is
index f7061a5ef1d2a1c424c78f486d4348fc96b9b8ff..516a5b188ea5248a48f1cacb64cddb984096d9ea 100644 (file)
@@ -927,7 +927,7 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain,
        int ret;
 
        if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
-               return -EINVAL;
+               return -EACCES;
 
        if (!ctrl->loaded) {
                ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
@@ -1061,7 +1061,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
 
        ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
        if (ctrl == NULL) {
-               ret = -EINVAL;
+               ret = -ENOENT;
                goto done;
        }
 
@@ -1099,12 +1099,13 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
                return -ERESTARTSYS;
 
        ctrl = uvc_find_control(chain, query_menu->id, &mapping);
-       if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
-               ret = -EINVAL;
+       if (ctrl == NULL) {
+               ret = -ENOENT;
                goto done;
        }
 
-       if (query_menu->index >= mapping->menu_count) {
+       if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU ||
+           query_menu->index >= mapping->menu_count) {
                ret = -EINVAL;
                goto done;
        }
@@ -1263,7 +1264,7 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
 
        ctrl = uvc_find_control(handle->chain, sev->id, &mapping);
        if (ctrl == NULL) {
-               ret = -EINVAL;
+               ret = -ENOENT;
                goto done;
        }
 
@@ -1414,7 +1415,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
 
        ctrl = uvc_find_control(chain, xctrl->id, &mapping);
        if (ctrl == NULL)
-               return -EINVAL;
+               return -ENOENT;
 
        return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
 }
@@ -1431,8 +1432,10 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
        int ret;
 
        ctrl = uvc_find_control(chain, xctrl->id, &mapping);
-       if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0)
-               return -EINVAL;
+       if (ctrl == NULL)
+               return -ENOENT;
+       if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
+               return -EACCES;
 
        /* Clamp out of range values. */
        switch (mapping->v4l2_type) {
@@ -1452,8 +1455,12 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
                if (step == 0)
                        step = 1;
 
-               xctrl->value = min + (xctrl->value - min + step/2) / step * step;
-               xctrl->value = clamp(xctrl->value, min, max);
+               xctrl->value = min + ((u32)(xctrl->value - min) + step / 2)
+                            / step * step;
+               if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
+                       xctrl->value = clamp(xctrl->value, min, max);
+               else
+                       xctrl->value = clamp_t(u32, xctrl->value, min, max);
                value = xctrl->value;
                break;
 
index 5967081747ceb974814a5818ad8cccb43aacf64a..5dbefa68b1d20f0e0ca14fd725b99aafb9410fcd 100644 (file)
@@ -1562,6 +1562,9 @@ static int uvc_scan_device(struct uvc_device *dev)
                INIT_LIST_HEAD(&chain->entities);
                mutex_init(&chain->ctrl_mutex);
                chain->dev = dev;
+               v4l2_prio_init(&chain->prio);
+
+               term->flags |= UVC_ENTITY_FLAG_DEFAULT;
 
                if (uvc_scan_chain(chain, term) < 0) {
                        kfree(chain);
@@ -1722,6 +1725,8 @@ static int uvc_register_video(struct uvc_device *dev,
        vdev->v4l2_dev = &dev->vdev;
        vdev->fops = &uvc_fops;
        vdev->release = uvc_release;
+       vdev->prio = &stream->chain->prio;
+       set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
        if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
                vdev->vfl_dir = VFL_DIR_TX;
        strlcpy(vdev->name, dev->name, sizeof vdev->name);
@@ -1741,6 +1746,11 @@ static int uvc_register_video(struct uvc_device *dev,
                return ret;
        }
 
+       if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE;
+       else
+               stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT;
+
        atomic_inc(&dev->nstreams);
        return 0;
 }
index 29e239911d0e28a6d7a688ab5907781ffa1b41d0..dc56a59ecadc4b5dc2185a9717256eec96ba17c0 100644 (file)
@@ -93,6 +93,8 @@ static int uvc_mc_init_entity(struct uvc_entity *entity)
        } else if (entity->vdev != NULL) {
                ret = media_entity_init(&entity->vdev->entity,
                                        entity->num_pads, entity->pads, 0);
+               if (entity->flags & UVC_ENTITY_FLAG_DEFAULT)
+                       entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
        } else
                ret = 0;
 
index 18a91fae6bc1869e644ffa05e5e103e13b67a3dc..778addc5caffa3112f6509a57269f30431e1d58d 100644 (file)
@@ -128,7 +128,7 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
        int ret;
 
        queue->queue.type = type;
-       queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
+       queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
        queue->queue.drv_priv = queue;
        queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
        queue->queue.ops = &uvc_queue_qops;
index f00db3060e0e36e005b306a53f393cc55071b101..8e056046bc203c4224dd08fa931f56219bdd6157 100644 (file)
@@ -165,17 +165,18 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
                        fcc[0], fcc[1], fcc[2], fcc[3],
                        fmt->fmt.pix.width, fmt->fmt.pix.height);
 
-       /* Check if the hardware supports the requested format. */
+       /* Check if the hardware supports the requested format, use the default
+        * format otherwise.
+        */
        for (i = 0; i < stream->nformats; ++i) {
                format = &stream->format[i];
                if (format->fcc == fmt->fmt.pix.pixelformat)
                        break;
        }
 
-       if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
-               uvc_trace(UVC_TRACE_FORMAT, "Unsupported format 0x%08x.\n",
-                               fmt->fmt.pix.pixelformat);
-               return -EINVAL;
+       if (i == stream->nformats) {
+               format = stream->def_format;
+               fmt->fmt.pix.pixelformat = format->fcc;
        }
 
        /* Find the closest image size. The distance between image sizes is
@@ -564,15 +565,30 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                usb_make_path(stream->dev->udev,
                              cap->bus_info, sizeof(cap->bus_info));
                cap->version = LINUX_VERSION_CODE;
+               cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
+                                 | chain->caps;
                if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-                       cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
-                                         | V4L2_CAP_STREAMING;
+                       cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
+                                        | V4L2_CAP_STREAMING;
                else
-                       cap->capabilities = V4L2_CAP_VIDEO_OUTPUT
-                                         | V4L2_CAP_STREAMING;
+                       cap->device_caps = V4L2_CAP_VIDEO_OUTPUT
+                                        | V4L2_CAP_STREAMING;
                break;
        }
 
+       /* Priority */
+       case VIDIOC_G_PRIORITY:
+               *(u32 *)arg = v4l2_prio_max(vdev->prio);
+               break;
+
+       case VIDIOC_S_PRIORITY:
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+
+               return v4l2_prio_change(vdev->prio, &handle->vfh.prio,
+                                       *(u32 *)arg);
+
        /* Get, Set & Query control */
        case VIDIOC_QUERYCTRL:
                return uvc_query_v4l2_ctrl(chain, arg);
@@ -591,8 +607,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 
                ret = uvc_ctrl_get(chain, &xctrl);
                uvc_ctrl_rollback(handle);
-               if (ret >= 0)
-                       ctrl->value = xctrl.value;
+               if (ret < 0)
+                       return ret == -ENOENT ? -EINVAL : ret;
+
+               ctrl->value = xctrl.value;
                break;
        }
 
@@ -601,6 +619,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                struct v4l2_control *ctrl = arg;
                struct v4l2_ext_control xctrl;
 
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+
                memset(&xctrl, 0, sizeof xctrl);
                xctrl.id = ctrl->id;
                xctrl.value = ctrl->value;
@@ -612,7 +634,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                ret = uvc_ctrl_set(chain, &xctrl);
                if (ret < 0) {
                        uvc_ctrl_rollback(handle);
-                       return ret;
+                       return ret == -ENOENT ? -EINVAL : ret;
                }
                ret = uvc_ctrl_commit(handle, &xctrl, 1);
                if (ret == 0)
@@ -637,8 +659,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                        ret = uvc_ctrl_get(chain, ctrl);
                        if (ret < 0) {
                                uvc_ctrl_rollback(handle);
-                               ctrls->error_idx = i;
-                               return ret;
+                               ctrls->error_idx = ret == -ENOENT
+                                                ? ctrls->count : i;
+                               return ret == -ENOENT ? -EINVAL : ret;
                        }
                }
                ctrls->error_idx = 0;
@@ -647,6 +670,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        }
 
        case VIDIOC_S_EXT_CTRLS:
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+               /* Fall through */
        case VIDIOC_TRY_EXT_CTRLS:
        {
                struct v4l2_ext_controls *ctrls = arg;
@@ -661,8 +688,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                        ret = uvc_ctrl_set(chain, ctrl);
                        if (ret < 0) {
                                uvc_ctrl_rollback(handle);
-                               ctrls->error_idx = i;
-                               return ret;
+                               ctrls->error_idx = (ret == -ENOENT &&
+                                                   cmd == VIDIOC_S_EXT_CTRLS)
+                                                ? ctrls->count : i;
+                               return ret == -ENOENT ? -EINVAL : ret;
                        }
                }
 
@@ -739,6 +768,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        {
                u32 input = *(u32 *)arg + 1;
 
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+
                if ((ret = uvc_acquire_privileges(handle)) < 0)
                        return ret;
 
@@ -792,6 +825,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        }
 
        case VIDIOC_S_FMT:
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+
                if ((ret = uvc_acquire_privileges(handle)) < 0)
                        return ret;
 
@@ -894,6 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                return uvc_v4l2_get_streamparm(stream, arg);
 
        case VIDIOC_S_PARM:
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+
                if ((ret = uvc_acquire_privileges(handle)) < 0)
                        return ret;
 
@@ -924,10 +965,14 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 
        case VIDIOC_G_CROP:
        case VIDIOC_S_CROP:
-               return -EINVAL;
+               return -ENOTTY;
 
        /* Buffers & streaming */
        case VIDIOC_REQBUFS:
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+
                if ((ret = uvc_acquire_privileges(handle)) < 0)
                        return ret;
 
@@ -973,6 +1018,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                if (*type != stream->type)
                        return -EINVAL;
 
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+
                if (!uvc_has_privileges(handle))
                        return -EBUSY;
 
@@ -991,6 +1040,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                if (*type != stream->type)
                        return -EINVAL;
 
+               ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
+               if (ret < 0)
+                       return ret;
+
                if (!uvc_has_privileges(handle))
                        return -EBUSY;
 
@@ -1030,7 +1083,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 
        case VIDIOC_ENUMOUTPUT:
                uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
-               return -EINVAL;
+               return -ENOTTY;
 
        case UVCIOC_CTRL_MAP:
                return uvc_ioctl_ctrl_map(chain, arg);
index 57c3076a4625b09d4b75d05671c3bfbe38eb9109..3394c34320117542ccab9adc4607a1caedb18f53 100644 (file)
@@ -1812,6 +1812,7 @@ int uvc_video_init(struct uvc_streaming *stream)
        probe->bFormatIndex = format->index;
        probe->bFrameIndex = frame->bFrameIndex;
 
+       stream->def_format = format;
        stream->cur_format = format;
        stream->cur_frame = frame;
 
index af216ec45e390fa1bc8863372fd742b6b43b53da..af505fdd9b3f73d581665f660cf622921bea64c2 100644 (file)
@@ -225,10 +225,14 @@ struct uvc_format_desc {
  * always be accessed with the UVC_ENTITY_* macros and never directly.
  */
 
+#define UVC_ENTITY_FLAG_DEFAULT                (1 << 0)
+
 struct uvc_entity {
        struct list_head list;          /* Entity as part of a UVC device. */
        struct list_head chain;         /* Entity as part of a video device
                                         * chain. */
+       unsigned int flags;
+
        __u8 id;
        __u16 type;
        char name[64];
@@ -371,6 +375,9 @@ struct uvc_video_chain {
        struct uvc_entity *selector;            /* Selector unit */
 
        struct mutex ctrl_mutex;                /* Protects ctrl.info */
+
+       struct v4l2_prio_state prio;            /* V4L2 priority state */
+       u32 caps;                               /* V4L2 chain-wide caps */
 };
 
 struct uvc_stats_frame {
@@ -436,6 +443,7 @@ struct uvc_streaming {
        struct uvc_format *format;
 
        struct uvc_streaming_control ctrl;
+       struct uvc_format *def_format;
        struct uvc_format *cur_format;
        struct uvc_frame *cur_frame;
        /* Protect access to ctrl, cur_format, cur_frame and hardware video
index 9afab35878b417f0c0ef7a7b352b718655373d7b..39edd444293226406a4faed135930dcf09ff059c 100644 (file)
@@ -1007,8 +1007,7 @@ static void read_pipe_completion(struct urb *purb)
                return;
        }
 
-       if (purb->actual_length < 0 ||
-           purb->actual_length > pipe_info->transfer_size) {
+       if (purb->actual_length > pipe_info->transfer_size) {
                dev_err(&cam->udev->dev, "wrong number of bytes\n");
                return;
        }
index 0c54e19d9944271bca76d9658363aea34aaccd5a..65875c3aba1b5e59c2d5df049e0e9defd0543a45 100644 (file)
@@ -59,6 +59,7 @@ config VIDEOBUF_DVB
 
 # Used by drivers that need Videobuf2 modules
 config VIDEOBUF2_CORE
+       select DMA_SHARED_BUFFER
        tristate
 
 config VIDEOBUF2_MEMOPS
@@ -68,11 +69,13 @@ config VIDEOBUF2_DMA_CONTIG
        tristate
        select VIDEOBUF2_CORE
        select VIDEOBUF2_MEMOPS
+       select DMA_SHARED_BUFFER
 
 config VIDEOBUF2_VMALLOC
        tristate
        select VIDEOBUF2_CORE
        select VIDEOBUF2_MEMOPS
+       select DMA_SHARED_BUFFER
 
 config VIDEOBUF2_DMA_SG
        tristate
index f995dd31151d0cc36bce91110e8ca3c0443c0138..380ddd89fa4c6f8d6c1bb1b612eeb97fa8420a9f 100644 (file)
@@ -837,7 +837,7 @@ bool v4l2_detect_gtf(unsigned frame_height,
                struct v4l2_dv_timings *fmt)
 {
        int pix_clk;
-       int  v_fp, v_bp, h_fp, h_bp, hsync;
+       int  v_fp, v_bp, h_fp, hsync;
        int frame_width, image_height, image_width;
        bool default_gtf;
        int h_blank;
@@ -885,7 +885,6 @@ bool v4l2_detect_gtf(unsigned frame_height,
        hsync = hsync - hsync % GTF_CELL_GRAN;
 
        h_fp = h_blank / 2 - hsync;
-       h_bp = h_blank / 2;
 
        fmt->bt.polarities = polarities;
        fmt->bt.width = image_width;
index 83ffb6436baf67e22f7308acae67966dbfef6094..7157af301b14946b6b7c3ecbd0933fe80e472f35 100644 (file)
@@ -297,6 +297,7 @@ struct v4l2_plane32 {
        union {
                __u32           mem_offset;
                compat_long_t   userptr;
+               __s32           fd;
        } m;
        __u32                   data_offset;
        __u32                   reserved[11];
@@ -318,6 +319,7 @@ struct v4l2_buffer32 {
                __u32           offset;
                compat_long_t   userptr;
                compat_caddr_t  planes;
+               __s32           fd;
        } m;
        __u32                   length;
        __u32                   reserved2;
@@ -341,6 +343,9 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
                up_pln = compat_ptr(p);
                if (put_user((unsigned long)up_pln, &up->m.userptr))
                        return -EFAULT;
+       } else if (memory == V4L2_MEMORY_DMABUF) {
+               if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
+                       return -EFAULT;
        } else {
                if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
                                        sizeof(__u32)))
@@ -364,6 +369,11 @@ static int put_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
                if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
                                        sizeof(__u32)))
                        return -EFAULT;
+       /* For DMABUF, driver might've set up the fd, so copy it back. */
+       if (memory == V4L2_MEMORY_DMABUF)
+               if (copy_in_user(&up32->m.fd, &up->m.fd,
+                                       sizeof(int)))
+                       return -EFAULT;
 
        return 0;
 }
@@ -446,6 +456,10 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
                        if (get_user(kp->m.offset, &up->m.offset))
                                return -EFAULT;
                        break;
+               case V4L2_MEMORY_DMABUF:
+                       if (get_user(kp->m.fd, &up->m.fd))
+                               return -EFAULT;
+                       break;
                }
        }
 
@@ -510,6 +524,10 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
                        if (put_user(kp->m.offset, &up->m.offset))
                                return -EFAULT;
                        break;
+               case V4L2_MEMORY_DMABUF:
+                       if (put_user(kp->m.fd, &up->m.fd))
+                               return -EFAULT;
+                       break;
                }
        }
 
@@ -1000,6 +1018,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
        case VIDIOC_S_FBUF32:
        case VIDIOC_OVERLAY32:
        case VIDIOC_QBUF32:
+       case VIDIOC_EXPBUF:
        case VIDIOC_DQBUF32:
        case VIDIOC_STREAMON32:
        case VIDIOC_STREAMOFF32:
index a2df842e5100cfbffb16a0e88d4c2400d0666765..98dcad9c8a3bc804c941606dc82088b1d7dae414 100644 (file)
@@ -571,6 +571,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
        SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
        SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
        SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
+       SET_VALID_IOCTL(ops, VIDIOC_EXPBUF, vidioc_expbuf);
        SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
        SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
        SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
index 18a040b935a312d31abb944c50405e026a510f1b..c7200921815282a11e0afa1804840fa803e07917 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 2009--2010 Nokia Corporation.
  *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 9e3fc040ea20303056fcffcaa0b6f0f318deffb4..e57c002b415066a7cf616cc9ef719b12a855bd2b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 2009--2010 Nokia Corporation.
  *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 8f388ff31ebb8732fd1793778c578f9395df777a..aa6e7c788db2b00ed0493c9babae92924a65b6a5 100644 (file)
@@ -155,6 +155,7 @@ static const char *v4l2_memory_names[] = {
        [V4L2_MEMORY_MMAP]    = "mmap",
        [V4L2_MEMORY_USERPTR] = "userptr",
        [V4L2_MEMORY_OVERLAY] = "overlay",
+       [V4L2_MEMORY_DMABUF] = "dmabuf",
 };
 
 #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : "unknown")
@@ -453,6 +454,15 @@ static void v4l_print_buffer(const void *arg, bool write_only)
                        tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits);
 }
 
+static void v4l_print_exportbuffer(const void *arg, bool write_only)
+{
+       const struct v4l2_exportbuffer *p = arg;
+
+       pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
+               p->fd, prt_names(p->type, v4l2_type_names),
+               p->index, p->plane, p->flags);
+}
+
 static void v4l_print_create_buffers(const void *arg, bool write_only)
 {
        const struct v4l2_create_buffers *p = arg;
@@ -1960,6 +1970,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
        IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, INFO_FL_PRIO),
        IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, INFO_FL_PRIO),
        IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
+       IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
        IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, INFO_FL_QUEUE),
        IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
        IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
index 3ac83583ad7ae5695e3087d2960bc88647c4e501..438ea45d10749750a2941474265b0e72ea75f239 100644 (file)
@@ -368,6 +368,19 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
 
+/**
+ * v4l2_m2m_expbuf() - export a source or destination buffer, depending on
+ * the type
+ */
+int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+                 struct v4l2_exportbuffer *eb)
+{
+       struct vb2_queue *vq;
+
+       vq = v4l2_m2m_get_vq(m2m_ctx, eb->type);
+       return vb2_expbuf(vq, eb);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf);
 /**
  * v4l2_m2m_streamon() - turn on streaming for a video queue
  */
@@ -510,12 +523,10 @@ struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops)
 {
        struct v4l2_m2m_dev *m2m_dev;
 
-       if (!m2m_ops)
+       if (!m2m_ops || WARN_ON(!m2m_ops->device_run) ||
+                       WARN_ON(!m2m_ops->job_abort))
                return ERR_PTR(-EINVAL);
 
-       BUG_ON(!m2m_ops->device_run);
-       BUG_ON(!m2m_ops->job_abort);
-
        m2m_dev = kzalloc(sizeof *m2m_dev, GFP_KERNEL);
        if (!m2m_dev)
                return ERR_PTR(-ENOMEM);
index dced41c1d993d78f72c20f0ac00592154393b206..996c248dea42bc501497b2b6328321c456373d3b 100644 (file)
@@ -412,20 +412,20 @@ static int
 v4l2_subdev_link_validate_get_format(struct media_pad *pad,
                                     struct v4l2_subdev_format *fmt)
 {
-       switch (media_entity_type(pad->entity)) {
-       case MEDIA_ENT_T_V4L2_SUBDEV:
+       if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) {
+               struct v4l2_subdev *sd =
+                       media_entity_to_v4l2_subdev(pad->entity);
+
                fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
                fmt->pad = pad->index;
-               return v4l2_subdev_call(media_entity_to_v4l2_subdev(
-                                               pad->entity),
-                                       pad, get_fmt, NULL, fmt);
-       default:
-               WARN(1, "Driver bug! Wrong media entity type %d, entity %s\n",
-                    media_entity_type(pad->entity), pad->entity->name);
-               /* Fall through */
-       case MEDIA_ENT_T_DEVNODE_V4L:
-               return -EINVAL;
+               return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
        }
+
+       WARN(pad->entity->type != MEDIA_ENT_T_DEVNODE_V4L,
+            "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
+            pad->entity->type, pad->entity->name);
+
+       return -EINVAL;
 }
 
 int v4l2_subdev_link_validate(struct media_link *link)
index bf7a326b1cdc06f8346981f246a74be572894fe4..5449e8aa984a7b9ba18d1f02679a68d976411f9c 100644 (file)
@@ -335,6 +335,9 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
        case V4L2_MEMORY_OVERLAY:
                b->m.offset  = vb->boff;
                break;
+       case V4L2_MEMORY_DMABUF:
+               /* DMABUF is not handled in videobuf framework */
+               break;
        }
 
        b->flags    = 0;
@@ -405,6 +408,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
                        break;
                case V4L2_MEMORY_USERPTR:
                case V4L2_MEMORY_OVERLAY:
+               case V4L2_MEMORY_DMABUF:
                        /* nothing */
                        break;
                }
index 432df119af278dd953a492fece76552a4c8d3e86..9f81be23a81f06a1d527ac792071e1b7a6154979 100644 (file)
@@ -108,6 +108,36 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
        }
 }
 
+/**
+ * __vb2_plane_dmabuf_put() - release memory associated with
+ * a DMABUF shared plane
+ */
+static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
+{
+       if (!p->mem_priv)
+               return;
+
+       if (p->dbuf_mapped)
+               call_memop(q, unmap_dmabuf, p->mem_priv);
+
+       call_memop(q, detach_dmabuf, p->mem_priv);
+       dma_buf_put(p->dbuf);
+       memset(p, 0, sizeof(*p));
+}
+
+/**
+ * __vb2_buf_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
+{
+       struct vb2_queue *q = vb->vb2_queue;
+       unsigned int plane;
+
+       for (plane = 0; plane < vb->num_planes; ++plane)
+               __vb2_plane_dmabuf_put(q, &vb->planes[plane]);
+}
+
 /**
  * __setup_offsets() - setup unique offsets ("cookies") for every plane in
  * every buffer on the queue
@@ -230,6 +260,8 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
                /* Free MMAP buffers or release USERPTR buffers */
                if (q->memory == V4L2_MEMORY_MMAP)
                        __vb2_buf_mem_free(vb);
+               else if (q->memory == V4L2_MEMORY_DMABUF)
+                       __vb2_buf_dmabuf_put(vb);
                else
                        __vb2_buf_userptr_put(vb);
        }
@@ -362,6 +394,8 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
                        b->m.offset = vb->v4l2_planes[0].m.mem_offset;
                else if (q->memory == V4L2_MEMORY_USERPTR)
                        b->m.userptr = vb->v4l2_planes[0].m.userptr;
+               else if (q->memory == V4L2_MEMORY_DMABUF)
+                       b->m.fd = vb->v4l2_planes[0].m.fd;
        }
 
        /*
@@ -453,6 +487,20 @@ static int __verify_mmap_ops(struct vb2_queue *q)
        return 0;
 }
 
+/**
+ * __verify_dmabuf_ops() - verify that all memory operations required for
+ * DMABUF queue type have been provided
+ */
+static int __verify_dmabuf_ops(struct vb2_queue *q)
+{
+       if (!(q->io_modes & VB2_DMABUF) || !q->mem_ops->attach_dmabuf ||
+           !q->mem_ops->detach_dmabuf  || !q->mem_ops->map_dmabuf ||
+           !q->mem_ops->unmap_dmabuf)
+               return -EINVAL;
+
+       return 0;
+}
+
 /**
  * __verify_memory_type() - Check whether the memory type and buffer type
  * passed to a buffer operation are compatible with the queue.
@@ -460,7 +508,8 @@ static int __verify_mmap_ops(struct vb2_queue *q)
 static int __verify_memory_type(struct vb2_queue *q,
                enum v4l2_memory memory, enum v4l2_buf_type type)
 {
-       if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR) {
+       if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR &&
+           memory != V4L2_MEMORY_DMABUF) {
                dprintk(1, "reqbufs: unsupported memory type\n");
                return -EINVAL;
        }
@@ -484,6 +533,11 @@ static int __verify_memory_type(struct vb2_queue *q,
                return -EINVAL;
        }
 
+       if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {
+               dprintk(1, "reqbufs: DMABUF for current setup unsupported\n");
+               return -EINVAL;
+       }
+
        /*
         * Place the busy tests at the end: -EBUSY can be ignored when
         * create_bufs is called with count == 0, but count == 0 should still
@@ -790,6 +844,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
 {
        struct vb2_queue *q = vb->vb2_queue;
        unsigned long flags;
+       unsigned int plane;
 
        if (vb->state != VB2_BUF_STATE_ACTIVE)
                return;
@@ -800,6 +855,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
        dprintk(4, "Done processing on buffer %d, state: %d\n",
                        vb->v4l2_buf.index, vb->state);
 
+       /* sync buffers */
+       for (plane = 0; plane < vb->num_planes; ++plane)
+               call_memop(q, finish, vb->planes[plane].mem_priv);
+
        /* Add the buffer to the done buffers list */
        spin_lock_irqsave(&q->done_lock, flags);
        vb->state = state;
@@ -845,6 +904,16 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
                                        b->m.planes[plane].length;
                        }
                }
+               if (b->memory == V4L2_MEMORY_DMABUF) {
+                       for (plane = 0; plane < vb->num_planes; ++plane) {
+                               v4l2_planes[plane].m.fd =
+                                       b->m.planes[plane].m.fd;
+                               v4l2_planes[plane].length =
+                                       b->m.planes[plane].length;
+                               v4l2_planes[plane].data_offset =
+                                       b->m.planes[plane].data_offset;
+                       }
+               }
        } else {
                /*
                 * Single-planar buffers do not use planes array,
@@ -859,6 +928,13 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
                        v4l2_planes[0].m.userptr = b->m.userptr;
                        v4l2_planes[0].length = b->length;
                }
+
+               if (b->memory == V4L2_MEMORY_DMABUF) {
+                       v4l2_planes[0].m.fd = b->m.fd;
+                       v4l2_planes[0].length = b->length;
+                       v4l2_planes[0].data_offset = 0;
+               }
+
        }
 
        vb->v4l2_buf.field = b->field;
@@ -958,15 +1034,122 @@ static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
        return 0;
 }
 
+/**
+ * __qbuf_dmabuf() - handle qbuf of a DMABUF buffer
+ */
+static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+{
+       struct v4l2_plane planes[VIDEO_MAX_PLANES];
+       struct vb2_queue *q = vb->vb2_queue;
+       void *mem_priv;
+       unsigned int plane;
+       int ret;
+       int write = !V4L2_TYPE_IS_OUTPUT(q->type);
+
+       /* Verify and copy relevant information provided by the userspace */
+       __fill_vb2_buffer(vb, b, planes);
+
+       for (plane = 0; plane < vb->num_planes; ++plane) {
+               struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);
+
+               if (IS_ERR_OR_NULL(dbuf)) {
+                       dprintk(1, "qbuf: invalid dmabuf fd for plane %d\n",
+                               plane);
+                       ret = -EINVAL;
+                       goto err;
+               }
+
+               /* use DMABUF size if length is not provided */
+               if (planes[plane].length == 0)
+                       planes[plane].length = dbuf->size;
+
+               if (planes[plane].length < planes[plane].data_offset +
+                   q->plane_sizes[plane]) {
+                       ret = -EINVAL;
+                       goto err;
+               }
+
+               /* Skip the plane if already verified */
+               if (dbuf == vb->planes[plane].dbuf &&
+                   vb->v4l2_planes[plane].length == planes[plane].length) {
+                       dma_buf_put(dbuf);
+                       continue;
+               }
+
+               dprintk(1, "qbuf: buffer for plane %d changed\n", plane);
+
+               /* Release previously acquired memory if present */
+               __vb2_plane_dmabuf_put(q, &vb->planes[plane]);
+               memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
+
+               /* Acquire each plane's memory */
+               mem_priv = call_memop(q, attach_dmabuf, q->alloc_ctx[plane],
+                       dbuf, planes[plane].length, write);
+               if (IS_ERR(mem_priv)) {
+                       dprintk(1, "qbuf: failed to attach dmabuf\n");
+                       ret = PTR_ERR(mem_priv);
+                       dma_buf_put(dbuf);
+                       goto err;
+               }
+
+               vb->planes[plane].dbuf = dbuf;
+               vb->planes[plane].mem_priv = mem_priv;
+       }
+
+       /* TODO: This pins the buffer(s) with  dma_buf_map_attachment()).. but
+        * really we want to do this just before the DMA, not while queueing
+        * the buffer(s)..
+        */
+       for (plane = 0; plane < vb->num_planes; ++plane) {
+               ret = call_memop(q, map_dmabuf, vb->planes[plane].mem_priv);
+               if (ret) {
+                       dprintk(1, "qbuf: failed to map dmabuf for plane %d\n",
+                               plane);
+                       goto err;
+               }
+               vb->planes[plane].dbuf_mapped = 1;
+       }
+
+       /*
+        * Call driver-specific initialization on the newly acquired buffer,
+        * if provided.
+        */
+       ret = call_qop(q, buf_init, vb);
+       if (ret) {
+               dprintk(1, "qbuf: buffer initialization failed\n");
+               goto err;
+       }
+
+       /*
+        * Now that everything is in order, copy relevant information
+        * provided by userspace.
+        */
+       for (plane = 0; plane < vb->num_planes; ++plane)
+               vb->v4l2_planes[plane] = planes[plane];
+
+       return 0;
+err:
+       /* In case of errors, release planes that were already acquired */
+       __vb2_buf_dmabuf_put(vb);
+
+       return ret;
+}
+
 /**
  * __enqueue_in_driver() - enqueue a vb2_buffer in driver for processing
  */
 static void __enqueue_in_driver(struct vb2_buffer *vb)
 {
        struct vb2_queue *q = vb->vb2_queue;
+       unsigned int plane;
 
        vb->state = VB2_BUF_STATE_ACTIVE;
        atomic_inc(&q->queued_count);
+
+       /* sync buffers */
+       for (plane = 0; plane < vb->num_planes; ++plane)
+               call_memop(q, prepare, vb->planes[plane].mem_priv);
+
        q->ops->buf_queue(vb);
 }
 
@@ -982,6 +1165,9 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
        case V4L2_MEMORY_USERPTR:
                ret = __qbuf_userptr(vb, b);
                break;
+       case V4L2_MEMORY_DMABUF:
+               ret = __qbuf_dmabuf(vb, b);
+               break;
        default:
                WARN(1, "Invalid queue type\n");
                ret = -EINVAL;
@@ -1302,6 +1488,30 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q)
 }
 EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
 
+/**
+ * __vb2_dqbuf() - bring back the buffer to the DEQUEUED state
+ */
+static void __vb2_dqbuf(struct vb2_buffer *vb)
+{
+       struct vb2_queue *q = vb->vb2_queue;
+       unsigned int i;
+
+       /* nothing to do if the buffer is already dequeued */
+       if (vb->state == VB2_BUF_STATE_DEQUEUED)
+               return;
+
+       vb->state = VB2_BUF_STATE_DEQUEUED;
+
+       /* unmap DMABUF buffer */
+       if (q->memory == V4L2_MEMORY_DMABUF)
+               for (i = 0; i < vb->num_planes; ++i) {
+                       if (!vb->planes[i].dbuf_mapped)
+                               continue;
+                       call_memop(q, unmap_dmabuf, vb->planes[i].mem_priv);
+                       vb->planes[i].dbuf_mapped = 0;
+               }
+}
+
 /**
  * vb2_dqbuf() - Dequeue a buffer to the userspace
  * @q:         videobuf2 queue
@@ -1363,11 +1573,12 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
        __fill_v4l2_buffer(vb, b);
        /* Remove from videobuf queue */
        list_del(&vb->queued_entry);
+       /* go back to dequeued state */
+       __vb2_dqbuf(vb);
 
        dprintk(1, "dqbuf of buffer %d, with state %d\n",
                        vb->v4l2_buf.index, vb->state);
 
-       vb->state = VB2_BUF_STATE_DEQUEUED;
        return 0;
 }
 EXPORT_SYMBOL_GPL(vb2_dqbuf);
@@ -1406,7 +1617,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
         * Reinitialize all buffers for next use.
         */
        for (i = 0; i < q->num_buffers; ++i)
-               q->bufs[i]->state = VB2_BUF_STATE_DEQUEUED;
+               __vb2_dqbuf(q->bufs[i]);
 }
 
 /**
@@ -1539,6 +1750,79 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
        return -EINVAL;
 }
 
+/**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q:         videobuf2 queue
+ * @eb:                export buffer structure passed from userspace to vidioc_expbuf
+ *             handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+       struct vb2_buffer *vb = NULL;
+       struct vb2_plane *vb_plane;
+       int ret;
+       struct dma_buf *dbuf;
+
+       if (q->memory != V4L2_MEMORY_MMAP) {
+               dprintk(1, "Queue is not currently set up for mmap\n");
+               return -EINVAL;
+       }
+
+       if (!q->mem_ops->get_dmabuf) {
+               dprintk(1, "Queue does not support DMA buffer exporting\n");
+               return -EINVAL;
+       }
+
+       if (eb->flags & ~O_CLOEXEC) {
+               dprintk(1, "Queue does support only O_CLOEXEC flag\n");
+               return -EINVAL;
+       }
+
+       if (eb->type != q->type) {
+               dprintk(1, "qbuf: invalid buffer type\n");
+               return -EINVAL;
+       }
+
+       if (eb->index >= q->num_buffers) {
+               dprintk(1, "buffer index out of range\n");
+               return -EINVAL;
+       }
+
+       vb = q->bufs[eb->index];
+
+       if (eb->plane >= vb->num_planes) {
+               dprintk(1, "buffer plane out of range\n");
+               return -EINVAL;
+       }
+
+       vb_plane = &vb->planes[eb->plane];
+
+       dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+       if (IS_ERR_OR_NULL(dbuf)) {
+               dprintk(1, "Failed to export buffer %d, plane %d\n",
+                       eb->index, eb->plane);
+               return -EINVAL;
+       }
+
+       ret = dma_buf_fd(dbuf, eb->flags);
+       if (ret < 0) {
+               dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
+                       eb->index, eb->plane, ret);
+               dma_buf_put(dbuf);
+               return ret;
+       }
+
+       dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
+               eb->index, eb->plane, ret);
+       eb->fd = ret;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
 /**
  * vb2_mmap() - map video buffers into application address space
  * @q:         videobuf2 queue
@@ -2245,6 +2529,16 @@ int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 }
 EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
 
+int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p)
+{
+       struct video_device *vdev = video_devdata(file);
+
+       if (vb2_queue_is_busy(vdev, file))
+               return -EBUSY;
+       return vb2_expbuf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
+
 /* v4l2_file_operations helpers */
 
 int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
index 4b7132660a938f52b105b6306b39d5d54a39777e..10beaee7f0ae592ae88803d7720d298a20beac0d 100644 (file)
  * the Free Software Foundation.
  */
 
+#include <linux/dma-buf.h>
 #include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 
@@ -23,40 +26,158 @@ struct vb2_dc_conf {
 };
 
 struct vb2_dc_buf {
-       struct vb2_dc_conf              *conf;
+       struct device                   *dev;
        void                            *vaddr;
-       dma_addr_t                      dma_addr;
        unsigned long                   size;
-       struct vm_area_struct           *vma;
-       atomic_t                        refcount;
+       dma_addr_t                      dma_addr;
+       enum dma_data_direction         dma_dir;
+       struct sg_table                 *dma_sgt;
+
+       /* MMAP related */
        struct vb2_vmarea_handler       handler;
+       atomic_t                        refcount;
+       struct sg_table                 *sgt_base;
+
+       /* USERPTR related */
+       struct vm_area_struct           *vma;
+
+       /* DMABUF related */
+       struct dma_buf_attachment       *db_attach;
 };
 
-static void vb2_dma_contig_put(void *buf_priv);
+/*********************************************/
+/*        scatterlist table functions        */
+/*********************************************/
+
+
+static void vb2_dc_sgt_foreach_page(struct sg_table *sgt,
+       void (*cb)(struct page *pg))
+{
+       struct scatterlist *s;
+       unsigned int i;
+
+       for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+               struct page *page = sg_page(s);
+               unsigned int n_pages = PAGE_ALIGN(s->offset + s->length)
+                       >> PAGE_SHIFT;
+               unsigned int j;
+
+               for (j = 0; j < n_pages; ++j, ++page)
+                       cb(page);
+       }
+}
+
+static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt)
+{
+       struct scatterlist *s;
+       dma_addr_t expected = sg_dma_address(sgt->sgl);
+       unsigned int i;
+       unsigned long size = 0;
+
+       for_each_sg(sgt->sgl, s, sgt->nents, i) {
+               if (sg_dma_address(s) != expected)
+                       break;
+               expected = sg_dma_address(s) + sg_dma_len(s);
+               size += sg_dma_len(s);
+       }
+       return size;
+}
+
+/*********************************************/
+/*         callbacks for all buffers         */
+/*********************************************/
+
+static void *vb2_dc_cookie(void *buf_priv)
+{
+       struct vb2_dc_buf *buf = buf_priv;
+
+       return &buf->dma_addr;
+}
+
+static void *vb2_dc_vaddr(void *buf_priv)
+{
+       struct vb2_dc_buf *buf = buf_priv;
+
+       return buf->vaddr;
+}
+
+static unsigned int vb2_dc_num_users(void *buf_priv)
+{
+       struct vb2_dc_buf *buf = buf_priv;
+
+       return atomic_read(&buf->refcount);
+}
+
+static void vb2_dc_prepare(void *buf_priv)
+{
+       struct vb2_dc_buf *buf = buf_priv;
+       struct sg_table *sgt = buf->dma_sgt;
+
+       /* DMABUF exporter will flush the cache for us */
+       if (!sgt || buf->db_attach)
+               return;
+
+       dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
+static void vb2_dc_finish(void *buf_priv)
+{
+       struct vb2_dc_buf *buf = buf_priv;
+       struct sg_table *sgt = buf->dma_sgt;
+
+       /* DMABUF exporter will flush the cache for us */
+       if (!sgt || buf->db_attach)
+               return;
+
+       dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
+/*********************************************/
+/*        callbacks for MMAP buffers         */
+/*********************************************/
+
+static void vb2_dc_put(void *buf_priv)
+{
+       struct vb2_dc_buf *buf = buf_priv;
+
+       if (!atomic_dec_and_test(&buf->refcount))
+               return;
+
+       if (buf->sgt_base) {
+               sg_free_table(buf->sgt_base);
+               kfree(buf->sgt_base);
+       }
+       dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+       put_device(buf->dev);
+       kfree(buf);
+}
 
-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
+static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
        struct vb2_dc_conf *conf = alloc_ctx;
+       struct device *dev = conf->dev;
        struct vb2_dc_buf *buf;
 
        buf = kzalloc(sizeof *buf, GFP_KERNEL);
        if (!buf)
                return ERR_PTR(-ENOMEM);
 
-       buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->dma_addr,
-                                       GFP_KERNEL);
+       /* align image size to PAGE_SIZE */
+       size = PAGE_ALIGN(size);
+
+       buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
        if (!buf->vaddr) {
-               dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
-                       size);
+               dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
                kfree(buf);
                return ERR_PTR(-ENOMEM);
        }
 
-       buf->conf = conf;
+       /* Prevent the device from being released while the buffer is used */
+       buf->dev = get_device(dev);
        buf->size = size;
 
        buf->handler.refcount = &buf->refcount;
-       buf->handler.put = vb2_dma_contig_put;
+       buf->handler.put = vb2_dc_put;
        buf->handler.arg = buf;
 
        atomic_inc(&buf->refcount);
@@ -64,100 +185,569 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
        return buf;
 }
 
-static void vb2_dma_contig_put(void *buf_priv)
+static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
        struct vb2_dc_buf *buf = buf_priv;
+       int ret;
 
-       if (atomic_dec_and_test(&buf->refcount)) {
-               dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr,
-                                 buf->dma_addr);
-               kfree(buf);
+       if (!buf) {
+               printk(KERN_ERR "No buffer to map\n");
+               return -EINVAL;
+       }
+
+       /*
+        * dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to
+        * map whole buffer
+        */
+       vma->vm_pgoff = 0;
+
+       ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr,
+               buf->dma_addr, buf->size);
+
+       if (ret) {
+               pr_err("Remapping memory failed, error: %d\n", ret);
+               return ret;
        }
+
+       vma->vm_flags           |= VM_DONTEXPAND | VM_DONTDUMP;
+       vma->vm_private_data    = &buf->handler;
+       vma->vm_ops             = &vb2_common_vm_ops;
+
+       vma->vm_ops->open(vma);
+
+       pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
+               __func__, (unsigned long)buf->dma_addr, vma->vm_start,
+               buf->size);
+
+       return 0;
 }
 
-static void *vb2_dma_contig_cookie(void *buf_priv)
+/*********************************************/
+/*         DMABUF ops for exporters          */
+/*********************************************/
+
+struct vb2_dc_attachment {
+       struct sg_table sgt;
+       enum dma_data_direction dir;
+};
+
+static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
+       struct dma_buf_attachment *dbuf_attach)
 {
-       struct vb2_dc_buf *buf = buf_priv;
+       struct vb2_dc_attachment *attach;
+       unsigned int i;
+       struct scatterlist *rd, *wr;
+       struct sg_table *sgt;
+       struct vb2_dc_buf *buf = dbuf->priv;
+       int ret;
 
-       return &buf->dma_addr;
+       attach = kzalloc(sizeof(*attach), GFP_KERNEL);
+       if (!attach)
+               return -ENOMEM;
+
+       sgt = &attach->sgt;
+       /* Copy the buf->base_sgt scatter list to the attachment, as we can't
+        * map the same scatter list to multiple attachments at the same time.
+        */
+       ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
+       if (ret) {
+               kfree(attach);
+               return -ENOMEM;
+       }
+
+       rd = buf->sgt_base->sgl;
+       wr = sgt->sgl;
+       for (i = 0; i < sgt->orig_nents; ++i) {
+               sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
+               rd = sg_next(rd);
+               wr = sg_next(wr);
+       }
+
+       attach->dir = DMA_NONE;
+       dbuf_attach->priv = attach;
+
+       return 0;
 }
 
-static void *vb2_dma_contig_vaddr(void *buf_priv)
+static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
+       struct dma_buf_attachment *db_attach)
 {
-       struct vb2_dc_buf *buf = buf_priv;
-       if (!buf)
-               return NULL;
+       struct vb2_dc_attachment *attach = db_attach->priv;
+       struct sg_table *sgt;
+
+       if (!attach)
+               return;
+
+       sgt = &attach->sgt;
+
+       /* release the scatterlist cache */
+       if (attach->dir != DMA_NONE)
+               dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+                       attach->dir);
+       sg_free_table(sgt);
+       kfree(attach);
+       db_attach->priv = NULL;
+}
+
+static struct sg_table *vb2_dc_dmabuf_ops_map(
+       struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
+{
+       struct vb2_dc_attachment *attach = db_attach->priv;
+       /* stealing dmabuf mutex to serialize map/unmap operations */
+       struct mutex *lock = &db_attach->dmabuf->lock;
+       struct sg_table *sgt;
+       int ret;
+
+       mutex_lock(lock);
+
+       sgt = &attach->sgt;
+       /* return previously mapped sg table */
+       if (attach->dir == dir) {
+               mutex_unlock(lock);
+               return sgt;
+       }
+
+       /* release any previous cache */
+       if (attach->dir != DMA_NONE) {
+               dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+                       attach->dir);
+               attach->dir = DMA_NONE;
+       }
+
+       /* mapping to the client with new direction */
+       ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
+       if (ret <= 0) {
+               pr_err("failed to map scatterlist\n");
+               mutex_unlock(lock);
+               return ERR_PTR(-EIO);
+       }
+
+       attach->dir = dir;
+
+       mutex_unlock(lock);
+
+       return sgt;
+}
+
+static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
+       struct sg_table *sgt, enum dma_data_direction dir)
+{
+       /* nothing to be done here */
+}
+
+static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf)
+{
+       /* drop reference obtained in vb2_dc_get_dmabuf */
+       vb2_dc_put(dbuf->priv);
+}
+
+static void *vb2_dc_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum)
+{
+       struct vb2_dc_buf *buf = dbuf->priv;
+
+       return buf->vaddr + pgnum * PAGE_SIZE;
+}
+
+static void *vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf)
+{
+       struct vb2_dc_buf *buf = dbuf->priv;
 
        return buf->vaddr;
 }
 
-static unsigned int vb2_dma_contig_num_users(void *buf_priv)
+static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf,
+       struct vm_area_struct *vma)
 {
-       struct vb2_dc_buf *buf = buf_priv;
+       return vb2_dc_mmap(dbuf->priv, vma);
+}
 
-       return atomic_read(&buf->refcount);
+static struct dma_buf_ops vb2_dc_dmabuf_ops = {
+       .attach = vb2_dc_dmabuf_ops_attach,
+       .detach = vb2_dc_dmabuf_ops_detach,
+       .map_dma_buf = vb2_dc_dmabuf_ops_map,
+       .unmap_dma_buf = vb2_dc_dmabuf_ops_unmap,
+       .kmap = vb2_dc_dmabuf_ops_kmap,
+       .kmap_atomic = vb2_dc_dmabuf_ops_kmap,
+       .vmap = vb2_dc_dmabuf_ops_vmap,
+       .mmap = vb2_dc_dmabuf_ops_mmap,
+       .release = vb2_dc_dmabuf_ops_release,
+};
+
+static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
+{
+       int ret;
+       struct sg_table *sgt;
+
+       sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
+       if (!sgt) {
+               dev_err(buf->dev, "failed to alloc sg table\n");
+               return NULL;
+       }
+
+       ret = dma_get_sgtable(buf->dev, sgt, buf->vaddr, buf->dma_addr,
+               buf->size);
+       if (ret < 0) {
+               dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
+               kfree(sgt);
+               return NULL;
+       }
+
+       return sgt;
 }
 
-static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
+static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
 {
        struct vb2_dc_buf *buf = buf_priv;
+       struct dma_buf *dbuf;
 
-       if (!buf) {
-               printk(KERN_ERR "No buffer to map\n");
-               return -EINVAL;
+       if (!buf->sgt_base)
+               buf->sgt_base = vb2_dc_get_base_sgt(buf);
+
+       if (WARN_ON(!buf->sgt_base))
+               return NULL;
+
+       dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, 0);
+       if (IS_ERR(dbuf))
+               return NULL;
+
+       /* dmabuf keeps reference to vb2 buffer */
+       atomic_inc(&buf->refcount);
+
+       return dbuf;
+}
+
+/*********************************************/
+/*       callbacks for USERPTR buffers       */
+/*********************************************/
+
+static inline int vma_is_io(struct vm_area_struct *vma)
+{
+       return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
+}
+
+static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+       int n_pages, struct vm_area_struct *vma, int write)
+{
+       if (vma_is_io(vma)) {
+               unsigned int i;
+
+               for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) {
+                       unsigned long pfn;
+                       int ret = follow_pfn(vma, start, &pfn);
+
+                       if (ret) {
+                               pr_err("no page for address %lu\n", start);
+                               return ret;
+                       }
+                       pages[i] = pfn_to_page(pfn);
+               }
+       } else {
+               int n;
+
+               n = get_user_pages(current, current->mm, start & PAGE_MASK,
+                       n_pages, write, 1, pages, NULL);
+               /* negative error means that no page was pinned */
+               n = max(n, 0);
+               if (n != n_pages) {
+                       pr_err("got only %d of %d user pages\n", n, n_pages);
+                       while (n)
+                               put_page(pages[--n]);
+                       return -EFAULT;
+               }
        }
 
-       return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size,
-                                 &vb2_common_vm_ops, &buf->handler);
+       return 0;
 }
 
-static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
-                                       unsigned long size, int write)
+static void vb2_dc_put_dirty_page(struct page *page)
 {
+       set_page_dirty_lock(page);
+       put_page(page);
+}
+
+static void vb2_dc_put_userptr(void *buf_priv)
+{
+       struct vb2_dc_buf *buf = buf_priv;
+       struct sg_table *sgt = buf->dma_sgt;
+
+       dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+       if (!vma_is_io(buf->vma))
+               vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
+
+       sg_free_table(sgt);
+       kfree(sgt);
+       vb2_put_vma(buf->vma);
+       kfree(buf);
+}
+
+static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
+       unsigned long size, int write)
+{
+       struct vb2_dc_conf *conf = alloc_ctx;
        struct vb2_dc_buf *buf;
+       unsigned long start;
+       unsigned long end;
+       unsigned long offset;
+       struct page **pages;
+       int n_pages;
+       int ret = 0;
        struct vm_area_struct *vma;
-       dma_addr_t dma_addr = 0;
-       int ret;
+       struct sg_table *sgt;
+       unsigned long contig_size;
+       unsigned long dma_align = dma_get_cache_alignment();
+
+       /* Only cache aligned DMA transfers are reliable */
+       if (!IS_ALIGNED(vaddr | size, dma_align)) {
+               pr_debug("user data must be aligned to %lu bytes\n", dma_align);
+               return ERR_PTR(-EINVAL);
+       }
+
+       if (!size) {
+               pr_debug("size is zero\n");
+               return ERR_PTR(-EINVAL);
+       }
 
        buf = kzalloc(sizeof *buf, GFP_KERNEL);
        if (!buf)
                return ERR_PTR(-ENOMEM);
 
-       ret = vb2_get_contig_userptr(vaddr, size, &vma, &dma_addr);
+       buf->dev = conf->dev;
+       buf->dma_dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+       start = vaddr & PAGE_MASK;
+       offset = vaddr & ~PAGE_MASK;
+       end = PAGE_ALIGN(vaddr + size);
+       n_pages = (end - start) >> PAGE_SHIFT;
+
+       pages = kmalloc(n_pages * sizeof(pages[0]), GFP_KERNEL);
+       if (!pages) {
+               ret = -ENOMEM;
+               pr_err("failed to allocate pages table\n");
+               goto fail_buf;
+       }
+
+       /* current->mm->mmap_sem is taken by videobuf2 core */
+       vma = find_vma(current->mm, vaddr);
+       if (!vma) {
+               pr_err("no vma for address %lu\n", vaddr);
+               ret = -EFAULT;
+               goto fail_pages;
+       }
+
+       if (vma->vm_end < vaddr + size) {
+               pr_err("vma at %lu is too small for %lu bytes\n", vaddr, size);
+               ret = -EFAULT;
+               goto fail_pages;
+       }
+
+       buf->vma = vb2_get_vma(vma);
+       if (!buf->vma) {
+               pr_err("failed to copy vma\n");
+               ret = -ENOMEM;
+               goto fail_pages;
+       }
+
+       /* extract page list from userspace mapping */
+       ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, write);
        if (ret) {
-               printk(KERN_ERR "Failed acquiring VMA for vaddr 0x%08lx\n",
-                               vaddr);
-               kfree(buf);
-               return ERR_PTR(ret);
+               pr_err("failed to get user pages\n");
+               goto fail_vma;
+       }
+
+       sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+       if (!sgt) {
+               pr_err("failed to allocate sg table\n");
+               ret = -ENOMEM;
+               goto fail_get_user_pages;
+       }
+
+       ret = sg_alloc_table_from_pages(sgt, pages, n_pages,
+               offset, size, GFP_KERNEL);
+       if (ret) {
+               pr_err("failed to initialize sg table\n");
+               goto fail_sgt;
        }
 
+       /* pages are no longer needed */
+       kfree(pages);
+       pages = NULL;
+
+       sgt->nents = dma_map_sg(buf->dev, sgt->sgl, sgt->orig_nents,
+               buf->dma_dir);
+       if (sgt->nents <= 0) {
+               pr_err("failed to map scatterlist\n");
+               ret = -EIO;
+               goto fail_sgt_init;
+       }
+
+       contig_size = vb2_dc_get_contiguous_size(sgt);
+       if (contig_size < size) {
+               pr_err("contiguous mapping is too small %lu/%lu\n",
+                       contig_size, size);
+               ret = -EFAULT;
+               goto fail_map_sg;
+       }
+
+       buf->dma_addr = sg_dma_address(sgt->sgl);
        buf->size = size;
-       buf->dma_addr = dma_addr;
-       buf->vma = vma;
+       buf->dma_sgt = sgt;
 
        return buf;
+
+fail_map_sg:
+       dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+
+fail_sgt_init:
+       if (!vma_is_io(buf->vma))
+               vb2_dc_sgt_foreach_page(sgt, put_page);
+       sg_free_table(sgt);
+
+fail_sgt:
+       kfree(sgt);
+
+fail_get_user_pages:
+       if (pages && !vma_is_io(buf->vma))
+               while (n_pages)
+                       put_page(pages[--n_pages]);
+
+fail_vma:
+       vb2_put_vma(buf->vma);
+
+fail_pages:
+       kfree(pages); /* kfree is NULL-proof */
+
+fail_buf:
+       kfree(buf);
+
+       return ERR_PTR(ret);
 }
 
-static void vb2_dma_contig_put_userptr(void *mem_priv)
+/*********************************************/
+/*       callbacks for DMABUF buffers        */
+/*********************************************/
+
+static int vb2_dc_map_dmabuf(void *mem_priv)
 {
        struct vb2_dc_buf *buf = mem_priv;
+       struct sg_table *sgt;
+       unsigned long contig_size;
 
-       if (!buf)
+       if (WARN_ON(!buf->db_attach)) {
+               pr_err("trying to pin a non attached buffer\n");
+               return -EINVAL;
+       }
+
+       if (WARN_ON(buf->dma_sgt)) {
+               pr_err("dmabuf buffer is already pinned\n");
+               return 0;
+       }
+
+       /* get the associated scatterlist for this buffer */
+       sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
+       if (IS_ERR_OR_NULL(sgt)) {
+               pr_err("Error getting dmabuf scatterlist\n");
+               return -EINVAL;
+       }
+
+       /* checking if dmabuf is big enough to store contiguous chunk */
+       contig_size = vb2_dc_get_contiguous_size(sgt);
+       if (contig_size < buf->size) {
+               pr_err("contiguous chunk is too small %lu/%lu b\n",
+                       contig_size, buf->size);
+               dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+               return -EFAULT;
+       }
+
+       buf->dma_addr = sg_dma_address(sgt->sgl);
+       buf->dma_sgt = sgt;
+
+       return 0;
+}
+
+static void vb2_dc_unmap_dmabuf(void *mem_priv)
+{
+       struct vb2_dc_buf *buf = mem_priv;
+       struct sg_table *sgt = buf->dma_sgt;
+
+       if (WARN_ON(!buf->db_attach)) {
+               pr_err("trying to unpin a not attached buffer\n");
                return;
+       }
 
-       vb2_put_vma(buf->vma);
+       if (WARN_ON(!sgt)) {
+               pr_err("dmabuf buffer is already unpinned\n");
+               return;
+       }
+
+       dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+
+       buf->dma_addr = 0;
+       buf->dma_sgt = NULL;
+}
+
+static void vb2_dc_detach_dmabuf(void *mem_priv)
+{
+       struct vb2_dc_buf *buf = mem_priv;
+
+       /* if vb2 works correctly you should never detach mapped buffer */
+       if (WARN_ON(buf->dma_addr))
+               vb2_dc_unmap_dmabuf(buf);
+
+       /* detach this attachment */
+       dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
        kfree(buf);
 }
 
+static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+       unsigned long size, int write)
+{
+       struct vb2_dc_conf *conf = alloc_ctx;
+       struct vb2_dc_buf *buf;
+       struct dma_buf_attachment *dba;
+
+       if (dbuf->size < size)
+               return ERR_PTR(-EFAULT);
+
+       buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+       if (!buf)
+               return ERR_PTR(-ENOMEM);
+
+       buf->dev = conf->dev;
+       /* create attachment for the dmabuf with the user device */
+       dba = dma_buf_attach(dbuf, buf->dev);
+       if (IS_ERR(dba)) {
+               pr_err("failed to attach dmabuf\n");
+               kfree(buf);
+               return dba;
+       }
+
+       buf->dma_dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+       buf->size = size;
+       buf->db_attach = dba;
+
+       return buf;
+}
+
+/*********************************************/
+/*       DMA CONTIG exported functions       */
+/*********************************************/
+
 const struct vb2_mem_ops vb2_dma_contig_memops = {
-       .alloc          = vb2_dma_contig_alloc,
-       .put            = vb2_dma_contig_put,
-       .cookie         = vb2_dma_contig_cookie,
-       .vaddr          = vb2_dma_contig_vaddr,
-       .mmap           = vb2_dma_contig_mmap,
-       .get_userptr    = vb2_dma_contig_get_userptr,
-       .put_userptr    = vb2_dma_contig_put_userptr,
-       .num_users      = vb2_dma_contig_num_users,
+       .alloc          = vb2_dc_alloc,
+       .put            = vb2_dc_put,
+       .get_dmabuf     = vb2_dc_get_dmabuf,
+       .cookie         = vb2_dc_cookie,
+       .vaddr          = vb2_dc_vaddr,
+       .mmap           = vb2_dc_mmap,
+       .get_userptr    = vb2_dc_get_userptr,
+       .put_userptr    = vb2_dc_put_userptr,
+       .prepare        = vb2_dc_prepare,
+       .finish         = vb2_dc_finish,
+       .map_dmabuf     = vb2_dc_map_dmabuf,
+       .unmap_dmabuf   = vb2_dc_unmap_dmabuf,
+       .attach_dmabuf  = vb2_dc_attach_dmabuf,
+       .detach_dmabuf  = vb2_dc_detach_dmabuf,
+       .num_users      = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
 
index 051ea3571b208968d6b55ed3f8568038898f1b84..81c1ad8b2cf1eb9582443273c427720be71b04d7 100644 (file)
@@ -136,46 +136,6 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
 }
 EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);
 
-/**
- * vb2_mmap_pfn_range() - map physical pages to userspace
- * @vma:       virtual memory region for the mapping
- * @paddr:     starting physical address of the memory to be mapped
- * @size:      size of the memory to be mapped
- * @vm_ops:    vm operations to be assigned to the created area
- * @priv:      private data to be associated with the area
- *
- * Returns 0 on success.
- */
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-                               unsigned long size,
-                               const struct vm_operations_struct *vm_ops,
-                               void *priv)
-{
-       int ret;
-
-       size = min_t(unsigned long, vma->vm_end - vma->vm_start, size);
-
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-       ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT,
-                               size, vma->vm_page_prot);
-       if (ret) {
-               printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
-               return ret;
-       }
-
-       vma->vm_flags           |= VM_DONTEXPAND | VM_DONTDUMP;
-       vma->vm_private_data    = priv;
-       vma->vm_ops             = vm_ops;
-
-       vma->vm_ops->open(vma);
-
-       pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
-                       __func__, paddr, vma->vm_start, size);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
-
 /**
  * vb2_common_vm_open() - increase refcount of the vma
  * @vma:       virtual memory region for the mapping
index 94efa04d8d55f3e4af400f0910cf791dbf9faf02..a47fd4f589a14bc9a466eee544a582659e25babd 100644 (file)
@@ -30,6 +30,7 @@ struct vb2_vmalloc_buf {
        unsigned int                    n_pages;
        atomic_t                        refcount;
        struct vb2_vmarea_handler       handler;
+       struct dma_buf                  *dbuf;
 };
 
 static void vb2_vmalloc_put(void *buf_priv);
@@ -207,11 +208,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma)
        return 0;
 }
 
+/*********************************************/
+/*       callbacks for DMABUF buffers        */
+/*********************************************/
+
+static int vb2_vmalloc_map_dmabuf(void *mem_priv)
+{
+       struct vb2_vmalloc_buf *buf = mem_priv;
+
+       buf->vaddr = dma_buf_vmap(buf->dbuf);
+
+       return buf->vaddr ? 0 : -EFAULT;
+}
+
+static void vb2_vmalloc_unmap_dmabuf(void *mem_priv)
+{
+       struct vb2_vmalloc_buf *buf = mem_priv;
+
+       dma_buf_vunmap(buf->dbuf, buf->vaddr);
+       buf->vaddr = NULL;
+}
+
+static void vb2_vmalloc_detach_dmabuf(void *mem_priv)
+{
+       struct vb2_vmalloc_buf *buf = mem_priv;
+
+       if (buf->vaddr)
+               dma_buf_vunmap(buf->dbuf, buf->vaddr);
+
+       kfree(buf);
+}
+
+static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+       unsigned long size, int write)
+{
+       struct vb2_vmalloc_buf *buf;
+
+       if (dbuf->size < size)
+               return ERR_PTR(-EFAULT);
+
+       buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+       if (!buf)
+               return ERR_PTR(-ENOMEM);
+
+       buf->dbuf = dbuf;
+       buf->write = write;
+       buf->size = size;
+
+       return buf;
+}
+
+
 const struct vb2_mem_ops vb2_vmalloc_memops = {
        .alloc          = vb2_vmalloc_alloc,
        .put            = vb2_vmalloc_put,
        .get_userptr    = vb2_vmalloc_get_userptr,
        .put_userptr    = vb2_vmalloc_put_userptr,
+       .map_dmabuf     = vb2_vmalloc_map_dmabuf,
+       .unmap_dmabuf   = vb2_vmalloc_unmap_dmabuf,
+       .attach_dmabuf  = vb2_vmalloc_attach_dmabuf,
+       .detach_dmabuf  = vb2_vmalloc_detach_dmabuf,
        .vaddr          = vb2_vmalloc_vaddr,
        .mmap           = vb2_vmalloc_mmap,
        .num_users      = vb2_vmalloc_num_users,
index 238910373f5c74cdc431725cf1d09bba8c33bd25..479c643da2f61c9382709161f9064747239df569 100644 (file)
@@ -396,7 +396,9 @@ dt3155_open(struct file *filp)
                pd->q->drv_priv = pd;
                pd->curr_buf = NULL;
                pd->field_count = 0;
-               vb2_queue_init(pd->q); /* cannot fail */
+               ret = vb2_queue_init(pd->q);
+               if (ret < 0)
+                       return ret;
                INIT_LIST_HEAD(&pd->dmaq);
                spin_lock_init(&pd->lock);
                /* disable all irqs, clear all irq flags */
index c9a6409edfe36f0153b976e9c63af42cbc37ad9c..f99c05b454b09f1ed1a7646178ccde517deef0b6 100644 (file)
@@ -382,8 +382,8 @@ static int gen_mjpeghdr_to_package(struct go7007 *go, __le16 *code, int space)
 
        buf = kzalloc(4096, GFP_KERNEL);
        if (buf == NULL) {
-               printk(KERN_ERR "go7007: unable to allocate 4096 bytes for "
-                               "firmware construction\n");
+               dev_err(go->dev,
+                       "unable to allocate 4096 bytes for firmware construction\n");
                return -1;
        }
 
@@ -652,8 +652,8 @@ static int gen_mpeg1hdr_to_package(struct go7007 *go,
 
        buf = kzalloc(5120, GFP_KERNEL);
        if (buf == NULL) {
-               printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
-                               "firmware construction\n");
+               dev_err(go->dev,
+                       "unable to allocate 5120 bytes for firmware construction\n");
                return -1;
        }
        framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
@@ -839,8 +839,8 @@ static int gen_mpeg4hdr_to_package(struct go7007 *go,
 
        buf = kzalloc(5120, GFP_KERNEL);
        if (buf == NULL) {
-               printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
-                               "firmware construction\n");
+               dev_err(go->dev,
+                       "unable to allocate 5120 bytes for firmware construction\n");
                return -1;
        }
        framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
@@ -1545,9 +1545,8 @@ static int do_special(struct go7007 *go, u16 type, __le16 *code, int space,
        case SPECIAL_MODET:
                return modet_to_package(go, code, space);
        }
-       printk(KERN_ERR
-               "go7007: firmware file contains unsupported feature %04x\n",
-               type);
+       dev_err(go->dev,
+               "firmware file contains unsupported feature %04x\n", type);
        return -1;
 }
 
@@ -1577,15 +1576,16 @@ int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
                return -1;
        }
        if (request_firmware(&fw_entry, go->board_info->firmware, go->dev)) {
-               printk(KERN_ERR
-                       "go7007: unable to load firmware from file \"%s\"\n",
+               dev_err(go->dev,
+                       "unable to load firmware from file \"%s\"\n",
                        go->board_info->firmware);
                return -1;
        }
        code = kzalloc(codespace * 2, GFP_KERNEL);
        if (code == NULL) {
-               printk(KERN_ERR "go7007: unable to allocate %d bytes for "
-                               "firmware construction\n", codespace * 2);
+               dev_err(go->dev,
+                       "unable to allocate %d bytes for firmware construction\n",
+                       codespace * 2);
                goto fw_failed;
        }
        src = (__le16 *)fw_entry->data;
@@ -1594,9 +1594,9 @@ int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
                chunk_flags = __le16_to_cpu(src[0]);
                chunk_len = __le16_to_cpu(src[1]);
                if (chunk_len + 2 > srclen) {
-                       printk(KERN_ERR "go7007: firmware file \"%s\" "
-                                       "appears to be corrupted\n",
-                                       go->board_info->firmware);
+                       dev_err(go->dev,
+                               "firmware file \"%s\" appears to be corrupted\n",
+                               go->board_info->firmware);
                        goto fw_failed;
                }
                if (chunk_flags & mode_flag) {
@@ -1604,17 +1604,15 @@ int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
                                ret = do_special(go, __le16_to_cpu(src[2]),
                                        &code[i], codespace - i, framelen);
                                if (ret < 0) {
-                                       printk(KERN_ERR "go7007: insufficient "
-                                                       "memory for firmware "
-                                                       "construction\n");
+                                       dev_err(go->dev,
+                                               "insufficient memory for firmware construction\n");
                                        goto fw_failed;
                                }
                                i += ret;
                        } else {
                                if (codespace - i < chunk_len) {
-                                       printk(KERN_ERR "go7007: insufficient "
-                                                       "memory for firmware "
-                                                       "construction\n");
+                                       dev_err(go->dev,
+                                               "insufficient memory for firmware construction\n");
                                        goto fw_failed;
                                }
                                memcpy(&code[i], &src[2], chunk_len * 2);
index 980371b0274966b45b71a38621f4452e8bf0cf72..a78133b67de2049f80190d3a2672c6fadbcaa68a 100644 (file)
@@ -812,7 +812,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
                return retval;
 
        mutex_lock(&gofh->lock);
-       if (buf->index < 0 || buf->index >= gofh->buf_count)
+       if (buf->index >= gofh->buf_count)
                goto unlock_and_return;
 
        gobuf = &gofh->bufs[buf->index];
index 014d38410c99bec9e100132fa875abd7938a33a9..b3974100c6cdccd0899da64fa8d5a2d9915365aa 100644 (file)
@@ -688,15 +688,4 @@ static struct i2c_driver s2250_driver = {
        .id_table       = s2250_id,
 };
 
-static __init int init_s2250(void)
-{
-       return i2c_add_driver(&s2250_driver);
-}
-
-static __exit void exit_s2250(void)
-{
-       i2c_del_driver(&s2250_driver);
-}
-
-module_init(init_s2250);
-module_exit(exit_s2250);
+module_i2c_driver(s2250_driver);
index 6bc9470fecb6f13de14d8bb1106a5209525f1102..9f01657f884ad5cbbccc29a6f3339e56fbe58dd0 100644 (file)
@@ -29,8 +29,7 @@ struct wis_ov7640 {
        int hue;
 };
 
-static u8 initial_registers[] =
-{
+static u8 initial_registers[] = {
        0x12, 0x80,
        0x12, 0x54,
        0x14, 0x24,
@@ -60,12 +59,12 @@ static int wis_ov7640_probe(struct i2c_client *client,
 
        client->flags = I2C_CLIENT_SCCB;
 
-       printk(KERN_DEBUG
+       dev_dbg(&client->dev,
                "wis-ov7640: initializing OV7640 at address %d on %s\n",
                client->addr, adapter->name);
 
        if (write_regs(client, initial_registers) < 0) {
-               printk(KERN_ERR "wis-ov7640: error initializing OV7640\n");
+               dev_err(&client->dev, "wis-ov7640: error initializing OV7640\n");
                return -ENODEV;
        }
 
@@ -92,17 +91,6 @@ static struct i2c_driver wis_ov7640_driver = {
        .id_table       = wis_ov7640_id,
 };
 
-static int __init wis_ov7640_init(void)
-{
-       return i2c_add_driver(&wis_ov7640_driver);
-}
-
-static void __exit wis_ov7640_cleanup(void)
-{
-       i2c_del_driver(&wis_ov7640_driver);
-}
-
-module_init(wis_ov7640_init);
-module_exit(wis_ov7640_cleanup);
+module_i2c_driver(wis_ov7640_driver);
 
 MODULE_LICENSE("GPL v2");
index 05e0e108386427b4ee22677707f373fd699bda65..8810c1e6e1ed0e1253fb4539cf1cb17bc1dd550f 100644 (file)
@@ -32,8 +32,7 @@ struct wis_saa7113 {
        int hue;
 };
 
-static u8 initial_registers[] =
-{
+static u8 initial_registers[] = {
        0x01, 0x08,
        0x02, 0xc0,
        0x03, 0x33,
@@ -282,12 +281,12 @@ static int wis_saa7113_probe(struct i2c_client *client,
        dec->hue = 0;
        i2c_set_clientdata(client, dec);
 
-       printk(KERN_DEBUG
+       dev_dbg(&client->dev,
                "wis-saa7113: initializing SAA7113 at address %d on %s\n",
                client->addr, adapter->name);
 
        if (write_regs(client, initial_registers) < 0) {
-               printk(KERN_ERR
+               dev_err(&client->dev,
                        "wis-saa7113: error initializing SAA7113\n");
                kfree(dec);
                return -ENODEV;
@@ -320,17 +319,6 @@ static struct i2c_driver wis_saa7113_driver = {
        .id_table       = wis_saa7113_id,
 };
 
-static int __init wis_saa7113_init(void)
-{
-       return i2c_add_driver(&wis_saa7113_driver);
-}
-
-static void __exit wis_saa7113_cleanup(void)
-{
-       i2c_del_driver(&wis_saa7113_driver);
-}
-
-module_init(wis_saa7113_init);
-module_exit(wis_saa7113_cleanup);
+module_i2c_driver(wis_saa7113_driver);
 
 MODULE_LICENSE("GPL v2");
index 46cff59e28b7faddddd41c259c3d56815dc446cc..fa86acd3fdf0d6f80dd9c9be1c50baa265bc2d7f 100644 (file)
@@ -32,8 +32,7 @@ struct wis_saa7115 {
        int hue;
 };
 
-static u8 initial_registers[] =
-{
+static u8 initial_registers[] = {
        0x01, 0x08,
        0x02, 0xc0,
        0x03, 0x20,
@@ -415,12 +414,12 @@ static int wis_saa7115_probe(struct i2c_client *client,
        dec->hue = 0;
        i2c_set_clientdata(client, dec);
 
-       printk(KERN_DEBUG
+       dev_dbg(&client->dev,
                "wis-saa7115: initializing SAA7115 at address %d on %s\n",
                client->addr, adapter->name);
 
        if (write_regs(client, initial_registers) < 0) {
-               printk(KERN_ERR
+               dev_err(&client->dev,
                        "wis-saa7115: error initializing SAA7115\n");
                kfree(dec);
                return -ENODEV;
@@ -453,17 +452,6 @@ static struct i2c_driver wis_saa7115_driver = {
        .id_table       = wis_saa7115_id,
 };
 
-static int __init wis_saa7115_init(void)
-{
-       return i2c_add_driver(&wis_saa7115_driver);
-}
-
-static void __exit wis_saa7115_cleanup(void)
-{
-       i2c_del_driver(&wis_saa7115_driver);
-}
-
-module_init(wis_saa7115_init);
-module_exit(wis_saa7115_cleanup);
+module_i2c_driver(wis_saa7115_driver);
 
 MODULE_LICENSE("GPL v2");
index 8f1b7d4f6a2e976504a849c262d462b0916a2b49..1291ab79d2af1189f5e5f319fab87097de6ac96c 100644 (file)
@@ -704,17 +704,6 @@ static struct i2c_driver wis_sony_tuner_driver = {
        .id_table       = wis_sony_tuner_id,
 };
 
-static int __init wis_sony_tuner_init(void)
-{
-       return i2c_add_driver(&wis_sony_tuner_driver);
-}
-
-static void __exit wis_sony_tuner_cleanup(void)
-{
-       i2c_del_driver(&wis_sony_tuner_driver);
-}
-
-module_init(wis_sony_tuner_init);
-module_exit(wis_sony_tuner_cleanup);
+module_i2c_driver(wis_sony_tuner_driver);
 
 MODULE_LICENSE("GPL v2");
index 9134f03e3cf092aa36d4d918cc897f14a9d32172..d6410ee01be86fbaee8dbb9428d1313d9ed917b2 100644 (file)
@@ -341,17 +341,6 @@ static struct i2c_driver wis_tw2804_driver = {
        .id_table       = wis_tw2804_id,
 };
 
-static int __init wis_tw2804_init(void)
-{
-       return i2c_add_driver(&wis_tw2804_driver);
-}
-
-static void __exit wis_tw2804_cleanup(void)
-{
-       i2c_del_driver(&wis_tw2804_driver);
-}
-
-module_init(wis_tw2804_init);
-module_exit(wis_tw2804_cleanup);
+module_i2c_driver(wis_tw2804_driver);
 
 MODULE_LICENSE("GPL v2");
index 9230f4a8052926c13de75810aab6d40c00992814..94071def3bb47dd93bbeef5a0e8f8fe3e7a183df 100644 (file)
@@ -325,17 +325,6 @@ static struct i2c_driver wis_tw9903_driver = {
        .id_table       = wis_tw9903_id,
 };
 
-static int __init wis_tw9903_init(void)
-{
-       return i2c_add_driver(&wis_tw9903_driver);
-}
-
-static void __exit wis_tw9903_cleanup(void)
-{
-       i2c_del_driver(&wis_tw9903_driver);
-}
-
-module_init(wis_tw9903_init);
-module_exit(wis_tw9903_cleanup);
+module_i2c_driver(wis_tw9903_driver);
 
 MODULE_LICENSE("GPL v2");
index 0127be2f3be0b68135aaa1ceeb3e75cac5a98536..05ac798f35f7d3aca908bc8d8989c0bd0756a845 100644 (file)
@@ -98,17 +98,6 @@ static struct i2c_driver wis_uda1342_driver = {
        .id_table       = wis_uda1342_id,
 };
 
-static int __init wis_uda1342_init(void)
-{
-       return i2c_add_driver(&wis_uda1342_driver);
-}
-
-static void __exit wis_uda1342_cleanup(void)
-{
-       i2c_del_driver(&wis_uda1342_driver);
-}
-
-module_init(wis_uda1342_init);
-module_exit(wis_uda1342_cleanup);
+module_i2c_driver(wis_uda1342_driver);
 
 MODULE_LICENSE("GPL v2");
index 71e3bf2937f9bf0ffc0674f491d5ad67532c1d56..b5d0088f3102a4fb52062a5a4d528634b77eaa7b 100644 (file)
@@ -1239,6 +1239,10 @@ static int __init lirc_serial_init_module(void)
                }
        }
 
+       /* make sure sense is either -1, 0, or 1 */
+       if (sense != -1)
+               sense = !!sense;
+
        result = lirc_serial_init();
        if (result)
                return result;
@@ -1298,7 +1302,7 @@ MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
 module_param(share_irq, bool, S_IRUGO);
 MODULE_PARM_DESC(share_irq, "Share interrupts (0 = off, 1 = on)");
 
-module_param(sense, bool, S_IRUGO);
+module_param(sense, int, S_IRUGO);
 MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
                 " (0 = active high, 1 = active low )");
 
diff --git a/include/linux/dvb/Kbuild b/include/linux/dvb/Kbuild
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h
deleted file mode 100644 (file)
index 0be6d8f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * dmx.h
- *
- * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
- *                  & Ralph  Metzler <ralph@convergence.de>
- *                    for convergence integrated media GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- */
-#ifndef _DVBDMX_H_
-#define _DVBDMX_H_
-
-#include <linux/time.h>
-#include <uapi/linux/dvb/dmx.h>
-
-#endif /*_DVBDMX_H_*/
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h
deleted file mode 100644 (file)
index 85c20d9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * video.h
- *
- * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
- *                  & Ralph  Metzler <ralph@convergence.de>
- *                    for convergence integrated media GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- */
-#ifndef _DVBVIDEO_H_
-#define _DVBVIDEO_H_
-
-#include <linux/compiler.h>
-#include <uapi/linux/dvb/video.h>
-
-#endif /*_DVBVIDEO_H_*/
index 50a1af88aed0b9b6d04d408bc5201fbd7876898e..1d9b48a3bd80aa0def7af5e8d76a7ecd28cdea59 100644 (file)
@@ -3,10 +3,10 @@
  *
  * Copyright (C) 2008--2011 Nokia Corporation
  *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
  *
  * Contributors:
- *     Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ *     Sakari Ailus <sakari.ailus@iki.fi>
  *     Tuukka Toivonen <tuukkat76@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
index dbf6b37682cd1c70f40b4bd06b8f99dc375527f0..8dffffedbb590ecaf7a5454fad2d84d21a557ebb 100644 (file)
@@ -16,7 +16,7 @@
 /* Header files */
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
-#include <media/videobuf-dma-contig.h>
+#include <media/videobuf2-dma-contig.h>
 #include <media/davinci/vpbe_types.h>
 #include <media/davinci/vpbe_osd.h>
 #include <media/davinci/vpbe.h>
@@ -62,6 +62,11 @@ struct display_layer_info {
        enum osd_v_exp_ratio v_exp;
 };
 
+struct vpbe_disp_buffer {
+       struct vb2_buffer vb;
+       struct list_head list;
+};
+
 /* vpbe display object structure */
 struct vpbe_layer {
        /* number of buffers in fbuffers */
@@ -69,13 +74,15 @@ struct vpbe_layer {
        /* Pointer to the vpbe_display */
        struct vpbe_display *disp_dev;
        /* Pointer pointing to current v4l2_buffer */
-       struct videobuf_buffer *cur_frm;
+       struct vpbe_disp_buffer *cur_frm;
        /* Pointer pointing to next v4l2_buffer */
-       struct videobuf_buffer *next_frm;
+       struct vpbe_disp_buffer *next_frm;
        /* videobuf specific parameters
         * Buffer queue used in video-buf
         */
-       struct videobuf_queue buffer_queue;
+       struct vb2_queue buffer_queue;
+       /* allocator-specific contexts for each plane */
+       struct vb2_alloc_ctx *alloc_ctx;
        /* Queue of filled frames */
        struct list_head dma_queue;
        /* Used in video-buf */
index d7e397a444e68baa9a240646d927f692719b251c..5ab0d8d41f6827b6cd582e669e536de3b106ee69 100644 (file)
@@ -357,7 +357,7 @@ struct osd_state {
        spinlock_t lock;
        struct device *dev;
        dma_addr_t osd_base_phys;
-       unsigned long osd_base;
+       void __iomem *osd_base;
        unsigned long osd_size;
        /* 1-->the isr will toggle the VID0 ping-pong buffer */
        int pingpong;
index 768aa77925cd952049cff78ae1c6ff8116369d90..e221bc74020b2f5505e02f114789bb24a46d2fd1 100644 (file)
@@ -37,7 +37,7 @@ enum ir_kbd_get_key_fn {
 struct IR_i2c_init_data {
        char                    *ir_codes;
        const char              *name;
-       u64                     type; /* RC_TYPE_RC5, etc */
+       u64                     type; /* RC_BIT_RC5, etc */
        u32                     polling_interval; /* 0 means DEFAULT_POLLING_INTERVAL */
 
        /*
diff --git a/include/media/mt9v022.h b/include/media/mt9v022.h
new file mode 100644 (file)
index 0000000..4056180
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * mt9v022 sensor
+ *
+ * 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 __MT9V022_H__
+#define __MT9V022_H__
+
+struct mt9v022_platform_data {
+       unsigned short y_skip_top;      /* Lines to skip at the top */
+};
+
+#endif
index b0c494a6907904b9ceb38dac8be868f06b276d5a..f03445f3c767d662b2b08bb57830cfd1ae8c3892 100644 (file)
@@ -50,7 +50,7 @@ enum rc_driver_type {
  * @input_dev: the input child device used to communicate events to userspace
  * @driver_type: specifies if protocol decoding is done in hardware or software
  * @idle: used to keep track of RX state
- * @allowed_protos: bitmask with the supported RC_TYPE_* protocols
+ * @allowed_protos: bitmask with the supported RC_BIT_* protocols
  * @scanmask: some hardware decoders are not capable of providing the full
  *     scancode to the application. As this is a hardware limit, we can't do
  *     anything with it. Yet, as the same keycode table can be used with other
@@ -113,7 +113,7 @@ struct rc_dev {
        u32                             max_timeout;
        u32                             rx_resolution;
        u32                             tx_resolution;
-       int                             (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       int                             (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
        int                             (*open)(struct rc_dev *dev);
        void                            (*close)(struct rc_dev *dev);
        int                             (*s_tx_mask)(struct rc_dev *dev, u32 mask);
index cfd5163ff7f3dc7dfb95cbe4ac8b00141a0cd9db..74f55a3f14eb80905186e927bd1d5f34bef070c6 100644 (file)
 
 #include <linux/input.h>
 
-#define RC_TYPE_UNKNOWN        0
-#define RC_TYPE_RC5    (1  << 0)       /* Philips RC5 protocol */
-#define RC_TYPE_NEC    (1  << 1)
-#define RC_TYPE_RC6    (1  << 2)       /* Philips RC6 protocol */
-#define RC_TYPE_JVC    (1  << 3)       /* JVC protocol */
-#define RC_TYPE_SONY   (1  << 4)       /* Sony12/15/20 protocol */
-#define RC_TYPE_RC5_SZ (1  << 5)       /* RC5 variant used by Streamzap */
-#define RC_TYPE_SANYO   (1  << 6)      /* Sanyo protocol */
-#define RC_TYPE_MCE_KBD        (1  << 29)      /* RC6-ish MCE keyboard/mouse */
-#define RC_TYPE_LIRC   (1  << 30)      /* Pass raw IR to lirc userspace */
-#define RC_TYPE_OTHER  (1u << 31)
+enum rc_type {
+       RC_TYPE_UNKNOWN         = 0,    /* Protocol not known */
+       RC_TYPE_OTHER           = 1,    /* Protocol known but proprietary */
+       RC_TYPE_LIRC            = 2,    /* Pass raw IR to lirc userspace */
+       RC_TYPE_RC5             = 3,    /* Philips RC5 protocol */
+       RC_TYPE_RC5X            = 4,    /* Philips RC5x protocol */
+       RC_TYPE_RC5_SZ          = 5,    /* StreamZap variant of RC5 */
+       RC_TYPE_JVC             = 6,    /* JVC protocol */
+       RC_TYPE_SONY12          = 7,    /* Sony 12 bit protocol */
+       RC_TYPE_SONY15          = 8,    /* Sony 15 bit protocol */
+       RC_TYPE_SONY20          = 9,    /* Sony 20 bit protocol */
+       RC_TYPE_NEC             = 10,   /* NEC protocol */
+       RC_TYPE_SANYO           = 11,   /* Sanyo protocol */
+       RC_TYPE_MCE_KBD         = 12,   /* RC6-ish MCE keyboard/mouse */
+       RC_TYPE_RC6_0           = 13,   /* Philips RC6-0-16 protocol */
+       RC_TYPE_RC6_6A_20       = 14,   /* Philips RC6-6A-20 protocol */
+       RC_TYPE_RC6_6A_24       = 15,   /* Philips RC6-6A-24 protocol */
+       RC_TYPE_RC6_6A_32       = 16,   /* Philips RC6-6A-32 protocol */
+       RC_TYPE_RC6_MCE         = 17,   /* MCE (Philips RC6-6A-32 subtype) protocol */
+};
+
+#define RC_BIT_NONE            0
+#define RC_BIT_UNKNOWN         (1 << RC_TYPE_UNKNOWN)
+#define RC_BIT_OTHER           (1 << RC_TYPE_OTHER)
+#define RC_BIT_LIRC            (1 << RC_TYPE_LIRC)
+#define RC_BIT_RC5             (1 << RC_TYPE_RC5)
+#define RC_BIT_RC5X            (1 << RC_TYPE_RC5X)
+#define RC_BIT_RC5_SZ          (1 << RC_TYPE_RC5_SZ)
+#define RC_BIT_JVC             (1 << RC_TYPE_JVC)
+#define RC_BIT_SONY12          (1 << RC_TYPE_SONY12)
+#define RC_BIT_SONY15          (1 << RC_TYPE_SONY15)
+#define RC_BIT_SONY20          (1 << RC_TYPE_SONY20)
+#define RC_BIT_NEC             (1 << RC_TYPE_NEC)
+#define RC_BIT_SANYO           (1 << RC_TYPE_SANYO)
+#define RC_BIT_MCE_KBD         (1 << RC_TYPE_MCE_KBD)
+#define RC_BIT_RC6_0           (1 << RC_TYPE_RC6_0)
+#define RC_BIT_RC6_6A_20       (1 << RC_TYPE_RC6_6A_20)
+#define RC_BIT_RC6_6A_24       (1 << RC_TYPE_RC6_6A_24)
+#define RC_BIT_RC6_6A_32       (1 << RC_TYPE_RC6_6A_32)
+#define RC_BIT_RC6_MCE         (1 << RC_TYPE_RC6_MCE)
 
-#define RC_TYPE_ALL (RC_TYPE_RC5    | RC_TYPE_NEC   | RC_TYPE_RC6     | \
-                    RC_TYPE_JVC    | RC_TYPE_SONY  | RC_TYPE_LIRC    | \
-                    RC_TYPE_RC5_SZ | RC_TYPE_SANYO | RC_TYPE_MCE_KBD | \
-                    RC_TYPE_OTHER)
+#define RC_BIT_ALL     (RC_BIT_UNKNOWN | RC_BIT_OTHER | RC_BIT_LIRC | \
+                        RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ | \
+                        RC_BIT_JVC | \
+                        RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \
+                        RC_BIT_NEC | RC_BIT_SANYO | RC_BIT_MCE_KBD | \
+                        RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \
+                        RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE)
 
 struct rc_map_table {
        u32     scancode;
@@ -38,7 +70,7 @@ struct rc_map {
        unsigned int            size;   /* Max number of entries */
        unsigned int            len;    /* Used number of entries */
        unsigned int            alloc;  /* Size of *scan in bytes */
-       u64                     rc_type;
+       enum rc_type            rc_type;
        const char              *name;
        spinlock_t              lock;
 };
diff --git a/include/media/s3c_camif.h b/include/media/s3c_camif.h
new file mode 100644 (file)
index 0000000..df96c2c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * s3c24xx/s3c64xx SoC series Camera Interface (CAMIF) driver
+ *
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.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 MEDIA_S3C_CAMIF_
+#define MEDIA_S3C_CAMIF_
+
+#include <linux/i2c.h>
+#include <media/v4l2-mediabus.h>
+
+/**
+ * struct s3c_camif_sensor_info - an image sensor description
+ * @i2c_board_info: pointer to an I2C sensor subdevice board info
+ * @clock_frequency: frequency of the clock the host provides to a sensor
+ * @mbus_type: media bus type
+ * @i2c_bus_num: i2c control bus id the sensor is attached to
+ * @flags: the parallel bus flags defining signals polarity (V4L2_MBUS_*)
+ * @use_field: 1 if parallel bus FIELD signal is used (only s3c64xx)
+ */
+struct s3c_camif_sensor_info {
+       struct i2c_board_info i2c_board_info;
+       unsigned long clock_frequency;
+       enum v4l2_mbus_type mbus_type;
+       u16 i2c_bus_num;
+       u16 flags;
+       u8 use_field;
+};
+
+struct s3c_camif_plat_data {
+       struct s3c_camif_sensor_info sensor;
+       int (*gpio_get)(void);
+       int (*gpio_put)(void);
+};
+
+/* Platform default helper functions */
+int s3c_camif_gpio_get(void);
+int s3c_camif_gpio_put(void);
+
+#endif /* MEDIA_S3C_CAMIF_ */
index 9ab07fd45d5cd1f71af1c5a8d98b90c5ff5794ba..07f96a89e189fa2a9414ca3ca8bb201b43b21ff4 100644 (file)
@@ -4,7 +4,7 @@
  * Generic driver for SMIA/SMIA++ compliant camera modules
  *
  * Copyright (C) 2011--2012 Nokia Corporation
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index e7c5d170a9cd48c42ae8876d279c1be1dd0479ec..eff85f934b247a70f6a4cd6cd0b445ad79f23663 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 2009--2010 Nokia Corporation.
  *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index 52513c225c182c6d8d5a4906b78a40a45834f112..a62ee18cb7b799c3982decdb63dc57f520e9b93a 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (C) 2009--2010 Nokia Corporation.
  *
- * Contact: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
+ * 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
index e48b571ca37d512111125bd8f49463622b38aae2..4118ad1324c91a20dcdf8afafa080b9619986695 100644 (file)
@@ -111,6 +111,8 @@ struct v4l2_ioctl_ops {
        int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b);
        int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer *b);
        int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
+       int (*vidioc_expbuf)  (struct file *file, void *fh,
+                               struct v4l2_exportbuffer *e);
        int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
 
        int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
index 131cc4a53675eb97f14c7cd4c5355e06640200d7..7e82d2b193d5625702594fe59f1484e1b09c3d06 100644 (file)
@@ -111,6 +111,9 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
 int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
                   struct v4l2_buffer *buf);
 
+int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+                  struct v4l2_exportbuffer *eb);
+
 int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
                      enum v4l2_buf_type type);
 int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
index e04252a9fea65e5f5db25a901368e82a3aa8b4d6..9cfd4ee9e56f1eb7dec09704b15a4fabcbb976a4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mutex.h>
 #include <linux/poll.h>
 #include <linux/videodev2.h>
+#include <linux/dma-buf.h>
 
 struct vb2_alloc_ctx;
 struct vb2_fileio_data;
@@ -41,6 +42,24 @@ struct vb2_fileio_data;
  *              argument to other ops in this structure
  * @put_userptr: inform the allocator that a USERPTR buffer will no longer
  *              be used
+ * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation;
+ *                used for DMABUF memory types; alloc_ctx is the alloc context
+ *                dbuf is the shared dma_buf; returns NULL on failure;
+ *                allocator private per-buffer structure on success;
+ *                this needs to be used for further accesses to the buffer
+ * @detach_dmabuf: inform the exporter of the buffer that the current DMABUF
+ *                buffer is no longer used; the buf_priv argument is the
+ *                allocator private per-buffer structure previously returned
+ *                from the attach_dmabuf callback
+ * @map_dmabuf: request for access to the dmabuf from allocator; the allocator
+ *             of dmabuf is informed that this driver is going to use the
+ *             dmabuf
+ * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
+ *               that this driver is done using the dmabuf for now
+ * @prepare:   called every time the buffer is passed from userspace to the
+ *             driver, useful for cache synchronisation, optional
+ * @finish:    called every time the buffer is passed back from the driver
+ *             to the userspace, also optional
  * @vaddr:     return a kernel virtual address to a given memory buffer
  *             associated with the passed private structure or NULL if no
  *             such mapping exists
@@ -56,15 +75,27 @@ struct vb2_fileio_data;
  * Required ops for USERPTR types: get_userptr, put_userptr.
  * Required ops for MMAP types: alloc, put, num_users, mmap.
  * Required ops for read/write access types: alloc, put, num_users, vaddr
+ * Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, map_dmabuf,
+ *                               unmap_dmabuf.
  */
 struct vb2_mem_ops {
        void            *(*alloc)(void *alloc_ctx, unsigned long size);
        void            (*put)(void *buf_priv);
+       struct dma_buf *(*get_dmabuf)(void *buf_priv);
 
        void            *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
                                        unsigned long size, int write);
        void            (*put_userptr)(void *buf_priv);
 
+       void            (*prepare)(void *buf_priv);
+       void            (*finish)(void *buf_priv);
+
+       void            *(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf,
+                               unsigned long size, int write);
+       void            (*detach_dmabuf)(void *buf_priv);
+       int             (*map_dmabuf)(void *buf_priv);
+       void            (*unmap_dmabuf)(void *buf_priv);
+
        void            *(*vaddr)(void *buf_priv);
        void            *(*cookie)(void *buf_priv);
 
@@ -75,6 +106,8 @@ struct vb2_mem_ops {
 
 struct vb2_plane {
        void                    *mem_priv;
+       struct dma_buf          *dbuf;
+       unsigned int            dbuf_mapped;
 };
 
 /**
@@ -83,12 +116,14 @@ struct vb2_plane {
  * @VB2_USERPTR:       driver supports USERPTR with streaming API
  * @VB2_READ:          driver supports read() style access
  * @VB2_WRITE:         driver supports write() style access
+ * @VB2_DMABUF:                driver supports DMABUF with streaming API
  */
 enum vb2_io_modes {
        VB2_MMAP        = (1 << 0),
        VB2_USERPTR     = (1 << 1),
        VB2_READ        = (1 << 2),
        VB2_WRITE       = (1 << 3),
+       VB2_DMABUF      = (1 << 4),
 };
 
 /**
@@ -329,6 +364,7 @@ int __must_check vb2_queue_init(struct vb2_queue *q);
 void vb2_queue_release(struct vb2_queue *q);
 
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
 
 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
@@ -438,6 +474,8 @@ int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
 int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p);
 int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i);
 int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i);
+int vb2_ioctl_expbuf(struct file *file, void *priv,
+       struct v4l2_exportbuffer *p);
 
 /* struct v4l2_file_operations helpers */
 
index 84e1f6c031c53515367ef0ba26d641f2f6ff212c..f05444ca8c0cd4f8bf0469b3a4b0fe978fc359cc 100644 (file)
@@ -33,11 +33,6 @@ extern const struct vm_operations_struct vb2_common_vm_ops;
 int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
                           struct vm_area_struct **res_vma, dma_addr_t *res_pa);
 
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-                               unsigned long size,
-                               const struct vm_operations_struct *vm_ops,
-                               void *priv);
-
 struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
 void vb2_put_vma(struct vm_area_struct *vma);
 
index 57bfa59cda74f3add633e7f6c0a7f6da9879b0b3..3cf3e946e331ee6ee006b03b5d569dc24719438b 100644 (file)
@@ -186,6 +186,7 @@ enum v4l2_memory {
        V4L2_MEMORY_MMAP             = 1,
        V4L2_MEMORY_USERPTR          = 2,
        V4L2_MEMORY_OVERLAY          = 3,
+       V4L2_MEMORY_DMABUF           = 4,
 };
 
 /* see also http://vektor.theorem.ca/graphics/ycbcr/ */
@@ -602,6 +603,8 @@ struct v4l2_requestbuffers {
  *                     should be passed to mmap() called on the video node)
  * @userptr:           when memory is V4L2_MEMORY_USERPTR, a userspace pointer
  *                     pointing to this plane
+ * @fd:                        when memory is V4L2_MEMORY_DMABUF, a userspace file
+ *                     descriptor associated with this plane
  * @data_offset:       offset in the plane to the start of data; usually 0,
  *                     unless there is a header in front of the data
  *
@@ -616,6 +619,7 @@ struct v4l2_plane {
        union {
                __u32           mem_offset;
                unsigned long   userptr;
+               __s32           fd;
        } m;
        __u32                   data_offset;
        __u32                   reserved[11];
@@ -640,6 +644,8 @@ struct v4l2_plane {
  *             (or a "cookie" that should be passed to mmap() as offset)
  * @userptr:   for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
  *             a userspace pointer pointing to this buffer
+ * @fd:                for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF;
+ *             a userspace file descriptor associated with this buffer
  * @planes:    for multiplanar buffers; userspace pointer to the array of plane
  *             info structs for this buffer
  * @length:    size in bytes of the buffer (NOT its payload) for single-plane
@@ -666,6 +672,7 @@ struct v4l2_buffer {
                __u32           offset;
                unsigned long   userptr;
                struct v4l2_plane *planes;
+               __s32           fd;
        } m;
        __u32                   length;
        __u32                   reserved2;
@@ -687,6 +694,33 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE      0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN           0x1000
 
+/**
+ * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
+ *
+ * @index:     id number of the buffer
+ * @type:      enum v4l2_buf_type; buffer type (type == *_MPLANE for
+ *             multiplanar buffers);
+ * @plane:     index of the plane to be exported, 0 for single plane queues
+ * @flags:     flags for newly created file, currently only O_CLOEXEC is
+ *             supported, refer to manual of open syscall for more details
+ * @fd:                file descriptor associated with DMABUF (set by driver)
+ *
+ * Contains data used for exporting a video buffer as DMABUF file descriptor.
+ * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
+ * (identical to the cookie used to mmap() the buffer to userspace). All
+ * reserved fields must be set to zero. The field reserved0 is expected to
+ * become a structure 'type' allowing an alternative layout of the structure
+ * content. Therefore this field should not be used for any other extensions.
+ */
+struct v4l2_exportbuffer {
+       __u32           type; /* enum v4l2_buf_type */
+       __u32           index;
+       __u32           plane;
+       __u32           flags;
+       __s32           fd;
+       __u32           reserved[11];
+};
+
 /*
  *     O V E R L A Y   P R E V I E W
  */
@@ -737,7 +771,7 @@ struct v4l2_window {
 struct v4l2_captureparm {
        __u32              capability;    /*  Supported modes */
        __u32              capturemode;   /*  Current mode */
-       struct v4l2_fract  timeperframe;  /*  Time per frame in .1us units */
+       struct v4l2_fract  timeperframe;  /*  Time per frame in seconds */
        __u32              extendedmode;  /*  Driver-specific extensions */
        __u32              readbuffers;   /*  # of buffers for read */
        __u32              reserved[4];
@@ -1888,6 +1922,7 @@ struct v4l2_create_buffers {
 #define VIDIOC_S_FBUF           _IOW('V', 11, struct v4l2_framebuffer)
 #define VIDIOC_OVERLAY          _IOW('V', 14, int)
 #define VIDIOC_QBUF            _IOWR('V', 15, struct v4l2_buffer)
+#define VIDIOC_EXPBUF          _IOWR('V', 16, struct v4l2_exportbuffer)
 #define VIDIOC_DQBUF           _IOWR('V', 17, struct v4l2_buffer)
 #define VIDIOC_STREAMON                 _IOW('V', 18, int)
 #define VIDIOC_STREAMOFF        _IOW('V', 19, int)
This page took 0.31791 seconds and 5 git commands to generate.