Bläddra i källkod

Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media into next

Pull media updates from Mauro Carvalho Chehab:
 "This contains:
   - a new frontend/tuner driver set for si2168 and sa2157
   - Videobuf 2 core now supports DVB too
   - A new gspca sub-driver (dtcs033)
   - saa7134 is now converted to use videobuf2
   - add support for 4K timings
   - several other driver fixes and improvements

  PS.  This pull request is shorter than usual, partly because I have
  some other patches on topic branches that I'll be sending you later
  this week"

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (286 commits)
  [media] au0828-dvb: restore its permission to 644
  [media] xc5000: delay tuner sleep to 5 seconds
  [media] xc5000: Don't use whitespace before tabs
  [media] xc5000: fix CamelCase
  [media] xc5000: Don't wrap msleep()
  [media] xc5000: get rid of positive error codes
  [media] au0828: reset streaming when a new frequency is set
  [media] au0828: Improve debug messages for urb_completion
  [media] au0828: Cancel stream-restart operation if frontend is disconnected
  [media] dib0700: fix RC support on Hauppauge Nova-TD
  [media] USB: as102_usb_drv.c: Remove useless return variables
  [media] v4l: Fix documentation of V4L2_PIX_FMT_H264_MVC and VP8 pixel formats
  [media] m5mols: Replace missing header
  [media] staging: lirc: Fix sparse warnings
  [media] fix mceusb endpoint type identification/handling
  [media] az6027: Added the PID for a new revision of the Elgato EyeTV Sat DVB-S Tuner
  [media] DocBook media: fix typo
  [media] adv7604: Add missing include to linux/types.h
  [media] v4l: Validate fields in the core code for subdev EDID ioctls
  [media] v4l: Add support for DV timings ioctls on subdev nodes
  ...
Linus Torvalds 11 år sedan
förälder
incheckning
aaeb255433
100 ändrade filer med 3750 tillägg och 3091 borttagningar
  1. 12 3
      Documentation/DocBook/media/v4l/io.xml
  2. 4 4
      Documentation/DocBook/media/v4l/media-ioc-enum-links.xml
  3. 2 2
      Documentation/DocBook/media/v4l/pixfmt.xml
  4. 760 0
      Documentation/DocBook/media/v4l/subdev-formats.xml
  5. 33 0
      Documentation/DocBook/media/v4l/vidioc-dqevent.xml
  6. 22 5
      Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml
  7. 23 7
      Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml
  8. 20 0
      Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
  9. 2 1
      Documentation/devicetree/bindings/media/s5p-mfc.txt
  10. 1 0
      Documentation/video4linux/CARDLIST.bttv
  11. 1 0
      Documentation/video4linux/CARDLIST.em28xx
  12. 0 30
      Documentation/video4linux/fimc.txt
  13. 29 13
      Documentation/video4linux/v4l2-pci-skeleton.c
  14. 20 1
      MAINTAINERS
  15. 0 51
      arch/arm/mach-s5pv210/mach-goni.c
  16. 3 0
      drivers/media/dvb-core/dvb-usb-ids.h
  17. 7 0
      drivers/media/dvb-frontends/Kconfig
  18. 1 0
      drivers/media/dvb-frontends/Makefile
  19. 760 0
      drivers/media/dvb-frontends/si2168.c
  20. 39 0
      drivers/media/dvb-frontends/si2168.h
  21. 46 0
      drivers/media/dvb-frontends/si2168_priv.h
  22. 35 29
      drivers/media/i2c/ad9389b.c
  23. 1 1
      drivers/media/i2c/adv7180.c
  24. 2 2
      drivers/media/i2c/adv7183.c
  25. 36 30
      drivers/media/i2c/adv7511.c
  26. 0 4
      drivers/media/i2c/adv7604.c
  27. 17 11
      drivers/media/i2c/adv7842.c
  28. 1 1
      drivers/media/i2c/bt819.c
  29. 2 2
      drivers/media/i2c/cx25840/cx25840-core.c
  30. 1 5
      drivers/media/i2c/ks0127.c
  31. 1 1
      drivers/media/i2c/m5mols/m5mols_capture.c
  32. 1 1
      drivers/media/i2c/ml86v7667.c
  33. 1 1
      drivers/media/i2c/msp3400-driver.c
  34. 39 14
      drivers/media/i2c/mt9p031.c
  35. 1 1
      drivers/media/i2c/saa6752hs.c
  36. 1 1
      drivers/media/i2c/saa7110.c
  37. 1 1
      drivers/media/i2c/saa7115.c
  38. 1 1
      drivers/media/i2c/saa717x.c
  39. 1 1
      drivers/media/i2c/saa7191.c
  40. 1 1
      drivers/media/i2c/smiapp-pll.h
  41. 29 28
      drivers/media/i2c/smiapp/smiapp-core.c
  42. 7 48
      drivers/media/i2c/smiapp/smiapp-quirk.c
  43. 16 8
      drivers/media/i2c/smiapp/smiapp-quirk.h
  44. 4 4
      drivers/media/i2c/smiapp/smiapp-reg-defs.h
  45. 61 28
      drivers/media/i2c/smiapp/smiapp-regs.c
  46. 10 9
      drivers/media/i2c/smiapp/smiapp-regs.h
  47. 9 2
      drivers/media/i2c/soc_camera/tw9910.c
  48. 5 5
      drivers/media/i2c/sony-btf-mpx.c
  49. 10 0
      drivers/media/i2c/ths8200.c
  50. 5 1
      drivers/media/i2c/tvaudio.c
  51. 1 1
      drivers/media/i2c/tvp514x.c
  52. 3 3
      drivers/media/i2c/tvp5150.c
  53. 4 1
      drivers/media/i2c/tvp7002.c
  54. 1 1
      drivers/media/i2c/tw2804.c
  55. 1 1
      drivers/media/i2c/tw9903.c
  56. 1 1
      drivers/media/i2c/tw9906.c
  57. 5 1
      drivers/media/i2c/vp27smpx.c
  58. 1 1
      drivers/media/i2c/vpx3220.c
  59. 4 3
      drivers/media/media-device.c
  60. 3 2
      drivers/media/media-devnode.c
  61. 1 1
      drivers/media/parport/bw-qcam.c
  62. 110 0
      drivers/media/pci/bt8xx/bttv-cards.c
  63. 1 1
      drivers/media/pci/bt8xx/bttv-driver.c
  64. 1 0
      drivers/media/pci/bt8xx/bttv.h
  65. 10 10
      drivers/media/pci/bt8xx/dst.c
  66. 1 1
      drivers/media/pci/cx18/cx18-av-core.c
  67. 1 1
      drivers/media/pci/cx18/cx18-fileops.c
  68. 5 1
      drivers/media/pci/cx18/cx18-gpio.c
  69. 1 1
      drivers/media/pci/cx18/cx18-ioctl.c
  70. 2 2
      drivers/media/pci/cx23885/cx23885-video.c
  71. 1 1
      drivers/media/pci/cx88/cx88-core.c
  72. 6 0
      drivers/media/pci/ivtv/ivtv-alsa-pcm.c
  73. 1 1
      drivers/media/pci/ivtv/ivtv-fileops.c
  74. 1 1
      drivers/media/pci/ivtv/ivtv-ioctl.c
  75. 2 2
      drivers/media/pci/saa7134/Kconfig
  76. 92 15
      drivers/media/pci/saa7134/saa7134-alsa.c
  77. 67 63
      drivers/media/pci/saa7134/saa7134-core.c
  78. 27 23
      drivers/media/pci/saa7134/saa7134-dvb.c
  79. 69 118
      drivers/media/pci/saa7134/saa7134-empress.c
  80. 0 7
      drivers/media/pci/saa7134/saa7134-i2c.c
  81. 5 7
      drivers/media/pci/saa7134/saa7134-reg.h
  82. 108 83
      drivers/media/pci/saa7134/saa7134-ts.c
  83. 0 7
      drivers/media/pci/saa7134/saa7134-tvaudio.c
  84. 79 96
      drivers/media/pci/saa7134/saa7134-vbi.c
  85. 279 418
      drivers/media/pci/saa7134/saa7134-video.c
  86. 53 55
      drivers/media/pci/saa7134/saa7134.h
  87. 7 7
      drivers/media/pci/saa7146/mxb.c
  88. 3 4
      drivers/media/pci/sta2x11/sta2x11_vip.c
  89. 4 2
      drivers/media/pci/ttpci/av7110_av.c
  90. 1 1
      drivers/media/pci/zoran/zoran_device.c
  91. 1 1
      drivers/media/pci/zoran/zoran_driver.c
  92. 6 8
      drivers/media/platform/blackfin/bfin_capture.c
  93. 2 4
      drivers/media/platform/coda.c
  94. 19 36
      drivers/media/platform/davinci/vpbe_display.c
  95. 7 8
      drivers/media/platform/davinci/vpfe_capture.c
  96. 306 813
      drivers/media/platform/davinci/vpif_capture.c
  97. 0 28
      drivers/media/platform/davinci/vpif_capture.h
  98. 358 848
      drivers/media/platform/davinci/vpif_display.c
  99. 4 40
      drivers/media/platform/davinci/vpif_display.h
  100. 1 3
      drivers/media/platform/exynos-gsc/gsc-m2m.c

+ 12 - 3
Documentation/DocBook/media/v4l/io.xml

@@ -125,7 +125,7 @@ location of the buffers in device memory can be determined with the
 <structfield>m.offset</structfield> and <structfield>length</structfield>
 <structfield>m.offset</structfield> and <structfield>length</structfield>
 returned in a &v4l2-buffer; are passed as sixth and second parameter to the
 returned in a &v4l2-buffer; are passed as sixth and second parameter to the
 <function>mmap()</function> function. When using the multi-planar API,
 <function>mmap()</function> function. When using the multi-planar API,
-struct &v4l2-buffer; contains an array of &v4l2-plane; structures, each
+&v4l2-buffer; contains an array of &v4l2-plane; structures, each
 containing its own <structfield>m.offset</structfield> and
 containing its own <structfield>m.offset</structfield> and
 <structfield>length</structfield>. When using the multi-planar API, every
 <structfield>length</structfield>. When using the multi-planar API, every
 plane of every buffer has to be mapped separately, so the number of
 plane of every buffer has to be mapped separately, so the number of
@@ -699,7 +699,12 @@ linkend="v4l2-buf-type" /></entry>
 buffer. It depends on the negotiated data format and may change with
 buffer. It depends on the negotiated data format and may change with
 each buffer for compressed variable size data like JPEG images.
 each buffer for compressed variable size data like JPEG images.
 Drivers must set this field when <structfield>type</structfield>
 Drivers must set this field when <structfield>type</structfield>
-refers to an input stream, applications when it refers to an output stream.</entry>
+refers to an input stream, applications when it refers to an output stream.
+If the application sets this to 0 for an output stream, then
+<structfield>bytesused</structfield> will be set to the size of the
+buffer (see the <structfield>length</structfield> field of this struct) by
+the driver. For multiplanar formats this field is ignored and the
+<structfield>planes</structfield> pointer is used instead.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
@@ -861,7 +866,11 @@ should set this to 0.</entry>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry>The number of bytes occupied by data in the plane
 	    <entry>The number of bytes occupied by data in the plane
 	      (its payload). Drivers must set this field when <structfield>type</structfield>
 	      (its payload). Drivers must set this field when <structfield>type</structfield>
-	      refers to an input stream, applications when it refers to an output stream.</entry>
+	      refers to an input stream, applications when it refers to an output stream.
+	      If the application sets this to 0 for an output stream, then
+	      <structfield>bytesused</structfield> will be set to the size of the
+	      plane (see the <structfield>length</structfield> field of this struct)
+	      by the driver.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>

+ 4 - 4
Documentation/DocBook/media/v4l/media-ioc-enum-links.xml

@@ -79,13 +79,13 @@
 	    <entry>Entity id, set by the application.</entry>
 	    <entry>Entity id, set by the application.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
-	    <entry>struct &media-pad-desc;</entry>
+	    <entry>&media-pad-desc;</entry>
 	    <entry>*<structfield>pads</structfield></entry>
 	    <entry>*<structfield>pads</structfield></entry>
 	    <entry>Pointer to a pads array allocated by the application. Ignored
 	    <entry>Pointer to a pads array allocated by the application. Ignored
 	    if NULL.</entry>
 	    if NULL.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
-	    <entry>struct &media-link-desc;</entry>
+	    <entry>&media-link-desc;</entry>
 	    <entry>*<structfield>links</structfield></entry>
 	    <entry>*<structfield>links</structfield></entry>
 	    <entry>Pointer to a links array allocated by the application. Ignored
 	    <entry>Pointer to a links array allocated by the application. Ignored
 	    if NULL.</entry>
 	    if NULL.</entry>
@@ -153,12 +153,12 @@
         &cs-str;
         &cs-str;
 	<tbody valign="top">
 	<tbody valign="top">
 	  <row>
 	  <row>
-	    <entry>struct &media-pad-desc;</entry>
+	    <entry>&media-pad-desc;</entry>
 	    <entry><structfield>source</structfield></entry>
 	    <entry><structfield>source</structfield></entry>
 	    <entry>Pad at the origin of this link.</entry>
 	    <entry>Pad at the origin of this link.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
-	    <entry>struct &media-pad-desc;</entry>
+	    <entry>&media-pad-desc;</entry>
 	    <entry><structfield>sink</structfield></entry>
 	    <entry><structfield>sink</structfield></entry>
 	    <entry>Pad at the target of this link.</entry>
 	    <entry>Pad at the target of this link.</entry>
 	  </row>
 	  </row>

+ 2 - 2
Documentation/DocBook/media/v4l/pixfmt.xml

@@ -772,7 +772,7 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
 	  </row>
 	  </row>
 	  <row id="V4L2-PIX-FMT-H264-MVC">
 	  <row id="V4L2-PIX-FMT-H264-MVC">
 		<entry><constant>V4L2_PIX_FMT_H264_MVC</constant></entry>
 		<entry><constant>V4L2_PIX_FMT_H264_MVC</constant></entry>
-		<entry>'MVC'</entry>
+		<entry>'M264'</entry>
 		<entry>H264 MVC video elementary stream.</entry>
 		<entry>H264 MVC video elementary stream.</entry>
 	  </row>
 	  </row>
 	  <row id="V4L2-PIX-FMT-H263">
 	  <row id="V4L2-PIX-FMT-H263">
@@ -812,7 +812,7 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
 	  </row>
 	  </row>
 	  <row id="V4L2-PIX-FMT-VP8">
 	  <row id="V4L2-PIX-FMT-VP8">
 		<entry><constant>V4L2_PIX_FMT_VP8</constant></entry>
 		<entry><constant>V4L2_PIX_FMT_VP8</constant></entry>
-		<entry>'VP8'</entry>
+		<entry>'VP80'</entry>
 		<entry>VP8 video elementary stream.</entry>
 		<entry>VP8 video elementary stream.</entry>
 	  </row>
 	  </row>
 	</tbody>
 	</tbody>

+ 760 - 0
Documentation/DocBook/media/v4l/subdev-formats.xml

@@ -1898,6 +1898,134 @@
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	    </row>
 	    </row>
+	    <row id="V4L2-MBUS-FMT-UYVY10-2X10">
+	      <entry>V4L2_MBUS_FMT_UYVY10_2X10</entry>
+	      <entry>0x2018</entry>
+	      <entry></entry>
+	      &dash-ent-22;
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-22;
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-22;
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-22;
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-VYUY10-2X10">
+	      <entry>V4L2_MBUS_FMT_VYUY10_2X10</entry>
+	      <entry>0x2019</entry>
+	      <entry></entry>
+	      &dash-ent-22;
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-22;
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-22;
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-22;
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
 	    <row id="V4L2-MBUS-FMT-YUYV10-2X10">
 	    <row id="V4L2-MBUS-FMT-YUYV10-2X10">
 	      <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry>
 	      <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry>
 	      <entry>0x200b</entry>
 	      <entry>0x200b</entry>
@@ -2308,6 +2436,110 @@
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
 	    </row>
 	    </row>
+	    <row id="V4L2-MBUS-FMT-UYVY10-1X20">
+	      <entry>V4L2_MBUS_FMT_UYVY10_1X20</entry>
+	      <entry>0x201a</entry>
+	      <entry></entry>
+	      &dash-ent-12;
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-12;
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-VYUY10-1X20">
+	      <entry>V4L2_MBUS_FMT_VYUY10_1X20</entry>
+	      <entry>0x201b</entry>
+	      <entry></entry>
+	      &dash-ent-12;
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-12;
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
 	    <row id="V4L2-MBUS-FMT-YUYV10-1X20">
 	    <row id="V4L2-MBUS-FMT-YUYV10-1X20">
 	      <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry>
 	      <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry>
 	      <entry>0x200d</entry>
 	      <entry>0x200d</entry>
@@ -2486,6 +2718,534 @@
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>1</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
 	      <entry>v<subscript>0</subscript></entry>
 	    </row>
 	    </row>
+	    <row id="V4L2-MBUS-FMT-UYVY12-2X12">
+	      <entry>V4L2_MBUS_FMT_UYVY12_2X12</entry>
+	      <entry>0x201c</entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-VYUY12-2X12">
+	      <entry>V4L2_MBUS_FMT_VYUY12_2X12</entry>
+	      <entry>0x201d</entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YUYV12-2X12">
+	      <entry>V4L2_MBUS_FMT_YUYV12_2X12</entry>
+	      <entry>0x201e</entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YVYU12-2X12">
+	      <entry>V4L2_MBUS_FMT_YVYU12_2X12</entry>
+	      <entry>0x201f</entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-20;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-UYVY12-1X24">
+	      <entry>V4L2_MBUS_FMT_UYVY12_1X24</entry>
+	      <entry>0x2020</entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-VYUY12-1X24">
+	      <entry>V4L2_MBUS_FMT_VYUY12_1X24</entry>
+	      <entry>0x2021</entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YUYV12-1X24">
+	      <entry>V4L2_MBUS_FMT_YUYV12_1X24</entry>
+	      <entry>0x2022</entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row id="V4L2-MBUS-FMT-YVYU12-1X24">
+	      <entry>V4L2_MBUS_FMT_YVYU12_1X24</entry>
+	      <entry>0x2023</entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>v<subscript>11</subscript></entry>
+	      <entry>v<subscript>10</subscript></entry>
+	      <entry>v<subscript>9</subscript></entry>
+	      <entry>v<subscript>8</subscript></entry>
+	      <entry>v<subscript>7</subscript></entry>
+	      <entry>v<subscript>6</subscript></entry>
+	      <entry>v<subscript>5</subscript></entry>
+	      <entry>v<subscript>4</subscript></entry>
+	      <entry>v<subscript>3</subscript></entry>
+	      <entry>v<subscript>2</subscript></entry>
+	      <entry>v<subscript>1</subscript></entry>
+	      <entry>v<subscript>0</subscript></entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>y<subscript>11</subscript></entry>
+	      <entry>y<subscript>10</subscript></entry>
+	      <entry>y<subscript>9</subscript></entry>
+	      <entry>y<subscript>8</subscript></entry>
+	      <entry>y<subscript>7</subscript></entry>
+	      <entry>y<subscript>6</subscript></entry>
+	      <entry>y<subscript>5</subscript></entry>
+	      <entry>y<subscript>4</subscript></entry>
+	      <entry>y<subscript>3</subscript></entry>
+	      <entry>y<subscript>2</subscript></entry>
+	      <entry>y<subscript>1</subscript></entry>
+	      <entry>y<subscript>0</subscript></entry>
+	      <entry>u<subscript>11</subscript></entry>
+	      <entry>u<subscript>10</subscript></entry>
+	      <entry>u<subscript>9</subscript></entry>
+	      <entry>u<subscript>8</subscript></entry>
+	      <entry>u<subscript>7</subscript></entry>
+	      <entry>u<subscript>6</subscript></entry>
+	      <entry>u<subscript>5</subscript></entry>
+	      <entry>u<subscript>4</subscript></entry>
+	      <entry>u<subscript>3</subscript></entry>
+	      <entry>u<subscript>2</subscript></entry>
+	      <entry>u<subscript>1</subscript></entry>
+	      <entry>u<subscript>0</subscript></entry>
+	    </row>
 	  </tbody>
 	  </tbody>
 	</tgroup>
 	</tgroup>
       </table>
       </table>

+ 33 - 0
Documentation/DocBook/media/v4l/vidioc-dqevent.xml

@@ -242,6 +242,22 @@
       </tgroup>
       </tgroup>
     </table>
     </table>
 
 
+    <table frame="none" pgwide="1" id="v4l2-event-src-change">
+      <title>struct <structname>v4l2_event_src_change</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>changes</structfield></entry>
+	    <entry>
+	      A bitmask that tells what has changed. See <xref linkend="src-changes-flags" />.
+	    </entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
     <table pgwide="1" frame="none" id="changes-flags">
     <table pgwide="1" frame="none" id="changes-flags">
       <title>Changes</title>
       <title>Changes</title>
       <tgroup cols="3">
       <tgroup cols="3">
@@ -270,6 +286,23 @@
 	</tbody>
 	</tbody>
       </tgroup>
       </tgroup>
     </table>
     </table>
+
+    <table pgwide="1" frame="none" id="src-changes-flags">
+      <title>Source Changes</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_EVENT_SRC_CH_RESOLUTION</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>This event gets triggered when a resolution change is
+	    detected at an input. This can come from an input connector or
+	    from a video decoder.
+	    </entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
   </refsect1>
   </refsect1>
   <refsect1>
   <refsect1>
     &return-value;
     &return-value;

+ 22 - 5
Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml

@@ -1,11 +1,12 @@
 <refentry id="vidioc-dv-timings-cap">
 <refentry id="vidioc-dv-timings-cap">
   <refmeta>
   <refmeta>
-    <refentrytitle>ioctl VIDIOC_DV_TIMINGS_CAP</refentrytitle>
+    <refentrytitle>ioctl VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP</refentrytitle>
     &manvol;
     &manvol;
   </refmeta>
   </refmeta>
 
 
   <refnamediv>
   <refnamediv>
     <refname>VIDIOC_DV_TIMINGS_CAP</refname>
     <refname>VIDIOC_DV_TIMINGS_CAP</refname>
+    <refname>VIDIOC_SUBDEV_DV_TIMINGS_CAP</refname>
     <refpurpose>The capabilities of the Digital Video receiver/transmitter</refpurpose>
     <refpurpose>The capabilities of the Digital Video receiver/transmitter</refpurpose>
   </refnamediv>
   </refnamediv>
 
 
@@ -33,7 +34,7 @@
       <varlistentry>
       <varlistentry>
 	<term><parameter>request</parameter></term>
 	<term><parameter>request</parameter></term>
 	<listitem>
 	<listitem>
-	  <para>VIDIOC_DV_TIMINGS_CAP</para>
+	  <para>VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP</para>
 	</listitem>
 	</listitem>
       </varlistentry>
       </varlistentry>
       <varlistentry>
       <varlistentry>
@@ -54,10 +55,19 @@
       interface and may change in the future.</para>
       interface and may change in the future.</para>
     </note>
     </note>
 
 
-    <para>To query the capabilities of the DV receiver/transmitter applications can call
-this ioctl and the driver will fill in the structure. Note that drivers may return
+    <para>To query the capabilities of the DV receiver/transmitter applications
+can call the <constant>VIDIOC_DV_TIMINGS_CAP</constant> ioctl on a video node
+and the driver will fill in the structure. Note that drivers may return
 different values after switching the video input or output.</para>
 different values after switching the video input or output.</para>
 
 
+    <para>When implemented by the driver DV capabilities of subdevices can be
+queried by calling the <constant>VIDIOC_SUBDEV_DV_TIMINGS_CAP</constant> ioctl
+directly on a subdevice node. The capabilities are specific to inputs (for DV
+receivers) or outputs (for DV transmitters), applications must specify the
+desired pad number in the &v4l2-dv-timings-cap; <structfield>pad</structfield>
+field. Attempts to query capabilities on a pad that doesn't support them will
+return an &EINVAL;.</para>
+
     <table pgwide="1" frame="none" id="v4l2-bt-timings-cap">
     <table pgwide="1" frame="none" id="v4l2-bt-timings-cap">
       <title>struct <structname>v4l2_bt_timings_cap</structname></title>
       <title>struct <structname>v4l2_bt_timings_cap</structname></title>
       <tgroup cols="3">
       <tgroup cols="3">
@@ -127,7 +137,14 @@ different values after switching the video input or output.</para>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
-	    <entry><structfield>reserved</structfield>[3]</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media controller API. This field
+	    is only used when operating on a subdevice node. When operating on a
+	    video node applications must set this field to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
 	    <entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
 	    <entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>

+ 23 - 7
Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml

@@ -1,11 +1,12 @@
 <refentry id="vidioc-enum-dv-timings">
 <refentry id="vidioc-enum-dv-timings">
   <refmeta>
   <refmeta>
-    <refentrytitle>ioctl VIDIOC_ENUM_DV_TIMINGS</refentrytitle>
+    <refentrytitle>ioctl VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS</refentrytitle>
     &manvol;
     &manvol;
   </refmeta>
   </refmeta>
 
 
   <refnamediv>
   <refnamediv>
     <refname>VIDIOC_ENUM_DV_TIMINGS</refname>
     <refname>VIDIOC_ENUM_DV_TIMINGS</refname>
+    <refname>VIDIOC_SUBDEV_ENUM_DV_TIMINGS</refname>
     <refpurpose>Enumerate supported Digital Video timings</refpurpose>
     <refpurpose>Enumerate supported Digital Video timings</refpurpose>
   </refnamediv>
   </refnamediv>
 
 
@@ -33,7 +34,7 @@
       <varlistentry>
       <varlistentry>
 	<term><parameter>request</parameter></term>
 	<term><parameter>request</parameter></term>
 	<listitem>
 	<listitem>
-	  <para>VIDIOC_ENUM_DV_TIMINGS</para>
+	  <para>VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS</para>
 	</listitem>
 	</listitem>
       </varlistentry>
       </varlistentry>
       <varlistentry>
       <varlistentry>
@@ -61,14 +62,21 @@ standards or even custom timings that are not in this list.</para>
 
 
     <para>To query the available timings, applications initialize the
     <para>To query the available timings, applications initialize the
 <structfield>index</structfield> field and zero the reserved array of &v4l2-enum-dv-timings;
 <structfield>index</structfield> field and zero the reserved array of &v4l2-enum-dv-timings;
-and call the <constant>VIDIOC_ENUM_DV_TIMINGS</constant> ioctl with a pointer to this
-structure. Drivers fill the rest of the structure or return an
+and call the <constant>VIDIOC_ENUM_DV_TIMINGS</constant> ioctl on a video node with a
+pointer to this structure. Drivers fill the rest of the structure or return an
 &EINVAL; when the index is out of bounds. To enumerate all supported DV timings,
 &EINVAL; when the index is out of bounds. To enumerate all supported DV timings,
 applications shall begin at index zero, incrementing by one until the
 applications shall begin at index zero, incrementing by one until the
 driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a
 driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a
 different set of DV timings after switching the video input or
 different set of DV timings after switching the video input or
 output.</para>
 output.</para>
 
 
+    <para>When implemented by the driver DV timings of subdevices can be queried
+by calling the <constant>VIDIOC_SUBDEV_ENUM_DV_TIMINGS</constant> ioctl directly
+on a subdevice node. The DV timings are specific to inputs (for DV receivers) or
+outputs (for DV transmitters), applications must specify the desired pad number
+in the &v4l2-enum-dv-timings; <structfield>pad</structfield> field. Attempts to
+enumerate timings on a pad that doesn't support them will return an &EINVAL;.</para>
+
     <table pgwide="1" frame="none" id="v4l2-enum-dv-timings">
     <table pgwide="1" frame="none" id="v4l2-enum-dv-timings">
       <title>struct <structname>v4l2_enum_dv_timings</structname></title>
       <title>struct <structname>v4l2_enum_dv_timings</structname></title>
       <tgroup cols="3">
       <tgroup cols="3">
@@ -82,8 +90,16 @@ application.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
-	    <entry><structfield>reserved</structfield>[3]</entry>
-	    <entry>Reserved for future extensions. Drivers must set the array to zero.</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media controller API. This field
+	    is only used when operating on a subdevice node. When operating on a
+	    video node applications must set this field to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
+	    <entry>Reserved for future extensions. Drivers and applications must
+	    set the array to zero.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>&v4l2-dv-timings;</entry>
 	    <entry>&v4l2-dv-timings;</entry>
@@ -103,7 +119,7 @@ application.</entry>
 	<term><errorcode>EINVAL</errorcode></term>
 	<term><errorcode>EINVAL</errorcode></term>
 	<listitem>
 	<listitem>
 	  <para>The &v4l2-enum-dv-timings; <structfield>index</structfield>
 	  <para>The &v4l2-enum-dv-timings; <structfield>index</structfield>
-is out of bounds.</para>
+is out of bounds or the <structfield>pad</structfield> number is invalid.</para>
 	</listitem>
 	</listitem>
       </varlistentry>
       </varlistentry>
       <varlistentry>
       <varlistentry>

+ 20 - 0
Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml

@@ -154,6 +154,26 @@
 	      frame interval in between them.</para>
 	      frame interval in between them.</para>
 	    </entry>
 	    </entry>
 	  </row>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_EVENT_SOURCE_CHANGE</constant></entry>
+	    <entry>5</entry>
+	    <entry>
+	      <para>This event is triggered when a source parameter change is
+	       detected during runtime by the video device. It can be a
+	       runtime resolution change triggered by a video decoder or the
+	       format change happening on an input connector.
+	       This event requires that the <structfield>id</structfield>
+	       matches the input index (when used with a video device node)
+	       or the pad index (when used with a subdevice node) from which
+	       you want to receive events.</para>
+
+              <para>This event has a &v4l2-event-src-change; associated
+	      with it. The <structfield>changes</structfield> bitfield denotes
+	      what has changed for the subscribed pad. If multiple events
+	      occurred before application could dequeue them, then the changes
+	      will have the ORed value of all the events generated.</para>
+	    </entry>
+	  </row>
 	  <row>
 	  <row>
 	    <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
 	    <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
 	    <entry>0x08000000</entry>
 	    <entry>0x08000000</entry>

+ 2 - 1
Documentation/devicetree/bindings/media/s5p-mfc.txt

@@ -10,7 +10,8 @@ Required properties:
   - compatible : value should be either one among the following
   - compatible : value should be either one among the following
 	(a) "samsung,mfc-v5" for MFC v5 present in Exynos4 SoCs
 	(a) "samsung,mfc-v5" for MFC v5 present in Exynos4 SoCs
 	(b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs
 	(b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs
-	(b) "samsung,mfc-v7" for MFC v7 present in Exynos5420 SoC
+	(c) "samsung,mfc-v7" for MFC v7 present in Exynos5420 SoC
+	(d) "samsung,mfc-v8" for MFC v8 present in Exynos5800 SoC
 
 
   - reg : Physical base address of the IP registers and length of memory
   - reg : Physical base address of the IP registers and length of memory
 	  mapped region.
 	  mapped region.

+ 1 - 0
Documentation/video4linux/CARDLIST.bttv

@@ -164,3 +164,4 @@
 163 -> Bt848 Capture 14MHz
 163 -> Bt848 Capture 14MHz
 164 -> CyberVision CV06 (SV)
 164 -> CyberVision CV06 (SV)
 165 -> Kworld V-Stream Xpert TV PVR878
 165 -> Kworld V-Stream Xpert TV PVR878
+166 -> PCI-8604PW

+ 1 - 0
Documentation/video4linux/CARDLIST.em28xx

@@ -92,3 +92,4 @@
  91 -> SpeedLink Vicious And Devine Laplace webcam (em2765)        [1ae7:9003,1ae7:9004]
  91 -> SpeedLink Vicious And Devine Laplace webcam (em2765)        [1ae7:9003,1ae7:9004]
  92 -> PCTV DVB-S2 Stick (461e)                 (em28178)
  92 -> PCTV DVB-S2 Stick (461e)                 (em28178)
  93 -> KWorld USB ATSC TV Stick UB435-Q V3      (em2874)        [1b80:e34c]
  93 -> KWorld USB ATSC TV Stick UB435-Q V3      (em2874)        [1b80:e34c]
+ 94 -> PCTV tripleStick (292e)                  (em28178)

+ 0 - 30
Documentation/video4linux/fimc.txt

@@ -140,39 +140,9 @@ You can either grep through the kernel log to find relevant information, i.e.
 or retrieve the information from /dev/media? with help of the media-ctl tool:
 or retrieve the information from /dev/media? with help of the media-ctl tool:
 # media-ctl -p
 # media-ctl -p
 
 
-6. Platform support
-===================
-
-The machine code (arch/arm/plat-samsung and arch/arm/mach-*) must select
-following options:
-
-CONFIG_S5P_DEV_FIMC0       mandatory
-CONFIG_S5P_DEV_FIMC1  \
-CONFIG_S5P_DEV_FIMC2  |    optional
-CONFIG_S5P_DEV_FIMC3  |
-CONFIG_S5P_SETUP_FIMC /
-CONFIG_S5P_DEV_CSIS0  \    optional for MIPI-CSI interface
-CONFIG_S5P_DEV_CSIS1  /
-
-Except that, relevant s5p_device_fimc? should be registered in the machine code
-in addition to a "s5p-fimc-md" platform device to which the media device driver
-is bound.  The "s5p-fimc-md" device instance is required even if only mem-to-mem
-operation is used.
-
-The description of sensor(s) attached to FIMC/MIPI-CSIS camera inputs should be
-passed as the "s5p-fimc-md" device platform_data.  The platform data structure
-is defined in file include/media/s5p_fimc.h.
-
 7. Build
 7. Build
 ========
 ========
 
 
-This driver depends on following config options:
-PLAT_S5P,
-PM_RUNTIME,
-I2C,
-REGULATOR,
-VIDEO_V4L2_SUBDEV_API,
-
 If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m)
 If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m)
 two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and
 two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and
 optional s5p-csis.ko (MIPI-CSI receiver subdev).
 optional s5p-csis.ko (MIPI-CSI receiver subdev).

+ 29 - 13
Documentation/video4linux/v4l2-pci-skeleton.c

@@ -77,7 +77,8 @@ struct skeleton {
 
 
 	spinlock_t qlock;
 	spinlock_t qlock;
 	struct list_head buf_list;
 	struct list_head buf_list;
-	unsigned int sequence;
+	unsigned field;
+	unsigned sequence;
 };
 };
 
 
 struct skel_buffer {
 struct skel_buffer {
@@ -124,7 +125,7 @@ static const struct v4l2_dv_timings_cap skel_timings_cap = {
  * Interrupt handler: typically interrupts happen after a new frame has been
  * Interrupt handler: typically interrupts happen after a new frame has been
  * captured. It is the job of the handler to remove the new frame from the
  * captured. It is the job of the handler to remove the new frame from the
  * internal list and give it back to the vb2 framework, updating the sequence
  * internal list and give it back to the vb2 framework, updating the sequence
- * counter and timestamp at the same time.
+ * counter, field and timestamp at the same time.
  */
  */
 static irqreturn_t skeleton_irq(int irq, void *dev_id)
 static irqreturn_t skeleton_irq(int irq, void *dev_id)
 {
 {
@@ -139,8 +140,15 @@ static irqreturn_t skeleton_irq(int irq, void *dev_id)
 		spin_lock(&skel->qlock);
 		spin_lock(&skel->qlock);
 		list_del(&new_buf->list);
 		list_del(&new_buf->list);
 		spin_unlock(&skel->qlock);
 		spin_unlock(&skel->qlock);
-		new_buf->vb.v4l2_buf.sequence = skel->sequence++;
 		v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp);
 		v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp);
+		new_buf->vb.v4l2_buf.sequence = skel->sequence++;
+		new_buf->vb.v4l2_buf.field = skel->field;
+		if (skel->format.field == V4L2_FIELD_ALTERNATE) {
+			if (skel->field == V4L2_FIELD_BOTTOM)
+				skel->field = V4L2_FIELD_TOP;
+			else if (skel->field == V4L2_FIELD_TOP)
+				skel->field = V4L2_FIELD_BOTTOM;
+		}
 		vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE);
 		vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE);
 	}
 	}
 #endif
 #endif
@@ -160,6 +168,17 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
 {
 {
 	struct skeleton *skel = vb2_get_drv_priv(vq);
 	struct skeleton *skel = vb2_get_drv_priv(vq);
 
 
+	skel->field = skel->format.field;
+	if (skel->field == V4L2_FIELD_ALTERNATE) {
+		/*
+		 * You cannot use read() with FIELD_ALTERNATE since the field
+		 * information (TOP/BOTTOM) cannot be passed back to the user.
+		 */
+		if (vb2_fileio_is_active(vq))
+			return -EINVAL;
+		skel->field = V4L2_FIELD_TOP;
+	}
+
 	if (vq->num_buffers + *nbuffers < 3)
 	if (vq->num_buffers + *nbuffers < 3)
 		*nbuffers = 3 - vq->num_buffers;
 		*nbuffers = 3 - vq->num_buffers;
 
 
@@ -173,10 +192,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
 
 
 /*
 /*
  * Prepare the buffer for queueing to the DMA engine: check and set the
  * Prepare the buffer for queueing to the DMA engine: check and set the
- * payload size and fill in the field. Note: if the format's field is
- * V4L2_FIELD_ALTERNATE, then vb->v4l2_buf.field should be set in the
- * interrupt handler since that's usually where you know if the TOP or
- * BOTTOM field has been captured.
+ * payload size.
  */
  */
 static int buffer_prepare(struct vb2_buffer *vb)
 static int buffer_prepare(struct vb2_buffer *vb)
 {
 {
@@ -190,7 +206,6 @@ static int buffer_prepare(struct vb2_buffer *vb)
 	}
 	}
 
 
 	vb2_set_plane_payload(vb, 0, size);
 	vb2_set_plane_payload(vb, 0, size);
-	vb->v4l2_buf.field = skel->format.field;
 	return 0;
 	return 0;
 }
 }
 
 
@@ -254,7 +269,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
  * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
  * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
  * and passed on to the vb2 framework marked as STATE_ERROR.
  * and passed on to the vb2 framework marked as STATE_ERROR.
  */
  */
-static int stop_streaming(struct vb2_queue *vq)
+static void stop_streaming(struct vb2_queue *vq)
 {
 {
 	struct skeleton *skel = vb2_get_drv_priv(vq);
 	struct skeleton *skel = vb2_get_drv_priv(vq);
 
 
@@ -262,7 +277,6 @@ static int stop_streaming(struct vb2_queue *vq)
 
 
 	/* Release all active buffers */
 	/* Release all active buffers */
 	return_all_buffers(skel, VB2_BUF_STATE_ERROR);
 	return_all_buffers(skel, VB2_BUF_STATE_ERROR);
-	return 0;
 }
 }
 
 
 /*
 /*
@@ -319,10 +333,12 @@ static void skeleton_fill_pix_format(struct skeleton *skel,
 		/* HDMI input */
 		/* HDMI input */
 		pix->width = skel->timings.bt.width;
 		pix->width = skel->timings.bt.width;
 		pix->height = skel->timings.bt.height;
 		pix->height = skel->timings.bt.height;
-		if (skel->timings.bt.interlaced)
-			pix->field = V4L2_FIELD_INTERLACED;
-		else
+		if (skel->timings.bt.interlaced) {
+			pix->field = V4L2_FIELD_ALTERNATE;
+			pix->height /= 2;
+		} else {
 			pix->field = V4L2_FIELD_NONE;
 			pix->field = V4L2_FIELD_NONE;
+		}
 		pix->colorspace = V4L2_COLORSPACE_REC709;
 		pix->colorspace = V4L2_COLORSPACE_REC709;
 	}
 	}
 
 

+ 20 - 1
MAINTAINERS

@@ -7668,7 +7668,6 @@ L:	linux-media@vger.kernel.org
 Q:	https://patchwork.linuxtv.org/project/linux-media/list/
 Q:	https://patchwork.linuxtv.org/project/linux-media/list/
 S:	Supported
 S:	Supported
 F:	drivers/media/platform/exynos4-is/
 F:	drivers/media/platform/exynos4-is/
-F:	include/media/s5p_fimc.h
 
 
 SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER
 SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER
 M:	Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
 M:	Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
@@ -7971,6 +7970,26 @@ M:	Robin Holt <robinmholt@gmail.com>
 S:	Maintained
 S:	Maintained
 F:	drivers/misc/sgi-xp/
 F:	drivers/misc/sgi-xp/
 
 
+SI2157 MEDIA DRIVER
+M:	Antti Palosaari <crope@iki.fi>
+L:	linux-media@vger.kernel.org
+W:	http://linuxtv.org/
+W:	http://palosaari.fi/linux/
+Q:	http://patchwork.linuxtv.org/project/linux-media/list/
+T:	git git://linuxtv.org/anttip/media_tree.git
+S:	Maintained
+F:	drivers/media/tuners/si2157*
+
+SI2168 MEDIA DRIVER
+M:	Antti Palosaari <crope@iki.fi>
+L:	linux-media@vger.kernel.org
+W:	http://linuxtv.org/
+W:	http://palosaari.fi/linux/
+Q:	http://patchwork.linuxtv.org/project/linux-media/list/
+T:	git git://linuxtv.org/anttip/media_tree.git
+S:	Maintained
+F:	drivers/media/dvb-frontends/si2168*
+
 SI470X FM RADIO RECEIVER I2C DRIVER
 SI470X FM RADIO RECEIVER I2C DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
 M:	Hans Verkuil <hverkuil@xs4all.nl>
 L:	linux-media@vger.kernel.org
 L:	linux-media@vger.kernel.org

+ 0 - 51
arch/arm/mach-s5pv210/mach-goni.c

@@ -49,11 +49,6 @@
 #include <plat/clock.h>
 #include <plat/clock.h>
 #include <plat/samsung-time.h>
 #include <plat/samsung-time.h>
 #include <plat/mfc.h>
 #include <plat/mfc.h>
-#include <plat/camport.h>
-
-#include <media/v4l2-mediabus.h>
-#include <media/s5p_fimc.h>
-#include <media/noon010pc30.h>
 
 
 #include "common.h"
 #include "common.h"
 
 
@@ -285,14 +280,6 @@ static void __init goni_tsp_init(void)
 /* USB OTG */
 /* USB OTG */
 static struct s3c_hsotg_plat goni_hsotg_pdata;
 static struct s3c_hsotg_plat goni_hsotg_pdata;
 
 
-static void goni_camera_init(void)
-{
-	s5pv210_fimc_setup_gpio(S5P_CAMPORT_A);
-
-	/* Set max driver strength on CAM_A_CLKOUT pin. */
-	s5p_gpio_set_drvstr(S5PV210_GPE1(3), S5P_GPIO_DRVSTR_LV4);
-}
-
 /* MAX8998 regulators */
 /* MAX8998 regulators */
 #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
 #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
 
 
@@ -825,34 +812,6 @@ static void goni_setup_sdhci(void)
 	s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
 	s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
 };
 };
 
 
-static struct noon010pc30_platform_data noon010pc30_pldata = {
-	.clk_rate	= 16000000UL,
-	.gpio_nreset	= S5PV210_GPB(2), /* CAM_CIF_NRST */
-	.gpio_nstby	= S5PV210_GPB(0), /* CAM_CIF_NSTBY */
-};
-
-static struct i2c_board_info noon010pc30_board_info = {
-	I2C_BOARD_INFO("NOON010PC30", 0x60 >> 1),
-	.platform_data = &noon010pc30_pldata,
-};
-
-static struct fimc_source_info goni_camera_sensors[] = {
-	{
-		.mux_id		= 0,
-		.flags		= V4L2_MBUS_PCLK_SAMPLE_FALLING |
-				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
-		.fimc_bus_type	= FIMC_BUS_TYPE_ITU_601,
-		.board_info	= &noon010pc30_board_info,
-		.i2c_bus_num	= 0,
-		.clk_frequency	= 16000000UL,
-	},
-};
-
-static struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
-	.source_info	= goni_camera_sensors,
-	.num_clients	= ARRAY_SIZE(goni_camera_sensors),
-};
-
 /* Audio device */
 /* Audio device */
 static struct platform_device goni_device_audio = {
 static struct platform_device goni_device_audio = {
 	.name = "smdk-audio",
 	.name = "smdk-audio",
@@ -874,10 +833,6 @@ static struct platform_device *goni_devices[] __initdata = {
 	&s5p_device_mixer,
 	&s5p_device_mixer,
 	&s5p_device_sdo,
 	&s5p_device_sdo,
 	&s3c_device_i2c0,
 	&s3c_device_i2c0,
-	&s5p_device_fimc0,
-	&s5p_device_fimc1,
-	&s5p_device_fimc2,
-	&s5p_device_fimc_md,
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc1,
 	&s3c_device_hsmmc1,
 	&s3c_device_hsmmc2,
 	&s3c_device_hsmmc2,
@@ -946,14 +901,8 @@ static void __init goni_machine_init(void)
 	/* FB */
 	/* FB */
 	s3c_fb_set_platdata(&goni_lcd_pdata);
 	s3c_fb_set_platdata(&goni_lcd_pdata);
 
 
-	/* FIMC */
-	s3c_set_platdata(&goni_fimc_md_platdata, sizeof(goni_fimc_md_platdata),
-			 &s5p_device_fimc_md);
-
 	s3c_hsotg_set_platdata(&goni_hsotg_pdata);
 	s3c_hsotg_set_platdata(&goni_hsotg_pdata);
 
 
-	goni_camera_init();
-
 	/* SPI */
 	/* SPI */
 	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 
 

+ 3 - 0
drivers/media/dvb-core/dvb-usb-ids.h

@@ -356,11 +356,13 @@
 #define USB_PID_ELGATO_EYETV_DTT_2			0x003f
 #define USB_PID_ELGATO_EYETV_DTT_2			0x003f
 #define USB_PID_ELGATO_EYETV_DTT_Dlx			0x0020
 #define USB_PID_ELGATO_EYETV_DTT_Dlx			0x0020
 #define USB_PID_ELGATO_EYETV_SAT			0x002a
 #define USB_PID_ELGATO_EYETV_SAT			0x002a
+#define USB_PID_ELGATO_EYETV_SAT_V2			0x0025
 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD		0x5000
 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD		0x5000
 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM		0x5001
 #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM		0x5001
 #define USB_PID_FRIIO_WHITE				0x0001
 #define USB_PID_FRIIO_WHITE				0x0001
 #define USB_PID_TVWAY_PLUS				0x0002
 #define USB_PID_TVWAY_PLUS				0x0002
 #define USB_PID_SVEON_STV20				0xe39d
 #define USB_PID_SVEON_STV20				0xe39d
+#define USB_PID_SVEON_STV20_RTL2832U			0xd39d
 #define USB_PID_SVEON_STV22				0xe401
 #define USB_PID_SVEON_STV22				0xe401
 #define USB_PID_SVEON_STV22_IT9137			0xe411
 #define USB_PID_SVEON_STV22_IT9137			0xe411
 #define USB_PID_AZUREWAVE_AZ6027			0x3275
 #define USB_PID_AZUREWAVE_AZ6027			0x3275
@@ -375,4 +377,5 @@
 #define USB_PID_CTVDIGDUAL_V2				0xe410
 #define USB_PID_CTVDIGDUAL_V2				0xe410
 #define USB_PID_PCTV_2002E                              0x025c
 #define USB_PID_PCTV_2002E                              0x025c
 #define USB_PID_PCTV_2002E_SE                           0x025d
 #define USB_PID_PCTV_2002E_SE                           0x025d
+#define USB_PID_SVEON_STV27                             0xd3af
 #endif
 #endif

+ 7 - 0
drivers/media/dvb-frontends/Kconfig

@@ -446,6 +446,13 @@ config DVB_RTL2832
 	help
 	help
 	  Say Y when you want to support this frontend.
 	  Say Y when you want to support this frontend.
 
 
+config DVB_SI2168
+	tristate "Silicon Labs Si2168"
+	depends on DVB_CORE && I2C && I2C_MUX
+	default m if !MEDIA_SUBDRV_AUTOSELECT
+	help
+	  Say Y when you want to support this frontend.
+
 comment "DVB-C (cable) frontends"
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 	depends on DVB_CORE
 
 

+ 1 - 0
drivers/media/dvb-frontends/Makefile

@@ -78,6 +78,7 @@ obj-$(CONFIG_DVB_AF9013) += af9013.o
 obj-$(CONFIG_DVB_CX24116) += cx24116.o
 obj-$(CONFIG_DVB_CX24116) += cx24116.o
 obj-$(CONFIG_DVB_CX24117) += cx24117.o
 obj-$(CONFIG_DVB_CX24117) += cx24117.o
 obj-$(CONFIG_DVB_SI21XX) += si21xx.o
 obj-$(CONFIG_DVB_SI21XX) += si21xx.o
+obj-$(CONFIG_DVB_SI2168) += si2168.o
 obj-$(CONFIG_DVB_STV0288) += stv0288.o
 obj-$(CONFIG_DVB_STV0288) += stv0288.o
 obj-$(CONFIG_DVB_STB6000) += stb6000.o
 obj-$(CONFIG_DVB_STB6000) += stb6000.o
 obj-$(CONFIG_DVB_S921) += s921.o
 obj-$(CONFIG_DVB_S921) += s921.o

+ 760 - 0
drivers/media/dvb-frontends/si2168.c

@@ -0,0 +1,760 @@
+/*
+ * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#include "si2168_priv.h"
+
+static const struct dvb_frontend_ops si2168_ops;
+
+/* execute firmware command */
+static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
+{
+	int ret;
+	unsigned long timeout;
+
+	mutex_lock(&s->i2c_mutex);
+
+	if (cmd->wlen) {
+		/* write cmd and args for firmware */
+		ret = i2c_master_send(s->client, cmd->args, cmd->wlen);
+		if (ret < 0) {
+			goto err_mutex_unlock;
+		} else if (ret != cmd->wlen) {
+			ret = -EREMOTEIO;
+			goto err_mutex_unlock;
+		}
+	}
+
+	if (cmd->rlen) {
+		/* wait cmd execution terminate */
+		#define TIMEOUT 50
+		timeout = jiffies + msecs_to_jiffies(TIMEOUT);
+		while (!time_after(jiffies, timeout)) {
+			ret = i2c_master_recv(s->client, cmd->args, cmd->rlen);
+			if (ret < 0) {
+				goto err_mutex_unlock;
+			} else if (ret != cmd->rlen) {
+				ret = -EREMOTEIO;
+				goto err_mutex_unlock;
+			}
+
+			/* firmware ready? */
+			if ((cmd->args[0] >> 7) & 0x01)
+				break;
+		}
+
+		dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n",
+				__func__,
+				jiffies_to_msecs(jiffies) -
+				(jiffies_to_msecs(timeout) - TIMEOUT));
+
+		if (!(cmd->args[0] >> 7) & 0x01) {
+			ret = -ETIMEDOUT;
+			goto err_mutex_unlock;
+		}
+	}
+
+	ret = 0;
+
+err_mutex_unlock:
+	mutex_unlock(&s->i2c_mutex);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct si2168 *s = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	struct si2168_cmd cmd;
+
+	*status = 0;
+
+	if (!s->active) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+		cmd.args[0] = 0xa0;
+		cmd.args[1] = 0x01;
+		cmd.wlen = 2;
+		cmd.rlen = 13;
+		break;
+	case SYS_DVBC_ANNEX_A:
+		cmd.args[0] = 0x90;
+		cmd.args[1] = 0x01;
+		cmd.wlen = 2;
+		cmd.rlen = 9;
+		break;
+	case SYS_DVBT2:
+		cmd.args[0] = 0x50;
+		cmd.args[1] = 0x01;
+		cmd.wlen = 2;
+		cmd.rlen = 14;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	/*
+	 * Possible values seen, in order from strong signal to weak:
+	 * 16 0001 0110 full lock
+	 * 1e 0001 1110 partial lock
+	 * 1a 0001 1010 partial lock
+	 * 18 0001 1000 no lock
+	 *
+	 * [b3:b1] lock bits
+	 * [b4] statistics ready? Set in a few secs after lock is gained.
+	 */
+
+	switch ((cmd.args[2] >> 1) & 0x03) {
+	case 0x01:
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+		break;
+	case 0x03:
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+				FE_HAS_SYNC | FE_HAS_LOCK;
+		break;
+	}
+
+	s->fe_status = *status;
+
+	dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
+			__func__, *status, cmd.rlen, cmd.args);
+
+	return 0;
+err:
+	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int si2168_set_frontend(struct dvb_frontend *fe)
+{
+	struct si2168 *s = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	struct si2168_cmd cmd;
+	u8 bandwidth, delivery_system;
+
+	dev_dbg(&s->client->dev,
+			"%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u\n",
+			__func__, c->delivery_system, c->modulation,
+			c->frequency, c->bandwidth_hz, c->symbol_rate,
+			c->inversion);
+
+	if (!s->active) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+		delivery_system = 0x20;
+		break;
+	case SYS_DVBC_ANNEX_A:
+		delivery_system = 0x30;
+		break;
+	case SYS_DVBT2:
+		delivery_system = 0x70;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (c->bandwidth_hz <= 5000000)
+		bandwidth = 0x05;
+	else if (c->bandwidth_hz <= 6000000)
+		bandwidth = 0x06;
+	else if (c->bandwidth_hz <= 7000000)
+		bandwidth = 0x07;
+	else if (c->bandwidth_hz <= 8000000)
+		bandwidth = 0x08;
+	else if (c->bandwidth_hz <= 9000000)
+		bandwidth = 0x09;
+	else if (c->bandwidth_hz <= 10000000)
+		bandwidth = 0x0a;
+	else
+		bandwidth = 0x0f;
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params) {
+		ret = fe->ops.tuner_ops.set_params(fe);
+		if (ret)
+			goto err;
+	}
+
+	memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5);
+	cmd.wlen = 5;
+	cmd.rlen = 5;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	/* that has no big effect */
+	if (c->delivery_system == SYS_DVBT)
+		memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6);
+	else if (c->delivery_system == SYS_DVBC_ANNEX_A)
+		memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6);
+	else if (c->delivery_system == SYS_DVBT2)
+		memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 3;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x51\x03", 2);
+	cmd.wlen = 2;
+	cmd.rlen = 12;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x12\x08\x04", 3);
+	cmd.wlen = 3;
+	cmd.rlen = 3;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x01\x04\x00\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x03\x10\x17\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x02\x10\x15\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x0b\x10\x88\x13", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
+	cmd.args[4] = delivery_system | bandwidth;
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x04\x10\x15\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x05\x10\xa1\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x0d\x10\xd0\x02", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x01\x10\x00\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x04\x03\x00\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x03\x03\x00\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x08\x03\x00\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x07\x03\x01\x02", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x06\x03\x00\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x05\x03\x00\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x40", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
+	cmd.wlen = 6;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	cmd.args[0] = 0x85;
+	cmd.wlen = 1;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	s->delivery_system = c->delivery_system;
+
+	return 0;
+err:
+	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int si2168_init(struct dvb_frontend *fe)
+{
+	struct si2168 *s = fe->demodulator_priv;
+	int ret, len, remaining;
+	const struct firmware *fw = NULL;
+	u8 *fw_file = SI2168_FIRMWARE;
+	const unsigned int i2c_wr_max = 8;
+	struct si2168_cmd cmd;
+
+	dev_dbg(&s->client->dev, "%s:\n", __func__);
+
+	cmd.args[0] = 0x13;
+	cmd.wlen = 1;
+	cmd.rlen = 0;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	cmd.args[0] = 0xc0;
+	cmd.args[1] = 0x12;
+	cmd.args[2] = 0x00;
+	cmd.args[3] = 0x0c;
+	cmd.args[4] = 0x00;
+	cmd.args[5] = 0x0d;
+	cmd.args[6] = 0x16;
+	cmd.args[7] = 0x00;
+	cmd.args[8] = 0x00;
+	cmd.args[9] = 0x00;
+	cmd.args[10] = 0x00;
+	cmd.args[11] = 0x00;
+	cmd.args[12] = 0x00;
+	cmd.wlen = 13;
+	cmd.rlen = 0;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	cmd.args[0] = 0xc0;
+	cmd.args[1] = 0x06;
+	cmd.args[2] = 0x01;
+	cmd.args[3] = 0x0f;
+	cmd.args[4] = 0x00;
+	cmd.args[5] = 0x20;
+	cmd.args[6] = 0x20;
+	cmd.args[7] = 0x01;
+	cmd.wlen = 8;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	cmd.args[0] = 0x02;
+	cmd.wlen = 1;
+	cmd.rlen = 13;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	cmd.args[0] = 0x05;
+	cmd.args[1] = 0x00;
+	cmd.args[2] = 0xaa;
+	cmd.args[3] = 0x4d;
+	cmd.args[4] = 0x56;
+	cmd.args[5] = 0x40;
+	cmd.args[6] = 0x00;
+	cmd.args[7] = 0x00;
+	cmd.wlen = 8;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	/* cold state - try to download firmware */
+	dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
+			KBUILD_MODNAME, si2168_ops.info.name);
+
+	/* request the firmware, this will block and timeout */
+	ret = request_firmware(&fw, fw_file, &s->client->dev);
+	if (ret) {
+		dev_err(&s->client->dev, "%s: firmare file '%s' not found\n",
+				KBUILD_MODNAME, fw_file);
+		goto err;
+	}
+
+	dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
+			KBUILD_MODNAME, fw_file);
+
+	for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
+		len = remaining;
+		if (len > i2c_wr_max)
+			len = i2c_wr_max;
+
+		memcpy(cmd.args, &fw->data[fw->size - remaining], len);
+		cmd.wlen = len;
+		cmd.rlen = 1;
+		ret = si2168_cmd_execute(s, &cmd);
+		if (ret) {
+			dev_err(&s->client->dev,
+					"%s: firmware download failed=%d\n",
+					KBUILD_MODNAME, ret);
+			goto err;
+		}
+	}
+
+	release_firmware(fw);
+	fw = NULL;
+
+	cmd.args[0] = 0x01;
+	cmd.args[1] = 0x01;
+	cmd.wlen = 2;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	dev_info(&s->client->dev, "%s: found a '%s' in warm state\n",
+			KBUILD_MODNAME, si2168_ops.info.name);
+
+	s->active = true;
+
+	return 0;
+err:
+	if (fw)
+		release_firmware(fw);
+
+	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int si2168_sleep(struct dvb_frontend *fe)
+{
+	struct si2168 *s = fe->demodulator_priv;
+
+	dev_dbg(&s->client->dev, "%s:\n", __func__);
+
+	s->active = false;
+
+	return 0;
+}
+
+static int si2168_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s)
+{
+	s->min_delay_ms = 900;
+
+	return 0;
+}
+
+/*
+ * I2C gate logic
+ * We must use unlocked i2c_transfer() here because I2C lock is already taken
+ * by tuner driver.
+ */
+static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
+{
+	struct si2168 *s = mux_priv;
+	int ret;
+	struct i2c_msg gate_open_msg = {
+		.addr = s->client->addr,
+		.flags = 0,
+		.len = 3,
+		.buf = "\xc0\x0d\x01",
+	};
+
+	mutex_lock(&s->i2c_mutex);
+
+	/* open tuner I2C gate */
+	ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1);
+	if (ret != 1) {
+		dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
+				KBUILD_MODNAME, ret);
+		if (ret >= 0)
+			ret = -EREMOTEIO;
+	} else {
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
+{
+	struct si2168 *s = mux_priv;
+	int ret;
+	struct i2c_msg gate_close_msg = {
+		.addr = s->client->addr,
+		.flags = 0,
+		.len = 3,
+		.buf = "\xc0\x0d\x00",
+	};
+
+	/* close tuner I2C gate */
+	ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1);
+	if (ret != 1) {
+		dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
+				KBUILD_MODNAME, ret);
+		if (ret >= 0)
+			ret = -EREMOTEIO;
+	} else {
+		ret = 0;
+	}
+
+	mutex_unlock(&s->i2c_mutex);
+
+	return ret;
+}
+
+static const struct dvb_frontend_ops si2168_ops = {
+	.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
+	.info = {
+		.name = "Silicon Labs Si2168",
+		.caps =	FE_CAN_FEC_1_2 |
+			FE_CAN_FEC_2_3 |
+			FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_5_6 |
+			FE_CAN_FEC_7_8 |
+			FE_CAN_FEC_AUTO |
+			FE_CAN_QPSK |
+			FE_CAN_QAM_16 |
+			FE_CAN_QAM_32 |
+			FE_CAN_QAM_64 |
+			FE_CAN_QAM_128 |
+			FE_CAN_QAM_256 |
+			FE_CAN_QAM_AUTO |
+			FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO |
+			FE_CAN_HIERARCHY_AUTO |
+			FE_CAN_MUTE_TS |
+			FE_CAN_2G_MODULATION
+	},
+
+	.get_tune_settings = si2168_get_tune_settings,
+
+	.init = si2168_init,
+	.sleep = si2168_sleep,
+
+	.set_frontend = si2168_set_frontend,
+
+	.read_status = si2168_read_status,
+};
+
+static int si2168_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct si2168_config *config = client->dev.platform_data;
+	struct si2168 *s;
+	int ret;
+	struct si2168_cmd cmd;
+
+	dev_dbg(&client->dev, "%s:\n", __func__);
+
+	s = kzalloc(sizeof(struct si2168), GFP_KERNEL);
+	if (!s) {
+		ret = -ENOMEM;
+		dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+		goto err;
+	}
+
+	s->client = client;
+	mutex_init(&s->i2c_mutex);
+
+	/* check if the demod is there */
+	cmd.wlen = 0;
+	cmd.rlen = 1;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	/* create mux i2c adapter for tuner */
+	s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s,
+			0, 0, 0, si2168_select, si2168_deselect);
+	if (s->adapter == NULL)
+		goto err;
+
+	/* create dvb_frontend */
+	memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops));
+	s->fe.demodulator_priv = s;
+
+	*config->i2c_adapter = s->adapter;
+	*config->fe = &s->fe;
+
+	i2c_set_clientdata(client, s);
+
+	dev_info(&s->client->dev,
+			"%s: Silicon Labs Si2168 successfully attached\n",
+			KBUILD_MODNAME);
+	return 0;
+err:
+	kfree(s);
+	dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
+static int si2168_remove(struct i2c_client *client)
+{
+	struct si2168 *s = i2c_get_clientdata(client);
+
+	dev_dbg(&client->dev, "%s:\n", __func__);
+
+	i2c_del_mux_adapter(s->adapter);
+
+	s->fe.ops.release = NULL;
+	s->fe.demodulator_priv = NULL;
+
+	kfree(s);
+
+	return 0;
+}
+
+static const struct i2c_device_id si2168_id[] = {
+	{"si2168", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, si2168_id);
+
+static struct i2c_driver si2168_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "si2168",
+	},
+	.probe		= si2168_probe,
+	.remove		= si2168_remove,
+	.id_table	= si2168_id,
+};
+
+module_i2c_driver(si2168_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(SI2168_FIRMWARE);

+ 39 - 0
drivers/media/dvb-frontends/si2168.h

@@ -0,0 +1,39 @@
+/*
+ * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef SI2168_H
+#define SI2168_H
+
+#include <linux/dvb/frontend.h>
+/*
+ * I2C address
+ * 0x64
+ */
+struct si2168_config {
+	/*
+	 * frontend
+	 * returned by driver
+	 */
+	struct dvb_frontend **fe;
+
+	/*
+	 * tuner I2C adapter
+	 * returned by driver
+	 */
+	struct i2c_adapter **i2c_adapter;
+};
+
+#endif

+ 46 - 0
drivers/media/dvb-frontends/si2168_priv.h

@@ -0,0 +1,46 @@
+/*
+ * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
+ *
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef SI2168_PRIV_H
+#define SI2168_PRIV_H
+
+#include "si2168.h"
+#include "dvb_frontend.h"
+#include <linux/firmware.h>
+#include <linux/i2c-mux.h>
+
+#define SI2168_FIRMWARE "dvb-demod-si2168-01.fw"
+
+/* state struct */
+struct si2168 {
+	struct i2c_client *client;
+	struct i2c_adapter *adapter;
+	struct mutex i2c_mutex;
+	struct dvb_frontend fe;
+	fe_delivery_system_t delivery_system;
+	fe_status_t fe_status;
+	bool active;
+};
+
+/* firmare command struct */
+#define SI2157_ARGLEN      30
+struct si2168_cmd {
+	u8 args[SI2157_ARGLEN];
+	unsigned wlen;
+	unsigned rlen;
+};
+
+#endif

+ 35 - 29
drivers/media/i2c/ad9389b.c

@@ -571,35 +571,6 @@ static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
 	.interrupt_service_routine = ad9389b_isr,
 	.interrupt_service_routine = ad9389b_isr,
 };
 };
 
 
-/* ------------------------------ PAD OPS ------------------------------ */
-
-static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
-{
-	struct ad9389b_state *state = get_ad9389b_state(sd);
-
-	if (edid->pad != 0)
-		return -EINVAL;
-	if (edid->blocks == 0 || edid->blocks > 256)
-		return -EINVAL;
-	if (!edid->edid)
-		return -EINVAL;
-	if (!state->edid.segments) {
-		v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
-		return -ENODATA;
-	}
-	if (edid->start_block >= state->edid.segments * 2)
-		return -E2BIG;
-	if (edid->blocks + edid->start_block >= state->edid.segments * 2)
-		edid->blocks = state->edid.segments * 2 - edid->start_block;
-	memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
-	       128 * edid->blocks);
-	return 0;
-}
-
-static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = {
-	.get_edid = ad9389b_get_edid,
-};
-
 /* ------------------------------ VIDEO OPS ------------------------------ */
 /* ------------------------------ VIDEO OPS ------------------------------ */
 
 
 /* Enable/disable ad9389b output */
 /* Enable/disable ad9389b output */
@@ -678,6 +649,9 @@ static int ad9389b_g_dv_timings(struct v4l2_subdev *sd,
 static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
 static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
 				   struct v4l2_enum_dv_timings *timings)
 				   struct v4l2_enum_dv_timings *timings)
 {
 {
+	if (timings->pad != 0)
+		return -EINVAL;
+
 	return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap,
 	return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap,
 			NULL, NULL);
 			NULL, NULL);
 }
 }
@@ -685,6 +659,9 @@ static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd,
 static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd,
 static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd,
 				  struct v4l2_dv_timings_cap *cap)
 				  struct v4l2_dv_timings_cap *cap)
 {
 {
+	if (cap->pad != 0)
+		return -EINVAL;
+
 	*cap = ad9389b_timings_cap;
 	*cap = ad9389b_timings_cap;
 	return 0;
 	return 0;
 }
 }
@@ -693,10 +670,39 @@ static const struct v4l2_subdev_video_ops ad9389b_video_ops = {
 	.s_stream = ad9389b_s_stream,
 	.s_stream = ad9389b_s_stream,
 	.s_dv_timings = ad9389b_s_dv_timings,
 	.s_dv_timings = ad9389b_s_dv_timings,
 	.g_dv_timings = ad9389b_g_dv_timings,
 	.g_dv_timings = ad9389b_g_dv_timings,
+};
+
+/* ------------------------------ PAD OPS ------------------------------ */
+
+static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
+{
+	struct ad9389b_state *state = get_ad9389b_state(sd);
+
+	if (edid->pad != 0)
+		return -EINVAL;
+	if (edid->blocks == 0 || edid->blocks > 256)
+		return -EINVAL;
+	if (!state->edid.segments) {
+		v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
+		return -ENODATA;
+	}
+	if (edid->start_block >= state->edid.segments * 2)
+		return -E2BIG;
+	if (edid->blocks + edid->start_block >= state->edid.segments * 2)
+		edid->blocks = state->edid.segments * 2 - edid->start_block;
+	memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
+	       128 * edid->blocks);
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = {
+	.get_edid = ad9389b_get_edid,
 	.enum_dv_timings = ad9389b_enum_dv_timings,
 	.enum_dv_timings = ad9389b_enum_dv_timings,
 	.dv_timings_cap = ad9389b_dv_timings_cap,
 	.dv_timings_cap = ad9389b_dv_timings_cap,
 };
 };
 
 
+/* ------------------------------ AUDIO OPS ------------------------------ */
+
 static int ad9389b_s_audio_stream(struct v4l2_subdev *sd, int enable)
 static int ad9389b_s_audio_stream(struct v4l2_subdev *sd, int enable)
 {
 {
 	v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));
 	v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis"));

+ 1 - 1
drivers/media/i2c/adv7180.c

@@ -461,6 +461,7 @@ static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
 }
 }
 
 
 static const struct v4l2_subdev_video_ops adv7180_video_ops = {
 static const struct v4l2_subdev_video_ops adv7180_video_ops = {
+	.s_std = adv7180_s_std,
 	.querystd = adv7180_querystd,
 	.querystd = adv7180_querystd,
 	.g_input_status = adv7180_g_input_status,
 	.g_input_status = adv7180_g_input_status,
 	.s_routing = adv7180_s_routing,
 	.s_routing = adv7180_s_routing,
@@ -472,7 +473,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_core_ops adv7180_core_ops = {
 static const struct v4l2_subdev_core_ops adv7180_core_ops = {
-	.s_std = adv7180_s_std,
 	.s_power = adv7180_s_power,
 	.s_power = adv7180_s_power,
 };
 };
 
 

+ 2 - 2
drivers/media/i2c/adv7183.c

@@ -501,8 +501,6 @@ static const struct v4l2_ctrl_ops adv7183_ctrl_ops = {
 
 
 static const struct v4l2_subdev_core_ops adv7183_core_ops = {
 static const struct v4l2_subdev_core_ops adv7183_core_ops = {
 	.log_status = adv7183_log_status,
 	.log_status = adv7183_log_status,
-	.g_std = adv7183_g_std,
-	.s_std = adv7183_s_std,
 	.reset = adv7183_reset,
 	.reset = adv7183_reset,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = adv7183_g_register,
 	.g_register = adv7183_g_register,
@@ -511,6 +509,8 @@ static const struct v4l2_subdev_core_ops adv7183_core_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_video_ops adv7183_video_ops = {
 static const struct v4l2_subdev_video_ops adv7183_video_ops = {
+	.g_std = adv7183_g_std,
+	.s_std = adv7183_s_std,
 	.s_routing = adv7183_s_routing,
 	.s_routing = adv7183_s_routing,
 	.querystd = adv7183_querystd,
 	.querystd = adv7183_querystd,
 	.g_input_status = adv7183_g_input_status,
 	.g_input_status = adv7183_g_input_status,

+ 36 - 30
drivers/media/i2c/adv7511.c

@@ -597,34 +597,6 @@ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
 	return 0;
 	return 0;
 }
 }
 
 
-static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
-{
-	struct adv7511_state *state = get_adv7511_state(sd);
-
-	if (edid->pad != 0)
-		return -EINVAL;
-	if ((edid->blocks == 0) || (edid->blocks > 256))
-		return -EINVAL;
-	if (!edid->edid)
-		return -EINVAL;
-	if (!state->edid.segments) {
-		v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
-		return -ENODATA;
-	}
-	if (edid->start_block >= state->edid.segments * 2)
-		return -E2BIG;
-	if ((edid->blocks + edid->start_block) >= state->edid.segments * 2)
-		edid->blocks = state->edid.segments * 2 - edid->start_block;
-
-	memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
-			128 * edid->blocks);
-	return 0;
-}
-
-static const struct v4l2_subdev_pad_ops adv7511_pad_ops = {
-	.get_edid = adv7511_get_edid,
-};
-
 static const struct v4l2_subdev_core_ops adv7511_core_ops = {
 static const struct v4l2_subdev_core_ops adv7511_core_ops = {
 	.log_status = adv7511_log_status,
 	.log_status = adv7511_log_status,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -700,12 +672,18 @@ static int adv7511_g_dv_timings(struct v4l2_subdev *sd,
 static int adv7511_enum_dv_timings(struct v4l2_subdev *sd,
 static int adv7511_enum_dv_timings(struct v4l2_subdev *sd,
 				   struct v4l2_enum_dv_timings *timings)
 				   struct v4l2_enum_dv_timings *timings)
 {
 {
+	if (timings->pad != 0)
+		return -EINVAL;
+
 	return v4l2_enum_dv_timings_cap(timings, &adv7511_timings_cap, NULL, NULL);
 	return v4l2_enum_dv_timings_cap(timings, &adv7511_timings_cap, NULL, NULL);
 }
 }
 
 
 static int adv7511_dv_timings_cap(struct v4l2_subdev *sd,
 static int adv7511_dv_timings_cap(struct v4l2_subdev *sd,
 				  struct v4l2_dv_timings_cap *cap)
 				  struct v4l2_dv_timings_cap *cap)
 {
 {
+	if (cap->pad != 0)
+		return -EINVAL;
+
 	*cap = adv7511_timings_cap;
 	*cap = adv7511_timings_cap;
 	return 0;
 	return 0;
 }
 }
@@ -714,8 +692,6 @@ static const struct v4l2_subdev_video_ops adv7511_video_ops = {
 	.s_stream = adv7511_s_stream,
 	.s_stream = adv7511_s_stream,
 	.s_dv_timings = adv7511_s_dv_timings,
 	.s_dv_timings = adv7511_s_dv_timings,
 	.g_dv_timings = adv7511_g_dv_timings,
 	.g_dv_timings = adv7511_g_dv_timings,
-	.enum_dv_timings = adv7511_enum_dv_timings,
-	.dv_timings_cap = adv7511_dv_timings_cap,
 };
 };
 
 
 /* ------------------------------ AUDIO OPS ------------------------------ */
 /* ------------------------------ AUDIO OPS ------------------------------ */
@@ -797,6 +773,36 @@ static const struct v4l2_subdev_audio_ops adv7511_audio_ops = {
 	.s_routing = adv7511_s_routing,
 	.s_routing = adv7511_s_routing,
 };
 };
 
 
+/* ---------------------------- PAD OPS ------------------------------------- */
+
+static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
+{
+	struct adv7511_state *state = get_adv7511_state(sd);
+
+	if (edid->pad != 0)
+		return -EINVAL;
+	if ((edid->blocks == 0) || (edid->blocks > 256))
+		return -EINVAL;
+	if (!state->edid.segments) {
+		v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n");
+		return -ENODATA;
+	}
+	if (edid->start_block >= state->edid.segments * 2)
+		return -E2BIG;
+	if ((edid->blocks + edid->start_block) >= state->edid.segments * 2)
+		edid->blocks = state->edid.segments * 2 - edid->start_block;
+
+	memcpy(edid->edid, &state->edid.data[edid->start_block * 128],
+			128 * edid->blocks);
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops adv7511_pad_ops = {
+	.get_edid = adv7511_get_edid,
+	.enum_dv_timings = adv7511_enum_dv_timings,
+	.dv_timings_cap = adv7511_dv_timings_cap,
+};
+
 /* --------------------- SUBDEV OPS --------------------------------------- */
 /* --------------------- SUBDEV OPS --------------------------------------- */
 
 
 static const struct v4l2_subdev_ops adv7511_ops = {
 static const struct v4l2_subdev_ops adv7511_ops = {

+ 0 - 4
drivers/media/i2c/adv7604.c

@@ -1673,8 +1673,6 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 		return -EINVAL;
 		return -EINVAL;
 	if (edid->start_block == 1)
 	if (edid->start_block == 1)
 		edid->blocks = 1;
 		edid->blocks = 1;
-	if (!edid->edid)
-		return -EINVAL;
 
 
 	if (edid->blocks > state->edid.blocks)
 	if (edid->blocks > state->edid.blocks)
 		edid->blocks = state->edid.blocks;
 		edid->blocks = state->edid.blocks;
@@ -1761,8 +1759,6 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 		edid->blocks = 2;
 		edid->blocks = 2;
 		return -E2BIG;
 		return -E2BIG;
 	}
 	}
-	if (!edid->edid)
-		return -EINVAL;
 
 
 	v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n",
 	v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n",
 			__func__, edid->pad, state->edid.present);
 			__func__, edid->pad, state->edid.present);

+ 17 - 11
drivers/media/i2c/adv7842.c

@@ -1399,6 +1399,9 @@ static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi)
 static int adv7842_enum_dv_timings(struct v4l2_subdev *sd,
 static int adv7842_enum_dv_timings(struct v4l2_subdev *sd,
 				   struct v4l2_enum_dv_timings *timings)
 				   struct v4l2_enum_dv_timings *timings)
 {
 {
+	if (timings->pad != 0)
+		return -EINVAL;
+
 	return v4l2_enum_dv_timings_cap(timings,
 	return v4l2_enum_dv_timings_cap(timings,
 		adv7842_get_dv_timings_cap(sd), adv7842_check_dv_timings, NULL);
 		adv7842_get_dv_timings_cap(sd), adv7842_check_dv_timings, NULL);
 }
 }
@@ -1406,6 +1409,9 @@ static int adv7842_enum_dv_timings(struct v4l2_subdev *sd,
 static int adv7842_dv_timings_cap(struct v4l2_subdev *sd,
 static int adv7842_dv_timings_cap(struct v4l2_subdev *sd,
 				  struct v4l2_dv_timings_cap *cap)
 				  struct v4l2_dv_timings_cap *cap)
 {
 {
+	if (cap->pad != 0)
+		return -EINVAL;
+
 	*cap = *adv7842_get_dv_timings_cap(sd);
 	*cap = *adv7842_get_dv_timings_cap(sd);
 	return 0;
 	return 0;
 }
 }
@@ -2000,6 +2006,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
 	if (irq_status[5] & 0x08) {
 	if (irq_status[5] & 0x08) {
 		v4l2_dbg(1, debug, sd, "%s: irq %s mode\n", __func__,
 		v4l2_dbg(1, debug, sd, "%s: irq %s mode\n", __func__,
 			 (io_read(sd, 0x65) & 0x08) ? "HDMI" : "DVI");
 			 (io_read(sd, 0x65) & 0x08) ? "HDMI" : "DVI");
+		set_rgb_quantization_range(sd);
 		if (handled)
 		if (handled)
 			*handled = true;
 			*handled = true;
 	}
 	}
@@ -2029,8 +2036,6 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
 		return -EINVAL;
 		return -EINVAL;
 	if (edid->start_block == 1)
 	if (edid->start_block == 1)
 		edid->blocks = 1;
 		edid->blocks = 1;
-	if (!edid->edid)
-		return -EINVAL;
 
 
 	switch (edid->pad) {
 	switch (edid->pad) {
 	case ADV7842_EDID_PORT_A:
 	case ADV7842_EDID_PORT_A:
@@ -2065,8 +2070,6 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e)
 		return -EINVAL;
 		return -EINVAL;
 	if (e->blocks > 2)
 	if (e->blocks > 2)
 		return -E2BIG;
 		return -E2BIG;
-	if (!e->edid)
-		return -EINVAL;
 
 
 	/* todo, per edid */
 	/* todo, per edid */
 	state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15],
 	state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15],
@@ -2610,6 +2613,12 @@ static int adv7842_core_init(struct v4l2_subdev *sd)
 
 
 	disable_input(sd);
 	disable_input(sd);
 
 
+	/*
+	 * Disable I2C access to internal EDID ram from HDMI DDC ports
+	 * Disable auto edid enable when leaving powerdown mode
+	 */
+	rep_write_and_or(sd, 0x77, 0xd3, 0x20);
+
 	/* power */
 	/* power */
 	io_write(sd, 0x0c, 0x42);   /* Power up part and power down VDP */
 	io_write(sd, 0x0c, 0x42);   /* Power up part and power down VDP */
 	io_write(sd, 0x15, 0x80);   /* Power up pads */
 	io_write(sd, 0x15, 0x80);   /* Power up pads */
@@ -2690,9 +2699,6 @@ static int adv7842_core_init(struct v4l2_subdev *sd)
 
 
 	enable_input(sd);
 	enable_input(sd);
 
 
-	/* disable I2C access to internal EDID ram from HDMI DDC ports */
-	rep_write_and_or(sd, 0x77, 0xf3, 0x00);
-
 	if (pdata->hpa_auto) {
 	if (pdata->hpa_auto) {
 		/* HPA auto, HPA 0.5s after Edid set and Cable detect */
 		/* HPA auto, HPA 0.5s after Edid set and Cable detect */
 		hdmi_write(sd, 0x69, 0x5c);
 		hdmi_write(sd, 0x69, 0x5c);
@@ -2869,8 +2875,6 @@ static const struct v4l2_ctrl_ops adv7842_ctrl_ops = {
 
 
 static const struct v4l2_subdev_core_ops adv7842_core_ops = {
 static const struct v4l2_subdev_core_ops adv7842_core_ops = {
 	.log_status = adv7842_log_status,
 	.log_status = adv7842_log_status,
-	.g_std = adv7842_g_std,
-	.s_std = adv7842_s_std,
 	.ioctl = adv7842_ioctl,
 	.ioctl = adv7842_ioctl,
 	.interrupt_service_routine = adv7842_isr,
 	.interrupt_service_routine = adv7842_isr,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -2880,14 +2884,14 @@ static const struct v4l2_subdev_core_ops adv7842_core_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_video_ops adv7842_video_ops = {
 static const struct v4l2_subdev_video_ops adv7842_video_ops = {
+	.g_std = adv7842_g_std,
+	.s_std = adv7842_s_std,
 	.s_routing = adv7842_s_routing,
 	.s_routing = adv7842_s_routing,
 	.querystd = adv7842_querystd,
 	.querystd = adv7842_querystd,
 	.g_input_status = adv7842_g_input_status,
 	.g_input_status = adv7842_g_input_status,
 	.s_dv_timings = adv7842_s_dv_timings,
 	.s_dv_timings = adv7842_s_dv_timings,
 	.g_dv_timings = adv7842_g_dv_timings,
 	.g_dv_timings = adv7842_g_dv_timings,
 	.query_dv_timings = adv7842_query_dv_timings,
 	.query_dv_timings = adv7842_query_dv_timings,
-	.enum_dv_timings = adv7842_enum_dv_timings,
-	.dv_timings_cap = adv7842_dv_timings_cap,
 	.enum_mbus_fmt = adv7842_enum_mbus_fmt,
 	.enum_mbus_fmt = adv7842_enum_mbus_fmt,
 	.g_mbus_fmt = adv7842_g_mbus_fmt,
 	.g_mbus_fmt = adv7842_g_mbus_fmt,
 	.try_mbus_fmt = adv7842_g_mbus_fmt,
 	.try_mbus_fmt = adv7842_g_mbus_fmt,
@@ -2897,6 +2901,8 @@ static const struct v4l2_subdev_video_ops adv7842_video_ops = {
 static const struct v4l2_subdev_pad_ops adv7842_pad_ops = {
 static const struct v4l2_subdev_pad_ops adv7842_pad_ops = {
 	.get_edid = adv7842_get_edid,
 	.get_edid = adv7842_get_edid,
 	.set_edid = adv7842_set_edid,
 	.set_edid = adv7842_set_edid,
+	.enum_dv_timings = adv7842_enum_dv_timings,
+	.dv_timings_cap = adv7842_dv_timings_cap,
 };
 };
 
 
 static const struct v4l2_subdev_ops adv7842_ops = {
 static const struct v4l2_subdev_ops adv7842_ops = {

+ 1 - 1
drivers/media/i2c/bt819.c

@@ -387,10 +387,10 @@ static const struct v4l2_subdev_core_ops bt819_core_ops = {
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
 	.querymenu = v4l2_subdev_querymenu,
-	.s_std = bt819_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops bt819_video_ops = {
 static const struct v4l2_subdev_video_ops bt819_video_ops = {
+	.s_std = bt819_s_std,
 	.s_routing = bt819_s_routing,
 	.s_routing = bt819_s_routing,
 	.s_stream = bt819_s_stream,
 	.s_stream = bt819_s_stream,
 	.querystd = bt819_querystd,
 	.querystd = bt819_querystd,

+ 2 - 2
drivers/media/i2c/cx25840/cx25840-core.c

@@ -5041,8 +5041,6 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = {
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
 	.querymenu = v4l2_subdev_querymenu,
-	.s_std = cx25840_s_std,
-	.g_std = cx25840_g_std,
 	.reset = cx25840_reset,
 	.reset = cx25840_reset,
 	.load_fw = cx25840_load_fw,
 	.load_fw = cx25840_load_fw,
 	.s_io_pin_config = common_s_io_pin_config,
 	.s_io_pin_config = common_s_io_pin_config,
@@ -5067,6 +5065,8 @@ static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_video_ops cx25840_video_ops = {
 static const struct v4l2_subdev_video_ops cx25840_video_ops = {
+	.s_std = cx25840_s_std,
+	.g_std = cx25840_g_std,
 	.s_routing = cx25840_s_video_routing,
 	.s_routing = cx25840_s_video_routing,
 	.s_mbus_fmt = cx25840_s_mbus_fmt,
 	.s_mbus_fmt = cx25840_s_mbus_fmt,
 	.s_stream = cx25840_s_stream,
 	.s_stream = cx25840_s_stream,

+ 1 - 5
drivers/media/i2c/ks0127.c

@@ -648,11 +648,8 @@ static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
 
 
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */
 
 
-static const struct v4l2_subdev_core_ops ks0127_core_ops = {
-	.s_std = ks0127_s_std,
-};
-
 static const struct v4l2_subdev_video_ops ks0127_video_ops = {
 static const struct v4l2_subdev_video_ops ks0127_video_ops = {
+	.s_std = ks0127_s_std,
 	.s_routing = ks0127_s_routing,
 	.s_routing = ks0127_s_routing,
 	.s_stream = ks0127_s_stream,
 	.s_stream = ks0127_s_stream,
 	.querystd = ks0127_querystd,
 	.querystd = ks0127_querystd,
@@ -660,7 +657,6 @@ static const struct v4l2_subdev_video_ops ks0127_video_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_ops ks0127_ops = {
 static const struct v4l2_subdev_ops ks0127_ops = {
-	.core = &ks0127_core_ops,
 	.video = &ks0127_video_ops,
 	.video = &ks0127_video_ops,
 };
 };
 
 

+ 1 - 1
drivers/media/i2c/m5mols/m5mols_capture.c

@@ -26,7 +26,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-subdev.h>
 #include <media/m5mols.h>
 #include <media/m5mols.h>
-#include <media/s5p_fimc.h>
+#include <media/exynos-fimc.h>
 
 
 #include "m5mols.h"
 #include "m5mols.h"
 #include "m5mols_reg.h"
 #include "m5mols_reg.h"

+ 1 - 1
drivers/media/i2c/ml86v7667.c

@@ -276,6 +276,7 @@ static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = {
 };
 };
 
 
 static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
 static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
+	.s_std = ml86v7667_s_std,
 	.querystd = ml86v7667_querystd,
 	.querystd = ml86v7667_querystd,
 	.g_input_status = ml86v7667_g_input_status,
 	.g_input_status = ml86v7667_g_input_status,
 	.enum_mbus_fmt = ml86v7667_enum_mbus_fmt,
 	.enum_mbus_fmt = ml86v7667_enum_mbus_fmt,
@@ -286,7 +287,6 @@ static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
 };
 };
 
 
 static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
 static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
-	.s_std = ml86v7667_s_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = ml86v7667_g_register,
 	.g_register = ml86v7667_g_register,
 	.s_register = ml86v7667_s_register,
 	.s_register = ml86v7667_s_register,

+ 1 - 1
drivers/media/i2c/msp3400-driver.c

@@ -649,10 +649,10 @@ static const struct v4l2_subdev_core_ops msp_core_ops = {
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
 	.querymenu = v4l2_subdev_querymenu,
-	.s_std = msp_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops msp_video_ops = {
 static const struct v4l2_subdev_video_ops msp_video_ops = {
+	.s_std = msp_s_std,
 	.querystd = msp_querystd,
 	.querystd = msp_querystd,
 };
 };
 
 

+ 39 - 14
drivers/media/i2c/mt9p031.c

@@ -647,6 +647,28 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev,
 #define V4L2_CID_BLC_ANALOG_OFFSET	(V4L2_CID_USER_BASE | 0x1004)
 #define V4L2_CID_BLC_ANALOG_OFFSET	(V4L2_CID_USER_BASE | 0x1004)
 #define V4L2_CID_BLC_DIGITAL_OFFSET	(V4L2_CID_USER_BASE | 0x1005)
 #define V4L2_CID_BLC_DIGITAL_OFFSET	(V4L2_CID_USER_BASE | 0x1005)
 
 
+static int mt9p031_restore_blc(struct mt9p031 *mt9p031)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
+	int ret;
+
+	if (mt9p031->blc_auto->cur.val != 0) {
+		ret = mt9p031_set_mode2(mt9p031, 0,
+					MT9P031_READ_MODE_2_ROW_BLC);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (mt9p031->blc_offset->cur.val != 0) {
+		ret = mt9p031_write(client, MT9P031_ROW_BLACK_TARGET,
+				    mt9p031->blc_offset->cur.val);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
 static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 {
 	struct mt9p031 *mt9p031 =
 	struct mt9p031 *mt9p031 =
@@ -655,6 +677,9 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
 	u16 data;
 	u16 data;
 	int ret;
 	int ret;
 
 
+	if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
+		return 0;
+
 	switch (ctrl->id) {
 	switch (ctrl->id) {
 	case V4L2_CID_EXPOSURE:
 	case V4L2_CID_EXPOSURE:
 		ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER,
 		ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER,
@@ -709,18 +734,20 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
 					MT9P031_READ_MODE_2_ROW_MIR, 0);
 					MT9P031_READ_MODE_2_ROW_MIR, 0);
 
 
 	case V4L2_CID_TEST_PATTERN:
 	case V4L2_CID_TEST_PATTERN:
+		/* The digital side of the Black Level Calibration function must
+		 * be disabled when generating a test pattern to avoid artifacts
+		 * in the image. Activate (deactivate) the BLC-related controls
+		 * when the test pattern is enabled (disabled).
+		 */
+		v4l2_ctrl_activate(mt9p031->blc_auto, ctrl->val == 0);
+		v4l2_ctrl_activate(mt9p031->blc_offset, ctrl->val == 0);
+
 		if (!ctrl->val) {
 		if (!ctrl->val) {
-			/* Restore the black level compensation settings. */
-			if (mt9p031->blc_auto->cur.val != 0) {
-				ret = mt9p031_s_ctrl(mt9p031->blc_auto);
-				if (ret < 0)
-					return ret;
-			}
-			if (mt9p031->blc_offset->cur.val != 0) {
-				ret = mt9p031_s_ctrl(mt9p031->blc_offset);
-				if (ret < 0)
-					return ret;
-			}
+			/* Restore the BLC settings. */
+			ret = mt9p031_restore_blc(mt9p031);
+			if (ret < 0)
+				return ret;
+
 			return mt9p031_write(client, MT9P031_TEST_PATTERN,
 			return mt9p031_write(client, MT9P031_TEST_PATTERN,
 					     MT9P031_TEST_PATTERN_DISABLE);
 					     MT9P031_TEST_PATTERN_DISABLE);
 		}
 		}
@@ -735,9 +762,7 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
 
 
-		/* Disable digital black level compensation when using a test
-		 * pattern.
-		 */
+		/* Disable digital BLC when generating a test pattern. */
 		ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
 		ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
 					0);
 					0);
 		if (ret < 0)
 		if (ret < 0)

+ 1 - 1
drivers/media/i2c/saa6752hs.c

@@ -643,10 +643,10 @@ static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = {
 
 
 static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
 static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
 	.init = saa6752hs_init,
 	.init = saa6752hs_init,
-	.s_std = saa6752hs_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
 static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
+	.s_std = saa6752hs_s_std,
 	.s_mbus_fmt = saa6752hs_s_mbus_fmt,
 	.s_mbus_fmt = saa6752hs_s_mbus_fmt,
 	.try_mbus_fmt = saa6752hs_try_mbus_fmt,
 	.try_mbus_fmt = saa6752hs_try_mbus_fmt,
 	.g_mbus_fmt = saa6752hs_g_mbus_fmt,
 	.g_mbus_fmt = saa6752hs_g_mbus_fmt,

+ 1 - 1
drivers/media/i2c/saa7110.c

@@ -365,10 +365,10 @@ static const struct v4l2_subdev_core_ops saa7110_core_ops = {
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
 	.querymenu = v4l2_subdev_querymenu,
-	.s_std = saa7110_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops saa7110_video_ops = {
 static const struct v4l2_subdev_video_ops saa7110_video_ops = {
+	.s_std = saa7110_s_std,
 	.s_routing = saa7110_s_routing,
 	.s_routing = saa7110_s_routing,
 	.s_stream = saa7110_s_stream,
 	.s_stream = saa7110_s_stream,
 	.querystd = saa7110_querystd,
 	.querystd = saa7110_querystd,

+ 1 - 1
drivers/media/i2c/saa7115.c

@@ -1582,7 +1582,6 @@ static const struct v4l2_subdev_core_ops saa711x_core_ops = {
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
 	.querymenu = v4l2_subdev_querymenu,
-	.s_std = saa711x_s_std,
 	.reset = saa711x_reset,
 	.reset = saa711x_reset,
 	.s_gpio = saa711x_s_gpio,
 	.s_gpio = saa711x_s_gpio,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1601,6 +1600,7 @@ static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_video_ops saa711x_video_ops = {
 static const struct v4l2_subdev_video_ops saa711x_video_ops = {
+	.s_std = saa711x_s_std,
 	.s_routing = saa711x_s_routing,
 	.s_routing = saa711x_s_routing,
 	.s_crystal_freq = saa711x_s_crystal_freq,
 	.s_crystal_freq = saa711x_s_crystal_freq,
 	.s_mbus_fmt = saa711x_s_mbus_fmt,
 	.s_mbus_fmt = saa711x_s_mbus_fmt,

+ 1 - 1
drivers/media/i2c/saa717x.c

@@ -1198,7 +1198,6 @@ static const struct v4l2_subdev_core_ops saa717x_core_ops = {
 	.g_register = saa717x_g_register,
 	.g_register = saa717x_g_register,
 	.s_register = saa717x_s_register,
 	.s_register = saa717x_s_register,
 #endif
 #endif
-	.s_std = saa717x_s_std,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -1216,6 +1215,7 @@ static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_video_ops saa717x_video_ops = {
 static const struct v4l2_subdev_video_ops saa717x_video_ops = {
+	.s_std = saa717x_s_std,
 	.s_routing = saa717x_s_video_routing,
 	.s_routing = saa717x_s_video_routing,
 	.s_mbus_fmt = saa717x_s_mbus_fmt,
 	.s_mbus_fmt = saa717x_s_mbus_fmt,
 	.s_stream = saa717x_s_stream,
 	.s_stream = saa717x_s_stream,

+ 1 - 1
drivers/media/i2c/saa7191.c

@@ -573,10 +573,10 @@ static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status)
 static const struct v4l2_subdev_core_ops saa7191_core_ops = {
 static const struct v4l2_subdev_core_ops saa7191_core_ops = {
 	.g_ctrl = saa7191_g_ctrl,
 	.g_ctrl = saa7191_g_ctrl,
 	.s_ctrl = saa7191_s_ctrl,
 	.s_ctrl = saa7191_s_ctrl,
-	.s_std = saa7191_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops saa7191_video_ops = {
 static const struct v4l2_subdev_video_ops saa7191_video_ops = {
+	.s_std = saa7191_s_std,
 	.s_routing = saa7191_s_routing,
 	.s_routing = saa7191_s_routing,
 	.querystd = saa7191_querystd,
 	.querystd = saa7191_querystd,
 	.g_input_status = saa7191_g_input_status,
 	.g_input_status = saa7191_g_input_status,

+ 1 - 1
drivers/media/i2c/smiapp-pll.h

@@ -46,7 +46,7 @@ struct smiapp_pll {
 			uint8_t bus_width;
 			uint8_t bus_width;
 		} parallel;
 		} parallel;
 	};
 	};
-	uint8_t flags;
+	unsigned long flags;
 	uint8_t binning_horizontal;
 	uint8_t binning_horizontal;
 	uint8_t binning_vertical;
 	uint8_t binning_vertical;
 	uint8_t scale_m;
 	uint8_t scale_m;

+ 29 - 28
drivers/media/i2c/smiapp/smiapp-core.c

@@ -606,7 +606,7 @@ static int smiapp_get_limits(struct smiapp_sensor *sensor, int const *limit,
 		if (rval)
 		if (rval)
 			return rval;
 			return rval;
 		sensor->limits[limit[i]] = val;
 		sensor->limits[limit[i]] = val;
-		dev_dbg(&client->dev, "0x%8.8x \"%s\" = %d, 0x%x\n",
+		dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n",
 			smiapp_reg_limits[limit[i]].addr,
 			smiapp_reg_limits[limit[i]].addr,
 			smiapp_reg_limits[limit[i]].what, val, val);
 			smiapp_reg_limits[limit[i]].what, val, val);
 	}
 	}
@@ -741,8 +741,8 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor)
 		if (rval)
 		if (rval)
 			return rval;
 			return rval;
 
 
-		dev_dbg(&client->dev, "bpp %d, compressed %d\n",
-			fmt >> 8, (u8)fmt);
+		dev_dbg(&client->dev, "%u: bpp %u, compressed %u\n",
+			i, fmt >> 8, (u8)fmt);
 
 
 		for (j = 0; j < ARRAY_SIZE(smiapp_csi_data_formats); j++) {
 		for (j = 0; j < ARRAY_SIZE(smiapp_csi_data_formats); j++) {
 			const struct smiapp_csi_data_format *f =
 			const struct smiapp_csi_data_format *f =
@@ -1128,7 +1128,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor)
 	}
 	}
 	usleep_range(1000, 1000);
 	usleep_range(1000, 1000);
 
 
-	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
+	if (gpio_is_valid(sensor->platform_data->xshutdown))
 		gpio_set_value(sensor->platform_data->xshutdown, 1);
 		gpio_set_value(sensor->platform_data->xshutdown, 1);
 
 
 	sleep = SMIAPP_RESET_DELAY(sensor->platform_data->ext_clk);
 	sleep = SMIAPP_RESET_DELAY(sensor->platform_data->ext_clk);
@@ -1238,7 +1238,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor)
 	return 0;
 	return 0;
 
 
 out_cci_addr_fail:
 out_cci_addr_fail:
-	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
+	if (gpio_is_valid(sensor->platform_data->xshutdown))
 		gpio_set_value(sensor->platform_data->xshutdown, 0);
 		gpio_set_value(sensor->platform_data->xshutdown, 0);
 	if (sensor->platform_data->set_xclk)
 	if (sensor->platform_data->set_xclk)
 		sensor->platform_data->set_xclk(&sensor->src->sd, 0);
 		sensor->platform_data->set_xclk(&sensor->src->sd, 0);
@@ -1264,7 +1264,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor)
 			     SMIAPP_REG_U8_SOFTWARE_RESET,
 			     SMIAPP_REG_U8_SOFTWARE_RESET,
 			     SMIAPP_SOFTWARE_RESET);
 			     SMIAPP_SOFTWARE_RESET);
 
 
-	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
+	if (gpio_is_valid(sensor->platform_data->xshutdown))
 		gpio_set_value(sensor->platform_data->xshutdown, 0);
 		gpio_set_value(sensor->platform_data->xshutdown, 0);
 	if (sensor->platform_data->set_xclk)
 	if (sensor->platform_data->set_xclk)
 		sensor->platform_data->set_xclk(&sensor->src->sd, 0);
 		sensor->platform_data->set_xclk(&sensor->src->sd, 0);
@@ -1766,7 +1766,7 @@ static void smiapp_set_compose_binner(struct v4l2_subdev *subdev,
 	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
 	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
 	unsigned int i;
 	unsigned int i;
 	unsigned int binh = 1, binv = 1;
 	unsigned int binh = 1, binv = 1;
-	unsigned int best = scaling_goodness(
+	int best = scaling_goodness(
 		subdev,
 		subdev,
 		crops[SMIAPP_PAD_SINK]->width, sel->r.width,
 		crops[SMIAPP_PAD_SINK]->width, sel->r.width,
 		crops[SMIAPP_PAD_SINK]->height, sel->r.height, sel->flags);
 		crops[SMIAPP_PAD_SINK]->height, sel->r.height, sel->flags);
@@ -2355,17 +2355,17 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
 	unsigned int i;
 	unsigned int i;
 	int rval;
 	int rval;
 
 
-	sensor->vana = devm_regulator_get(&client->dev, "VANA");
+	sensor->vana = devm_regulator_get(&client->dev, "vana");
 	if (IS_ERR(sensor->vana)) {
 	if (IS_ERR(sensor->vana)) {
 		dev_err(&client->dev, "could not get regulator for vana\n");
 		dev_err(&client->dev, "could not get regulator for vana\n");
-		return -ENODEV;
+		return PTR_ERR(sensor->vana);
 	}
 	}
 
 
 	if (!sensor->platform_data->set_xclk) {
 	if (!sensor->platform_data->set_xclk) {
 		sensor->ext_clk = devm_clk_get(&client->dev, "ext_clk");
 		sensor->ext_clk = devm_clk_get(&client->dev, "ext_clk");
 		if (IS_ERR(sensor->ext_clk)) {
 		if (IS_ERR(sensor->ext_clk)) {
 			dev_err(&client->dev, "could not get clock\n");
 			dev_err(&client->dev, "could not get clock\n");
-			return -ENODEV;
+			return PTR_ERR(sensor->ext_clk);
 		}
 		}
 
 
 		rval = clk_set_rate(sensor->ext_clk,
 		rval = clk_set_rate(sensor->ext_clk,
@@ -2374,18 +2374,19 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
 			dev_err(&client->dev,
 			dev_err(&client->dev,
 				"unable to set clock freq to %u\n",
 				"unable to set clock freq to %u\n",
 				sensor->platform_data->ext_clk);
 				sensor->platform_data->ext_clk);
-			return -ENODEV;
+			return rval;
 		}
 		}
 	}
 	}
 
 
-	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) {
-		if (devm_gpio_request_one(&client->dev,
-					  sensor->platform_data->xshutdown, 0,
-					  "SMIA++ xshutdown") != 0) {
+	if (gpio_is_valid(sensor->platform_data->xshutdown)) {
+		rval = devm_gpio_request_one(
+			&client->dev, sensor->platform_data->xshutdown, 0,
+			"SMIA++ xshutdown");
+		if (rval < 0) {
 			dev_err(&client->dev,
 			dev_err(&client->dev,
 				"unable to acquire reset gpio %d\n",
 				"unable to acquire reset gpio %d\n",
 				sensor->platform_data->xshutdown);
 				sensor->platform_data->xshutdown);
-			return -ENODEV;
+			return rval;
 		}
 		}
 	}
 	}
 
 
@@ -2423,6 +2424,12 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
 		sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP |
 		sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP |
 					  SMIAPP_IMAGE_ORIENTATION_VFLIP;
 					  SMIAPP_IMAGE_ORIENTATION_VFLIP;
 
 
+	rval = smiapp_call_quirk(sensor, limits);
+	if (rval) {
+		dev_err(&client->dev, "limits quirks failed\n");
+		goto out_power_off;
+	}
+
 	rval = smiapp_get_mbus_formats(sensor);
 	rval = smiapp_get_mbus_formats(sensor);
 	if (rval) {
 	if (rval) {
 		rval = -ENODEV;
 		rval = -ENODEV;
@@ -2483,12 +2490,6 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
 		}
 		}
 	}
 	}
 
 
-	rval = smiapp_call_quirk(sensor, limits);
-	if (rval) {
-		dev_err(&client->dev, "limits quirks failed\n");
-		goto out_nvm_release;
-	}
-
 	/* We consider this as profile 0 sensor if any of these are zero. */
 	/* We consider this as profile 0 sensor if any of these are zero. */
 	if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||
 	if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||
 	    !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||
 	    !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||
@@ -2543,8 +2544,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
 		}
 		}
 
 
 		snprintf(this->sd.name,
 		snprintf(this->sd.name,
-			 sizeof(this->sd.name), "%s %s",
-			 sensor->minfo.name, _this->name);
+			 sizeof(this->sd.name), "%s %d-%4.4x %s",
+			 sensor->minfo.name, i2c_adapter_id(client->adapter),
+			 client->addr, _this->name);
 
 
 		this->sink_fmt.width =
 		this->sink_fmt.width =
 			sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
 			sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
@@ -2616,12 +2618,11 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
 	pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
 	pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
 	pll->csi2.lanes = sensor->platform_data->lanes;
 	pll->csi2.lanes = sensor->platform_data->lanes;
 	pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
 	pll->ext_clk_freq_hz = sensor->platform_data->ext_clk;
+	pll->flags = smiapp_call_quirk(sensor, pll_flags);
+
 	/* Profile 0 sensors have no separate OP clock branch. */
 	/* Profile 0 sensors have no separate OP clock branch. */
 	if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
 	if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
 		pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
 		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];
 	pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
 
 
 	rval = smiapp_update_mode(sensor);
 	rval = smiapp_update_mode(sensor);
@@ -2830,7 +2831,7 @@ static int smiapp_remove(struct i2c_client *client)
 	unsigned int i;
 	unsigned int i;
 
 
 	if (sensor->power_count) {
 	if (sensor->power_count) {
-		if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
+		if (gpio_is_valid(sensor->platform_data->xshutdown))
 			gpio_set_value(sensor->platform_data->xshutdown, 0);
 			gpio_set_value(sensor->platform_data->xshutdown, 0);
 		if (sensor->platform_data->set_xclk)
 		if (sensor->platform_data->set_xclk)
 			sensor->platform_data->set_xclk(&sensor->src->sd, 0);
 			sensor->platform_data->set_xclk(&sensor->src->sd, 0);

+ 7 - 48
drivers/media/i2c/smiapp/smiapp-quirk.c

@@ -28,7 +28,7 @@
 
 
 static int smiapp_write_8(struct smiapp_sensor *sensor, u16 reg, u8 val)
 static int smiapp_write_8(struct smiapp_sensor *sensor, u16 reg, u8 val)
 {
 {
-	return smiapp_write(sensor, (SMIA_REG_8BIT << 16) | reg, val);
+	return smiapp_write(sensor, SMIAPP_REG_MK_U8(reg), val);
 }
 }
 
 
 static int smiapp_write_8s(struct smiapp_sensor *sensor,
 static int smiapp_write_8s(struct smiapp_sensor *sensor,
@@ -61,52 +61,6 @@ void smiapp_replace_limit(struct smiapp_sensor *sensor,
 	sensor->limits[limit] = val;
 	sensor->limits[limit] = val;
 }
 }
 
 
-bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
-		      u32 reg, u32 *val)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
-	const struct smia_reg *sreg;
-
-	if (!sensor->minfo.quirk)
-		return false;
-
-	sreg = sensor->minfo.quirk->regs;
-
-	if (!sreg)
-		return false;
-
-	while (sreg->type) {
-		u16 type = reg >> 16;
-		u16 reg16 = reg;
-
-		if (sreg->type != type || sreg->reg != reg16) {
-			sreg++;
-			continue;
-		}
-
-		switch ((u8)type) {
-		case SMIA_REG_8BIT:
-			dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%2.2x\n",
-				reg, sreg->val);
-			break;
-		case SMIA_REG_16BIT:
-			dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%4.4x\n",
-				reg, sreg->val);
-			break;
-		case SMIA_REG_32BIT:
-			dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%8.8x\n",
-				reg, sreg->val);
-			break;
-		}
-
-		*val = sreg->val;
-
-		return true;
-	}
-
-	return false;
-}
-
 static int jt8ew9_limits(struct smiapp_sensor *sensor)
 static int jt8ew9_limits(struct smiapp_sensor *sensor)
 {
 {
 	if (sensor->minfo.revision_number_major < 0x03)
 	if (sensor->minfo.revision_number_major < 0x03)
@@ -266,12 +220,17 @@ static int jt8ev1_post_streamoff(struct smiapp_sensor *sensor)
 	return smiapp_write_8(sensor, 0x3328, 0x80);
 	return smiapp_write_8(sensor, 0x3328, 0x80);
 }
 }
 
 
+static unsigned long jt8ev1_pll_flags(struct smiapp_sensor *sensor)
+{
+	return SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE;
+}
+
 const struct smiapp_quirk smiapp_jt8ev1_quirk = {
 const struct smiapp_quirk smiapp_jt8ev1_quirk = {
 	.limits = jt8ev1_limits,
 	.limits = jt8ev1_limits,
 	.post_poweron = jt8ev1_post_poweron,
 	.post_poweron = jt8ev1_post_poweron,
 	.pre_streamon = jt8ev1_pre_streamon,
 	.pre_streamon = jt8ev1_pre_streamon,
 	.post_streamoff = jt8ev1_post_streamoff,
 	.post_streamoff = jt8ev1_post_streamoff,
-	.flags = SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE,
+	.pll_flags = jt8ev1_pll_flags,
 };
 };
 
 
 static int tcm8500md_limits(struct smiapp_sensor *sensor)
 static int tcm8500md_limits(struct smiapp_sensor *sensor)

+ 16 - 8
drivers/media/i2c/smiapp/smiapp-quirk.h

@@ -35,19 +35,30 @@ struct smiapp_sensor;
  * @post_poweron: Called always after the sensor has been fully powered on.
  * @post_poweron: Called always after the sensor has been fully powered on.
  * @pre_streamon: Called just before streaming is enabled.
  * @pre_streamon: Called just before streaming is enabled.
  * @post_streamon: Called right after stopping streaming.
  * @post_streamon: Called right after stopping streaming.
+ * @reg_access: Register access quirk. The quirk may divert the access
+ *		to another register, or no register at all.
+ *
+ *		@write: Is this read (false) or write (true) access?
+ *		@reg: Pointer to the register to access
+ *		@value: Register value, set by the caller on write, or
+ *			by the quirk on read
+ *
+ *		@return: 0 on success, -ENOIOCTLCMD if no register
+ *			 access may be done by the caller (default read
+ *			 value is zero), else negative error code on error
  */
  */
 struct smiapp_quirk {
 struct smiapp_quirk {
 	int (*limits)(struct smiapp_sensor *sensor);
 	int (*limits)(struct smiapp_sensor *sensor);
 	int (*post_poweron)(struct smiapp_sensor *sensor);
 	int (*post_poweron)(struct smiapp_sensor *sensor);
 	int (*pre_streamon)(struct smiapp_sensor *sensor);
 	int (*pre_streamon)(struct smiapp_sensor *sensor);
 	int (*post_streamoff)(struct smiapp_sensor *sensor);
 	int (*post_streamoff)(struct smiapp_sensor *sensor);
-	const struct smia_reg *regs;
+	unsigned long (*pll_flags)(struct smiapp_sensor *sensor);
+	int (*reg_access)(struct smiapp_sensor *sensor, bool write, u32 *reg,
+			  u32 *val);
 	unsigned long flags;
 	unsigned long flags;
 };
 };
 
 
-/* op pix clock is for all lanes in total normally */
-#define SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE			(1 << 0)
-#define SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY			(1 << 1)
+#define SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY			(1 << 0)
 
 
 struct smiapp_reg_8 {
 struct smiapp_reg_8 {
 	u16 reg;
 	u16 reg;
@@ -56,12 +67,9 @@ struct smiapp_reg_8 {
 
 
 void smiapp_replace_limit(struct smiapp_sensor *sensor,
 void smiapp_replace_limit(struct smiapp_sensor *sensor,
 			  u32 limit, u32 val);
 			  u32 limit, u32 val);
-bool smiapp_quirk_reg(struct smiapp_sensor *sensor,
-		      u32 reg, u32 *val);
 
 
-#define SMIAPP_MK_QUIRK_REG(_reg, _val) \
+#define SMIAPP_MK_QUIRK_REG_8(_reg, _val) \
 	{				\
 	{				\
-		.type = (_reg >> 16),	\
 		.reg = (u16)_reg,	\
 		.reg = (u16)_reg,	\
 		.val = _val,		\
 		.val = _val,		\
 	}
 	}

+ 4 - 4
drivers/media/i2c/smiapp/smiapp-reg-defs.h

@@ -21,11 +21,11 @@
  * 02110-1301 USA
  * 02110-1301 USA
  *
  *
  */
  */
-#define SMIAPP_REG_MK_U8(r) ((SMIA_REG_8BIT << 16) | (r))
-#define SMIAPP_REG_MK_U16(r) ((SMIA_REG_16BIT << 16) | (r))
-#define SMIAPP_REG_MK_U32(r) ((SMIA_REG_32BIT << 16) | (r))
+#define SMIAPP_REG_MK_U8(r) ((SMIAPP_REG_8BIT << 16) | (r))
+#define SMIAPP_REG_MK_U16(r) ((SMIAPP_REG_16BIT << 16) | (r))
+#define SMIAPP_REG_MK_U32(r) ((SMIAPP_REG_32BIT << 16) | (r))
 
 
-#define SMIAPP_REG_MK_F32(r) (SMIA_REG_FLAG_FLOAT | (SMIA_REG_32BIT << 16) | (r))
+#define SMIAPP_REG_MK_F32(r) (SMIAPP_REG_FLAG_FLOAT | (SMIAPP_REG_32BIT << 16) | (r))
 
 
 #define SMIAPP_REG_U16_MODEL_ID					SMIAPP_REG_MK_U16(0x0000)
 #define SMIAPP_REG_U16_MODEL_ID					SMIAPP_REG_MK_U16(0x0000)
 #define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR			SMIAPP_REG_MK_U8(0x0002)
 #define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR			SMIAPP_REG_MK_U8(0x0002)

+ 61 - 28
drivers/media/i2c/smiapp/smiapp-regs.c

@@ -114,14 +114,14 @@ static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg,
 	*val = 0;
 	*val = 0;
 	/* high byte comes first */
 	/* high byte comes first */
 	switch (len) {
 	switch (len) {
-	case SMIA_REG_32BIT:
+	case SMIAPP_REG_32BIT:
 		*val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) +
 		*val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) +
 			data[3];
 			data[3];
 		break;
 		break;
-	case SMIA_REG_16BIT:
+	case SMIAPP_REG_16BIT:
 		*val = (data[0] << 8) + data[1];
 		*val = (data[0] << 8) + data[1];
 		break;
 		break;
-	case SMIA_REG_8BIT:
+	case SMIAPP_REG_8BIT:
 		*val = data[0];
 		*val = data[0];
 		break;
 		break;
 	default:
 	default:
@@ -165,31 +165,28 @@ static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val,
 			 bool only8)
 			 bool only8)
 {
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
-	unsigned int len = (u8)(reg >> 16);
+	u8 len = SMIAPP_REG_WIDTH(reg);
 	int rval;
 	int rval;
 
 
-	if (len != SMIA_REG_8BIT && len != SMIA_REG_16BIT
-	    && len != SMIA_REG_32BIT)
+	if (len != SMIAPP_REG_8BIT && len != SMIAPP_REG_16BIT
+	    && len != SMIAPP_REG_32BIT)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (smiapp_quirk_reg(sensor, reg, val))
-		goto found_quirk;
-
-	if (len == SMIA_REG_8BIT && !only8)
-		rval = ____smiapp_read(sensor, (u16)reg, len, val);
+	if (len == SMIAPP_REG_8BIT || !only8)
+		rval = ____smiapp_read(sensor, SMIAPP_REG_ADDR(reg), len, val);
 	else
 	else
-		rval = ____smiapp_read_8only(sensor, (u16)reg, len, val);
+		rval = ____smiapp_read_8only(sensor, SMIAPP_REG_ADDR(reg), len,
+					     val);
 	if (rval < 0)
 	if (rval < 0)
 		return rval;
 		return rval;
 
 
-found_quirk:
-	if (reg & SMIA_REG_FLAG_FLOAT)
+	if (reg & SMIAPP_REG_FLAG_FLOAT)
 		*val = float_to_u32_mul_1000000(client, *val);
 		*val = float_to_u32_mul_1000000(client, *val);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
+int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val)
 {
 {
 	return __smiapp_read(
 	return __smiapp_read(
 		sensor, reg, val,
 		sensor, reg, val,
@@ -197,28 +194,47 @@ int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
 				   SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY));
 				   SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY));
 }
 }
 
 
+int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val)
+{
+	int rval;
+
+	*val = 0;
+	rval = smiapp_call_quirk(sensor, reg_access, false, &reg, val);
+	if (rval == -ENOIOCTLCMD)
+		return 0;
+	if (rval < 0)
+		return rval;
+
+	return smiapp_read_no_quirk(sensor, reg, val);
+}
+
 int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val)
 int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val)
 {
 {
+	int rval;
+
+	*val = 0;
+	rval = smiapp_call_quirk(sensor, reg_access, false, &reg, val);
+	if (rval == -ENOIOCTLCMD)
+		return 0;
+	if (rval < 0)
+		return rval;
+
 	return __smiapp_read(sensor, reg, val, true);
 	return __smiapp_read(sensor, reg, val, true);
 }
 }
 
 
-/*
- * Write to a 8/16-bit register.
- * Returns zero if successful, or non-zero otherwise.
- */
-int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
+int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
 {
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
 	struct i2c_msg msg;
 	struct i2c_msg msg;
 	unsigned char data[6];
 	unsigned char data[6];
 	unsigned int retries;
 	unsigned int retries;
-	unsigned int flags = reg >> 24;
-	unsigned int len = (u8)(reg >> 16);
-	u16 offset = reg;
+	u8 flags = SMIAPP_REG_FLAGS(reg);
+	u8 len = SMIAPP_REG_WIDTH(reg);
+	u16 offset = SMIAPP_REG_ADDR(reg);
 	int r;
 	int r;
 
 
-	if ((len != SMIA_REG_8BIT && len != SMIA_REG_16BIT &&
-	     len != SMIA_REG_32BIT) || flags)
+	if ((len != SMIAPP_REG_8BIT && len != SMIAPP_REG_16BIT &&
+	     len != SMIAPP_REG_32BIT) || flags)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	msg.addr = client->addr;
 	msg.addr = client->addr;
@@ -231,14 +247,14 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
 	data[1] = (u8) (reg & 0xff);
 	data[1] = (u8) (reg & 0xff);
 
 
 	switch (len) {
 	switch (len) {
-	case SMIA_REG_8BIT:
+	case SMIAPP_REG_8BIT:
 		data[2] = val;
 		data[2] = val;
 		break;
 		break;
-	case SMIA_REG_16BIT:
+	case SMIAPP_REG_16BIT:
 		data[2] = val >> 8;
 		data[2] = val >> 8;
 		data[3] = val;
 		data[3] = val;
 		break;
 		break;
-	case SMIA_REG_32BIT:
+	case SMIAPP_REG_32BIT:
 		data[2] = val >> 24;
 		data[2] = val >> 24;
 		data[3] = val >> 16;
 		data[3] = val >> 16;
 		data[4] = val >> 8;
 		data[4] = val >> 8;
@@ -271,3 +287,20 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
 
 
 	return r;
 	return r;
 }
 }
+
+/*
+ * Write to a 8/16-bit register.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val)
+{
+	int rval;
+
+	rval = smiapp_call_quirk(sensor, reg_access, true, &reg, &val);
+	if (rval == -ENOIOCTLCMD)
+		return 0;
+	if (rval < 0)
+		return rval;
+
+	return smiapp_write_no_quirk(sensor, reg, val);
+}

+ 10 - 9
drivers/media/i2c/smiapp/smiapp-regs.h

@@ -28,22 +28,23 @@
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/types.h>
 #include <linux/types.h>
 
 
+#define SMIAPP_REG_ADDR(reg)		((u16)reg)
+#define SMIAPP_REG_WIDTH(reg)		((u8)(reg >> 16))
+#define SMIAPP_REG_FLAGS(reg)		((u8)(reg >> 24))
+
 /* Use upper 8 bits of the type field for flags */
 /* Use upper 8 bits of the type field for flags */
-#define SMIA_REG_FLAG_FLOAT		(1 << 24)
+#define SMIAPP_REG_FLAG_FLOAT		(1 << 24)
 
 
-#define SMIA_REG_8BIT			1
-#define SMIA_REG_16BIT			2
-#define SMIA_REG_32BIT			4
-struct smia_reg {
-	u16 type;
-	u16 reg;			/* 16-bit offset */
-	u32 val;			/* 8/16/32-bit value */
-};
+#define SMIAPP_REG_8BIT			1
+#define SMIAPP_REG_16BIT		2
+#define SMIAPP_REG_32BIT		4
 
 
 struct smiapp_sensor;
 struct smiapp_sensor;
 
 
+int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val);
 int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val);
 int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val);
 int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val);
 int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val);
+int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val);
 int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val);
 int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val);
 
 
 #endif
 #endif

+ 9 - 2
drivers/media/i2c/soc_camera/tw9910.c

@@ -814,8 +814,6 @@ done:
 }
 }
 
 
 static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
 static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
-	.s_std		= tw9910_s_std,
-	.g_std		= tw9910_g_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= tw9910_g_register,
 	.g_register	= tw9910_g_register,
 	.s_register	= tw9910_s_register,
 	.s_register	= tw9910_s_register,
@@ -872,7 +870,15 @@ static int tw9910_s_mbus_config(struct v4l2_subdev *sd,
 	return i2c_smbus_write_byte_data(client, OUTCTR1, val);
 	return i2c_smbus_write_byte_data(client, OUTCTR1, val);
 }
 }
 
 
+static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
+{
+	*norm = V4L2_STD_NTSC | V4L2_STD_PAL;
+	return 0;
+}
+
 static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
 static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
+	.s_std		= tw9910_s_std,
+	.g_std		= tw9910_g_std,
 	.s_stream	= tw9910_s_stream,
 	.s_stream	= tw9910_s_stream,
 	.g_mbus_fmt	= tw9910_g_fmt,
 	.g_mbus_fmt	= tw9910_g_fmt,
 	.s_mbus_fmt	= tw9910_s_fmt,
 	.s_mbus_fmt	= tw9910_s_fmt,
@@ -882,6 +888,7 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
 	.enum_mbus_fmt	= tw9910_enum_fmt,
 	.enum_mbus_fmt	= tw9910_enum_fmt,
 	.g_mbus_config	= tw9910_g_mbus_config,
 	.g_mbus_config	= tw9910_g_mbus_config,
 	.s_mbus_config	= tw9910_s_mbus_config,
 	.s_mbus_config	= tw9910_s_mbus_config,
+	.g_tvnorms	= tw9910_g_tvnorms,
 };
 };
 
 
 static struct v4l2_subdev_ops tw9910_subdev_ops = {
 static struct v4l2_subdev_ops tw9910_subdev_ops = {

+ 5 - 5
drivers/media/i2c/sony-btf-mpx.c

@@ -327,18 +327,18 @@ static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner
 
 
 /* --------------------------------------------------------------------------*/
 /* --------------------------------------------------------------------------*/
 
 
-static const struct v4l2_subdev_core_ops sony_btf_mpx_core_ops = {
-	.s_std = sony_btf_mpx_s_std,
-};
-
 static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = {
 static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = {
 	.s_tuner = sony_btf_mpx_s_tuner,
 	.s_tuner = sony_btf_mpx_s_tuner,
 	.g_tuner = sony_btf_mpx_g_tuner,
 	.g_tuner = sony_btf_mpx_g_tuner,
 };
 };
 
 
+static const struct v4l2_subdev_video_ops sony_btf_mpx_video_ops = {
+	.s_std = sony_btf_mpx_s_std,
+};
+
 static const struct v4l2_subdev_ops sony_btf_mpx_ops = {
 static const struct v4l2_subdev_ops sony_btf_mpx_ops = {
-	.core = &sony_btf_mpx_core_ops,
 	.tuner = &sony_btf_mpx_tuner_ops,
 	.tuner = &sony_btf_mpx_tuner_ops,
+	.video = &sony_btf_mpx_video_ops,
 };
 };
 
 
 /* --------------------------------------------------------------------------*/
 /* --------------------------------------------------------------------------*/

+ 10 - 0
drivers/media/i2c/ths8200.c

@@ -410,6 +410,9 @@ static int ths8200_g_dv_timings(struct v4l2_subdev *sd,
 static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
 static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
 				   struct v4l2_enum_dv_timings *timings)
 				   struct v4l2_enum_dv_timings *timings)
 {
 {
+	if (timings->pad != 0)
+		return -EINVAL;
+
 	return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap,
 	return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap,
 			NULL, NULL);
 			NULL, NULL);
 }
 }
@@ -417,6 +420,9 @@ static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
 static int ths8200_dv_timings_cap(struct v4l2_subdev *sd,
 static int ths8200_dv_timings_cap(struct v4l2_subdev *sd,
 				  struct v4l2_dv_timings_cap *cap)
 				  struct v4l2_dv_timings_cap *cap)
 {
 {
+	if (cap->pad != 0)
+		return -EINVAL;
+
 	*cap = ths8200_timings_cap;
 	*cap = ths8200_timings_cap;
 	return 0;
 	return 0;
 }
 }
@@ -426,6 +432,9 @@ static const struct v4l2_subdev_video_ops ths8200_video_ops = {
 	.s_stream = ths8200_s_stream,
 	.s_stream = ths8200_s_stream,
 	.s_dv_timings = ths8200_s_dv_timings,
 	.s_dv_timings = ths8200_s_dv_timings,
 	.g_dv_timings = ths8200_g_dv_timings,
 	.g_dv_timings = ths8200_g_dv_timings,
+};
+
+static const struct v4l2_subdev_pad_ops ths8200_pad_ops = {
 	.enum_dv_timings = ths8200_enum_dv_timings,
 	.enum_dv_timings = ths8200_enum_dv_timings,
 	.dv_timings_cap = ths8200_dv_timings_cap,
 	.dv_timings_cap = ths8200_dv_timings_cap,
 };
 };
@@ -434,6 +443,7 @@ static const struct v4l2_subdev_video_ops ths8200_video_ops = {
 static const struct v4l2_subdev_ops ths8200_ops = {
 static const struct v4l2_subdev_ops ths8200_ops = {
 	.core  = &ths8200_core_ops,
 	.core  = &ths8200_core_ops,
 	.video = &ths8200_video_ops,
 	.video = &ths8200_video_ops,
+	.pad = &ths8200_pad_ops,
 };
 };
 
 
 static int ths8200_probe(struct i2c_client *client,
 static int ths8200_probe(struct i2c_client *client,

+ 5 - 1
drivers/media/i2c/tvaudio.c

@@ -1862,7 +1862,6 @@ static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
 	.querymenu = v4l2_subdev_querymenu,
-	.s_std = tvaudio_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
 static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = {
@@ -1876,10 +1875,15 @@ static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = {
 	.s_routing = tvaudio_s_routing,
 	.s_routing = tvaudio_s_routing,
 };
 };
 
 
+static const struct v4l2_subdev_video_ops tvaudio_video_ops = {
+	.s_std = tvaudio_s_std,
+};
+
 static const struct v4l2_subdev_ops tvaudio_ops = {
 static const struct v4l2_subdev_ops tvaudio_ops = {
 	.core = &tvaudio_core_ops,
 	.core = &tvaudio_core_ops,
 	.tuner = &tvaudio_tuner_ops,
 	.tuner = &tvaudio_tuner_ops,
 	.audio = &tvaudio_audio_ops,
 	.audio = &tvaudio_audio_ops,
+	.video = &tvaudio_video_ops,
 };
 };
 
 
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */

+ 1 - 1
drivers/media/i2c/tvp514x.c

@@ -1010,10 +1010,10 @@ static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
 	.querymenu = v4l2_subdev_querymenu,
-	.s_std = tvp514x_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
 static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
+	.s_std = tvp514x_s_std,
 	.s_routing = tvp514x_s_routing,
 	.s_routing = tvp514x_s_routing,
 	.querystd = tvp514x_querystd,
 	.querystd = tvp514x_querystd,
 	.enum_mbus_fmt = tvp514x_enum_mbus_fmt,
 	.enum_mbus_fmt = tvp514x_enum_mbus_fmt,

+ 3 - 3
drivers/media/i2c/tvp5150.c

@@ -913,7 +913,7 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
 
 
 static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
 {
-	struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
+	struct tvp5150 *decoder = to_tvp5150(sd);
 
 
 	a->c	= decoder->rect;
 	a->c	= decoder->rect;
 	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -923,7 +923,7 @@ static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 
 
 static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 {
 {
-	struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
+	struct tvp5150 *decoder = to_tvp5150(sd);
 	v4l2_std_id std;
 	v4l2_std_id std;
 
 
 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1063,7 +1063,6 @@ static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
 
 
 static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
 static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
 	.log_status = tvp5150_log_status,
 	.log_status = tvp5150_log_status,
-	.s_std = tvp5150_s_std,
 	.reset = tvp5150_reset,
 	.reset = tvp5150_reset,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = tvp5150_g_register,
 	.g_register = tvp5150_g_register,
@@ -1076,6 +1075,7 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
 static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
+	.s_std = tvp5150_s_std,
 	.s_routing = tvp5150_s_routing,
 	.s_routing = tvp5150_s_routing,
 	.enum_mbus_fmt = tvp5150_enum_mbus_fmt,
 	.enum_mbus_fmt = tvp5150_enum_mbus_fmt,
 	.s_mbus_fmt = tvp5150_mbus_fmt,
 	.s_mbus_fmt = tvp5150_mbus_fmt,

+ 4 - 1
drivers/media/i2c/tvp7002.c

@@ -833,6 +833,9 @@ static int tvp7002_log_status(struct v4l2_subdev *sd)
 static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd,
 static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd,
 		struct v4l2_enum_dv_timings *timings)
 		struct v4l2_enum_dv_timings *timings)
 {
 {
+	if (timings->pad != 0)
+		return -EINVAL;
+
 	/* Check requested format index is within range */
 	/* Check requested format index is within range */
 	if (timings->index >= NUM_TIMINGS)
 	if (timings->index >= NUM_TIMINGS)
 		return -EINVAL;
 		return -EINVAL;
@@ -924,7 +927,6 @@ static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
 static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
 static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
 	.g_dv_timings = tvp7002_g_dv_timings,
 	.g_dv_timings = tvp7002_g_dv_timings,
 	.s_dv_timings = tvp7002_s_dv_timings,
 	.s_dv_timings = tvp7002_s_dv_timings,
-	.enum_dv_timings = tvp7002_enum_dv_timings,
 	.query_dv_timings = tvp7002_query_dv_timings,
 	.query_dv_timings = tvp7002_query_dv_timings,
 	.s_stream = tvp7002_s_stream,
 	.s_stream = tvp7002_s_stream,
 	.g_mbus_fmt = tvp7002_mbus_fmt,
 	.g_mbus_fmt = tvp7002_mbus_fmt,
@@ -938,6 +940,7 @@ static const struct v4l2_subdev_pad_ops tvp7002_pad_ops = {
 	.enum_mbus_code = tvp7002_enum_mbus_code,
 	.enum_mbus_code = tvp7002_enum_mbus_code,
 	.get_fmt = tvp7002_get_pad_format,
 	.get_fmt = tvp7002_get_pad_format,
 	.set_fmt = tvp7002_set_pad_format,
 	.set_fmt = tvp7002_set_pad_format,
+	.enum_dv_timings = tvp7002_enum_dv_timings,
 };
 };
 
 
 /* V4L2 top level operation handlers */
 /* V4L2 top level operation handlers */

+ 1 - 1
drivers/media/i2c/tw2804.c

@@ -342,12 +342,12 @@ static const struct v4l2_ctrl_ops tw2804_ctrl_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_video_ops tw2804_video_ops = {
 static const struct v4l2_subdev_video_ops tw2804_video_ops = {
+	.s_std = tw2804_s_std,
 	.s_routing = tw2804_s_video_routing,
 	.s_routing = tw2804_s_video_routing,
 };
 };
 
 
 static const struct v4l2_subdev_core_ops tw2804_core_ops = {
 static const struct v4l2_subdev_core_ops tw2804_core_ops = {
 	.log_status = tw2804_log_status,
 	.log_status = tw2804_log_status,
-	.s_std = tw2804_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_ops tw2804_ops = {
 static const struct v4l2_subdev_ops tw2804_ops = {

+ 1 - 1
drivers/media/i2c/tw9903.c

@@ -187,10 +187,10 @@ static const struct v4l2_ctrl_ops tw9903_ctrl_ops = {
 
 
 static const struct v4l2_subdev_core_ops tw9903_core_ops = {
 static const struct v4l2_subdev_core_ops tw9903_core_ops = {
 	.log_status = tw9903_log_status,
 	.log_status = tw9903_log_status,
-	.s_std = tw9903_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops tw9903_video_ops = {
 static const struct v4l2_subdev_video_ops tw9903_video_ops = {
+	.s_std = tw9903_s_std,
 	.s_routing = tw9903_s_video_routing,
 	.s_routing = tw9903_s_video_routing,
 };
 };
 
 

+ 1 - 1
drivers/media/i2c/tw9906.c

@@ -157,10 +157,10 @@ static const struct v4l2_ctrl_ops tw9906_ctrl_ops = {
 
 
 static const struct v4l2_subdev_core_ops tw9906_core_ops = {
 static const struct v4l2_subdev_core_ops tw9906_core_ops = {
 	.log_status = tw9906_log_status,
 	.log_status = tw9906_log_status,
-	.s_std = tw9906_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops tw9906_video_ops = {
 static const struct v4l2_subdev_video_ops tw9906_video_ops = {
+	.s_std = tw9906_s_std,
 	.s_routing = tw9906_s_video_routing,
 	.s_routing = tw9906_s_video_routing,
 };
 };
 
 

+ 5 - 1
drivers/media/i2c/vp27smpx.c

@@ -124,7 +124,6 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd)
 
 
 static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
 static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
 	.log_status = vp27smpx_log_status,
 	.log_status = vp27smpx_log_status,
-	.s_std = vp27smpx_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
 static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
@@ -133,9 +132,14 @@ static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = {
 	.g_tuner = vp27smpx_g_tuner,
 	.g_tuner = vp27smpx_g_tuner,
 };
 };
 
 
+static const struct v4l2_subdev_video_ops vp27smpx_video_ops = {
+	.s_std = vp27smpx_s_std,
+};
+
 static const struct v4l2_subdev_ops vp27smpx_ops = {
 static const struct v4l2_subdev_ops vp27smpx_ops = {
 	.core = &vp27smpx_core_ops,
 	.core = &vp27smpx_core_ops,
 	.tuner = &vp27smpx_tuner_ops,
 	.tuner = &vp27smpx_tuner_ops,
+	.video = &vp27smpx_video_ops,
 };
 };
 
 
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */

+ 1 - 1
drivers/media/i2c/vpx3220.c

@@ -457,10 +457,10 @@ static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
 	.querymenu = v4l2_subdev_querymenu,
-	.s_std = vpx3220_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
 static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
+	.s_std = vpx3220_s_std,
 	.s_routing = vpx3220_s_routing,
 	.s_routing = vpx3220_s_routing,
 	.s_stream = vpx3220_s_stream,
 	.s_stream = vpx3220_s_stream,
 	.querystd = vpx3220_querystd,
 	.querystd = vpx3220_querystd,

+ 4 - 3
drivers/media/media-device.c

@@ -373,7 +373,8 @@ static void media_device_release(struct media_devnode *mdev)
  * - dev must point to the parent device
  * - dev must point to the parent device
  * - model must be filled with the device model name
  * - model must be filled with the device model name
  */
  */
-int __must_check media_device_register(struct media_device *mdev)
+int __must_check __media_device_register(struct media_device *mdev,
+					 struct module *owner)
 {
 {
 	int ret;
 	int ret;
 
 
@@ -389,7 +390,7 @@ int __must_check media_device_register(struct media_device *mdev)
 	mdev->devnode.fops = &media_device_fops;
 	mdev->devnode.fops = &media_device_fops;
 	mdev->devnode.parent = mdev->dev;
 	mdev->devnode.parent = mdev->dev;
 	mdev->devnode.release = media_device_release;
 	mdev->devnode.release = media_device_release;
-	ret = media_devnode_register(&mdev->devnode);
+	ret = media_devnode_register(&mdev->devnode, owner);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -401,7 +402,7 @@ int __must_check media_device_register(struct media_device *mdev)
 
 
 	return 0;
 	return 0;
 }
 }
-EXPORT_SYMBOL_GPL(media_device_register);
+EXPORT_SYMBOL_GPL(__media_device_register);
 
 
 /**
 /**
  * media_device_unregister - unregister a media device
  * media_device_unregister - unregister a media device

+ 3 - 2
drivers/media/media-devnode.c

@@ -232,7 +232,8 @@ static const struct file_operations media_devnode_fops = {
  * the media_devnode structure is *not* called, so the caller is responsible for
  * the media_devnode structure is *not* called, so the caller is responsible for
  * freeing any data.
  * freeing any data.
  */
  */
-int __must_check media_devnode_register(struct media_devnode *mdev)
+int __must_check media_devnode_register(struct media_devnode *mdev,
+					struct module *owner)
 {
 {
 	int minor;
 	int minor;
 	int ret;
 	int ret;
@@ -253,7 +254,7 @@ int __must_check media_devnode_register(struct media_devnode *mdev)
 
 
 	/* Part 2: Initialize and register the character device */
 	/* Part 2: Initialize and register the character device */
 	cdev_init(&mdev->cdev, &media_devnode_fops);
 	cdev_init(&mdev->cdev, &media_devnode_fops);
-	mdev->cdev.owner = mdev->fops->owner;
+	mdev->cdev.owner = owner;
 
 
 	ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1);
 	ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1);
 	if (ret < 0) {
 	if (ret < 0) {

+ 1 - 1
drivers/media/parport/bw-qcam.c

@@ -937,7 +937,7 @@ static struct qcam *qcam_init(struct parport *port)
 		return NULL;
 		return NULL;
 
 
 	v4l2_dev = &qcam->v4l2_dev;
 	v4l2_dev = &qcam->v4l2_dev;
-	snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams);
+	snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%u", num_cams);
 
 
 	if (v4l2_device_register(port->dev, v4l2_dev) < 0) {
 	if (v4l2_device_register(port->dev, v4l2_dev) < 0) {
 		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
 		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");

+ 110 - 0
drivers/media/pci/bt8xx/bttv-cards.c

@@ -52,6 +52,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 ee[256]);
 static void modtec_eeprom(struct bttv *btv);
 static void modtec_eeprom(struct bttv *btv);
 static void init_PXC200(struct bttv *btv);
 static void init_PXC200(struct bttv *btv);
 static void init_RTV24(struct bttv *btv);
 static void init_RTV24(struct bttv *btv);
+static void init_PCI8604PW(struct bttv *btv);
 
 
 static void rv605_muxsel(struct bttv *btv, unsigned int input);
 static void rv605_muxsel(struct bttv *btv, unsigned int input);
 static void eagle_muxsel(struct bttv *btv, unsigned int input);
 static void eagle_muxsel(struct bttv *btv, unsigned int input);
@@ -2871,6 +2872,22 @@ struct tvcard bttv_tvcards[] = {
 		.has_remote     = 1,
 		.has_remote     = 1,
 		.has_radio      = 1,
 		.has_radio      = 1,
 	},
 	},
+	/* ---- card 0xa6---------------------------------- */
+	[BTTV_BOARD_PCI_8604PW] = {
+		/* PCI-8604PW with special unlock sequence */
+		.name           = "PCI-8604PW",
+		.video_inputs   = 2,
+		/* .audio_inputs= 0, */
+		.svhs           = NO_SVHS,
+		/* The second input is available on CN4, if populated.
+		 * The other 5x2 header (CN2?) connects to the same inputs
+		 * as the on-board BNCs */
+		.muxsel         = MUXSEL(2, 3),
+		.tuner_type     = TUNER_ABSENT,
+		.no_msp34xx	= 1,
+		.no_tda7432	= 1,
+		.pll            = PLL_35,
+	},
 };
 };
 
 
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3305,6 +3322,9 @@ void bttv_init_card1(struct bttv *btv)
 	case BTTV_BOARD_ADLINK_RTV24:
 	case BTTV_BOARD_ADLINK_RTV24:
 		init_RTV24( btv );
 		init_RTV24( btv );
 		break;
 		break;
+	case BTTV_BOARD_PCI_8604PW:
+		init_PCI8604PW(btv);
+		break;
 
 
 	}
 	}
 	if (!bttv_tvcards[btv->c.type].has_dvb)
 	if (!bttv_tvcards[btv->c.type].has_dvb)
@@ -4184,6 +4204,96 @@ init_RTV24 (struct bttv *btv)
 
 
 
 
 
 
+/* ----------------------------------------------------------------------- */
+/*
+ *  The PCI-8604PW contains a CPLD, probably an ispMACH 4A, that filters
+ *  the PCI REQ signals comming from the four BT878 chips. After power
+ *  up, the CPLD does not forward requests to the bus, which prevents
+ *  the BT878 from fetching RISC instructions from memory. While the
+ *  CPLD is connected to most of the GPIOs of PCI device 0xD, only
+ *  five appear to play a role in unlocking the REQ signal. The following
+ *  sequence has been determined by trial and error without access to the
+ *  original driver.
+ *
+ *  Eight GPIOs of device 0xC are provided on connector CN4 (4 in, 4 out).
+ *  Devices 0xE and 0xF do not appear to have anything connected to their
+ *  GPIOs.
+ *
+ *  The correct GPIO_OUT_EN value might have some more bits set. It should
+ *  be possible to derive it from a boundary scan of the CPLD. Its JTAG
+ *  pins are routed to test points.
+ *
+ */
+/* ----------------------------------------------------------------------- */
+static void
+init_PCI8604PW(struct bttv *btv)
+{
+	int state;
+
+	if ((PCI_SLOT(btv->c.pci->devfn) & ~3) != 0xC) {
+		pr_warn("This is not a PCI-8604PW\n");
+		return;
+	}
+
+	if (PCI_SLOT(btv->c.pci->devfn) != 0xD)
+		return;
+
+	btwrite(0x080002, BT848_GPIO_OUT_EN);
+
+	state = (btread(BT848_GPIO_DATA) >> 21) & 7;
+
+	for (;;) {
+		switch (state) {
+		case 1:
+		case 5:
+		case 6:
+		case 4:
+			pr_debug("PCI-8604PW in state %i, toggling pin\n",
+				 state);
+			btwrite(0x080000, BT848_GPIO_DATA);
+			msleep(1);
+			btwrite(0x000000, BT848_GPIO_DATA);
+			msleep(1);
+			break;
+		case 7:
+			pr_info("PCI-8604PW unlocked\n");
+			return;
+		case 0:
+			/* FIXME: If we are in state 7 and toggle GPIO[19] one
+			   more time, the CPLD goes into state 0, where PCI bus
+			   mastering is inhibited again. We have not managed to
+			   get out of that state. */
+
+			pr_err("PCI-8604PW locked until reset\n");
+			return;
+		default:
+			pr_err("PCI-8604PW in unknown state %i\n", state);
+			return;
+		}
+
+		state = (state << 4) | ((btread(BT848_GPIO_DATA) >> 21) & 7);
+
+		switch (state) {
+		case 0x15:
+		case 0x56:
+		case 0x64:
+		case 0x47:
+		/* The transition from state 7 to state 0 is, as explained
+		   above, valid but undesired and with this code impossible
+		   as we exit as soon as we are in state 7.
+		case 0x70: */
+			break;
+		default:
+			pr_err("PCI-8604PW invalid transition %i -> %i\n",
+			       state >> 4, state & 7);
+			return;
+		}
+		state &= 7;
+	}
+}
+
+
+
 /* ----------------------------------------------------------------------- */
 /* ----------------------------------------------------------------------- */
 /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports     */
 /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports     */
 /*
 /*

+ 1 - 1
drivers/media/pci/bt8xx/bttv-driver.c

@@ -1182,7 +1182,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
 		break;
 		break;
 	}
 	}
 	id = tvnorm->v4l2_id;
 	id = tvnorm->v4l2_id;
-	bttv_call_all(btv, core, s_std, id);
+	bttv_call_all(btv, video, s_std, id);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 0
drivers/media/pci/bt8xx/bttv.h

@@ -189,6 +189,7 @@
 #define BTTV_BOARD_BT848_CAP_14            0xa3
 #define BTTV_BOARD_BT848_CAP_14            0xa3
 #define BTTV_BOARD_CYBERVISION_CV06        0xa4
 #define BTTV_BOARD_CYBERVISION_CV06        0xa4
 #define BTTV_BOARD_KWORLD_VSTREAM_XPERT    0xa5
 #define BTTV_BOARD_KWORLD_VSTREAM_XPERT    0xa5
+#define BTTV_BOARD_PCI_8604PW              0xa6
 
 
 /* more card-specific defines */
 /* more card-specific defines */
 #define PT2254_L_CHANNEL 0x10
 #define PT2254_L_CHANNEL 0x10

+ 10 - 10
drivers/media/pci/bt8xx/dst.c

@@ -1544,7 +1544,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
 }
 }
 
 
 
 
-static int dst_init(struct dvb_frontend *fe)
+static int bt8xx_dst_init(struct dvb_frontend *fe)
 {
 {
 	struct dst_state *state = fe->demodulator_priv;
 	struct dst_state *state = fe->demodulator_priv;
 
 
@@ -1707,7 +1707,7 @@ static int dst_get_frontend(struct dvb_frontend *fe)
 	return 0;
 	return 0;
 }
 }
 
 
-static void dst_release(struct dvb_frontend *fe)
+static void bt8xx_dst_release(struct dvb_frontend *fe)
 {
 {
 	struct dst_state *state = fe->demodulator_priv;
 	struct dst_state *state = fe->demodulator_priv;
 	if (state->dst_ca) {
 	if (state->dst_ca) {
@@ -1776,8 +1776,8 @@ static struct dvb_frontend_ops dst_dvbt_ops = {
 			FE_CAN_GUARD_INTERVAL_AUTO
 			FE_CAN_GUARD_INTERVAL_AUTO
 	},
 	},
 
 
-	.release = dst_release,
-	.init = dst_init,
+	.release = bt8xx_dst_release,
+	.init = bt8xx_dst_init,
 	.tune = dst_tune_frontend,
 	.tune = dst_tune_frontend,
 	.set_frontend = dst_set_frontend,
 	.set_frontend = dst_set_frontend,
 	.get_frontend = dst_get_frontend,
 	.get_frontend = dst_get_frontend,
@@ -1801,8 +1801,8 @@ static struct dvb_frontend_ops dst_dvbs_ops = {
 		.caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
 		.caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
 	},
 	},
 
 
-	.release = dst_release,
-	.init = dst_init,
+	.release = bt8xx_dst_release,
+	.init = bt8xx_dst_init,
 	.tune = dst_tune_frontend,
 	.tune = dst_tune_frontend,
 	.set_frontend = dst_set_frontend,
 	.set_frontend = dst_set_frontend,
 	.get_frontend = dst_get_frontend,
 	.get_frontend = dst_get_frontend,
@@ -1834,8 +1834,8 @@ static struct dvb_frontend_ops dst_dvbc_ops = {
 			FE_CAN_QAM_256
 			FE_CAN_QAM_256
 	},
 	},
 
 
-	.release = dst_release,
-	.init = dst_init,
+	.release = bt8xx_dst_release,
+	.init = bt8xx_dst_init,
 	.tune = dst_tune_frontend,
 	.tune = dst_tune_frontend,
 	.set_frontend = dst_set_frontend,
 	.set_frontend = dst_set_frontend,
 	.get_frontend = dst_get_frontend,
 	.get_frontend = dst_get_frontend,
@@ -1857,8 +1857,8 @@ static struct dvb_frontend_ops dst_atsc_ops = {
 		.caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
 		.caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
 	},
 	},
 
 
-	.release = dst_release,
-	.init = dst_init,
+	.release = bt8xx_dst_release,
+	.init = bt8xx_dst_init,
 	.tune = dst_tune_frontend,
 	.tune = dst_tune_frontend,
 	.set_frontend = dst_set_frontend,
 	.set_frontend = dst_set_frontend,
 	.get_frontend = dst_get_frontend,
 	.get_frontend = dst_get_frontend,

+ 1 - 1
drivers/media/pci/cx18/cx18-av-core.c

@@ -1263,7 +1263,6 @@ static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
 	.log_status = cx18_av_log_status,
 	.log_status = cx18_av_log_status,
 	.load_fw = cx18_av_load_fw,
 	.load_fw = cx18_av_load_fw,
 	.reset = cx18_av_reset,
 	.reset = cx18_av_reset,
-	.s_std = cx18_av_s_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = cx18_av_g_register,
 	.g_register = cx18_av_g_register,
 	.s_register = cx18_av_s_register,
 	.s_register = cx18_av_s_register,
@@ -1283,6 +1282,7 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
 };
 };
 
 
 static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
 static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
+	.s_std = cx18_av_s_std,
 	.s_routing = cx18_av_s_video_routing,
 	.s_routing = cx18_av_s_video_routing,
 	.s_stream = cx18_av_s_stream,
 	.s_stream = cx18_av_s_stream,
 	.s_mbus_fmt = cx18_av_s_mbus_fmt,
 	.s_mbus_fmt = cx18_av_s_mbus_fmt,

+ 1 - 1
drivers/media/pci/cx18/cx18-fileops.c

@@ -760,7 +760,7 @@ int cx18_v4l2_close(struct file *filp)
 		/* Mark that the radio is no longer in use */
 		/* Mark that the radio is no longer in use */
 		clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 		clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 		/* Switch tuner to TV */
 		/* Switch tuner to TV */
-		cx18_call_all(cx, core, s_std, cx->std);
+		cx18_call_all(cx, video, s_std, cx->std);
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		cx18_audio_set_io(cx);
 		cx18_audio_set_io(cx);
 		if (atomic_read(&cx->ana_capturing) > 0) {
 		if (atomic_read(&cx->ana_capturing) > 0) {

+ 5 - 1
drivers/media/pci/cx18/cx18-gpio.c

@@ -180,7 +180,6 @@ static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
 
 
 static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
 static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
 	.log_status = gpiomux_log_status,
 	.log_status = gpiomux_log_status,
-	.s_std = gpiomux_s_std,
 };
 };
 
 
 static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
 static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
@@ -191,10 +190,15 @@ static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
 	.s_routing = gpiomux_s_audio_routing,
 	.s_routing = gpiomux_s_audio_routing,
 };
 };
 
 
+static const struct v4l2_subdev_video_ops gpiomux_video_ops = {
+	.s_std = gpiomux_s_std,
+};
+
 static const struct v4l2_subdev_ops gpiomux_ops = {
 static const struct v4l2_subdev_ops gpiomux_ops = {
 	.core = &gpiomux_core_ops,
 	.core = &gpiomux_core_ops,
 	.tuner = &gpiomux_tuner_ops,
 	.tuner = &gpiomux_tuner_ops,
 	.audio = &gpiomux_audio_ops,
 	.audio = &gpiomux_audio_ops,
+	.video = &gpiomux_video_ops,
 };
 };
 
 
 /*
 /*

+ 1 - 1
drivers/media/pci/cx18/cx18-ioctl.c

@@ -602,7 +602,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
 			(unsigned long long) cx->std);
 			(unsigned long long) cx->std);
 
 
 	/* Tuner */
 	/* Tuner */
-	cx18_call_all(cx, core, s_std, cx->std);
+	cx18_call_all(cx, video, s_std, cx->std);
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 2
drivers/media/pci/cx23885/cx23885-video.c

@@ -326,7 +326,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
 
 
 	dev->tvnorm = norm;
 	dev->tvnorm = norm;
 
 
-	call_all(dev, core, s_std, norm);
+	call_all(dev, video, s_std, norm);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1589,7 +1589,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev,
 		fe = &dev->ts1.analog_fe;
 		fe = &dev->ts1.analog_fe;
 
 
 	if (fe && fe->ops.tuner_ops.set_analog_params) {
 	if (fe && fe->ops.tuner_ops.set_analog_params) {
-		call_all(dev, core, s_std, dev->tvnorm);
+		call_all(dev, video, s_std, dev->tvnorm);
 		fe->ops.tuner_ops.set_analog_params(fe, &params);
 		fe->ops.tuner_ops.set_analog_params(fe, &params);
 	}
 	}
 	else
 	else

+ 1 - 1
drivers/media/pci/cx88/cx88-core.c

@@ -1012,7 +1012,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
 	set_tvaudio(core);
 	set_tvaudio(core);
 
 
 	// tell i2c chips
 	// tell i2c chips
-	call_all(core, core, s_std, norm);
+	call_all(core, video, s_std, norm);
 
 
 	/* The chroma_agc control should be inaccessible if the video format is SECAM */
 	/* The chroma_agc control should be inaccessible if the video format is SECAM */
 	v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);
 	v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);

+ 6 - 0
drivers/media/pci/ivtv/ivtv-alsa-pcm.c

@@ -159,6 +159,12 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)
 
 
 	/* Instruct the CX2341[56] to start sending packets */
 	/* Instruct the CX2341[56] to start sending packets */
 	snd_ivtv_lock(itvsc);
 	snd_ivtv_lock(itvsc);
+
+	if (ivtv_init_on_first_open(itv)) {
+		snd_ivtv_unlock(itvsc);
+		return -ENXIO;
+	}
+
 	s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
 	s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
 
 
 	v4l2_fh_init(&item.fh, s->vdev);
 	v4l2_fh_init(&item.fh, s->vdev);

+ 1 - 1
drivers/media/pci/ivtv/ivtv-fileops.c

@@ -894,7 +894,7 @@ int ivtv_v4l2_close(struct file *filp)
 		/* Mark that the radio is no longer in use */
 		/* Mark that the radio is no longer in use */
 		clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
 		clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
 		/* Switch tuner to TV */
 		/* Switch tuner to TV */
-		ivtv_call_all(itv, core, s_std, itv->std);
+		ivtv_call_all(itv, video, s_std, itv->std);
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		/* Select correct audio input (i.e. TV tuner or Line in) */
 		ivtv_audio_set_io(itv);
 		ivtv_audio_set_io(itv);
 		if (itv->hw_flags & IVTV_HW_SAA711X) {
 		if (itv->hw_flags & IVTV_HW_SAA711X) {

+ 1 - 1
drivers/media/pci/ivtv/ivtv-ioctl.c

@@ -1090,7 +1090,7 @@ void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std)
 		itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
 		itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
 
 
 	/* Tuner */
 	/* Tuner */
-	ivtv_call_all(itv, core, s_std, itv->std);
+	ivtv_call_all(itv, video, s_std, itv->std);
 }
 }
 
 
 void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)
 void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std)

+ 2 - 2
drivers/media/pci/saa7134/Kconfig

@@ -1,7 +1,7 @@
 config VIDEO_SAA7134
 config VIDEO_SAA7134
 	tristate "Philips SAA7134 support"
 	tristate "Philips SAA7134 support"
 	depends on VIDEO_DEV && PCI && I2C
 	depends on VIDEO_DEV && PCI && I2C
-	select VIDEOBUF_DMA_SG
+	select VIDEOBUF2_DMA_SG
 	select VIDEO_TUNER
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select CRC32
 	select CRC32
@@ -37,7 +37,7 @@ config VIDEO_SAA7134_RC
 config VIDEO_SAA7134_DVB
 config VIDEO_SAA7134_DVB
 	tristate "DVB/ATSC Support for saa7134 based TV cards"
 	tristate "DVB/ATSC Support for saa7134 based TV cards"
 	depends on VIDEO_SAA7134 && DVB_CORE
 	depends on VIDEO_SAA7134 && DVB_CORE
-	select VIDEOBUF_DVB
+	select VIDEOBUF2_DVB
 	select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT

+ 92 - 15
drivers/media/pci/saa7134/saa7134-alsa.c

@@ -27,6 +27,7 @@
 #include <sound/pcm_params.h>
 #include <sound/pcm_params.h>
 #include <sound/initval.h>
 #include <sound/initval.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
+#include <linux/vmalloc.h>
 
 
 #include "saa7134.h"
 #include "saa7134.h"
 #include "saa7134-reg.h"
 #include "saa7134-reg.h"
@@ -274,6 +275,82 @@ static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream
 	return err;
 	return err;
 }
 }
 
 
+static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages)
+{
+	struct saa7134_dmasound *dma = &dev->dmasound;
+	struct page *pg;
+	int i;
+
+	dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
+	if (NULL == dma->vaddr) {
+		dprintk("vmalloc_32(%d pages) failed\n", nr_pages);
+		return -ENOMEM;
+	}
+
+	dprintk("vmalloc is at addr 0x%08lx, size=%d\n",
+				(unsigned long)dma->vaddr,
+				nr_pages << PAGE_SHIFT);
+
+	memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT);
+	dma->nr_pages = nr_pages;
+
+	dma->sglist = vzalloc(dma->nr_pages * sizeof(*dma->sglist));
+	if (NULL == dma->sglist)
+		goto vzalloc_err;
+
+	sg_init_table(dma->sglist, dma->nr_pages);
+	for (i = 0; i < dma->nr_pages; i++) {
+		pg = vmalloc_to_page(dma->vaddr + i * PAGE_SIZE);
+		if (NULL == pg)
+			goto vmalloc_to_page_err;
+		sg_set_page(&dma->sglist[i], pg, PAGE_SIZE, 0);
+	}
+	return 0;
+
+vmalloc_to_page_err:
+	vfree(dma->sglist);
+	dma->sglist = NULL;
+vzalloc_err:
+	vfree(dma->vaddr);
+	dma->vaddr = NULL;
+	return -ENOMEM;
+}
+
+static int saa7134_alsa_dma_map(struct saa7134_dev *dev)
+{
+	struct saa7134_dmasound *dma = &dev->dmasound;
+
+	dma->sglen = dma_map_sg(&dev->pci->dev, dma->sglist,
+			dma->nr_pages, PCI_DMA_FROMDEVICE);
+
+	if (0 == dma->sglen) {
+		pr_warn("%s: saa7134_alsa_map_sg failed\n", __func__);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int saa7134_alsa_dma_unmap(struct saa7134_dev *dev)
+{
+	struct saa7134_dmasound *dma = &dev->dmasound;
+
+	if (!dma->sglen)
+		return 0;
+
+	dma_unmap_sg(&dev->pci->dev, dma->sglist, dma->sglen, PCI_DMA_FROMDEVICE);
+	dma->sglen = 0;
+	return 0;
+}
+
+static int saa7134_alsa_dma_free(struct saa7134_dmasound *dma)
+{
+	vfree(dma->sglist);
+	dma->sglist = NULL;
+	vfree(dma->vaddr);
+	dma->vaddr = NULL;
+	return 0;
+}
+
 /*
 /*
  * DMA buffer initialization
  * DMA buffer initialization
  *
  *
@@ -291,9 +368,8 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
 
 
 	BUG_ON(!dev->dmasound.bufsize);
 	BUG_ON(!dev->dmasound.bufsize);
 
 
-	videobuf_dma_init(&dev->dmasound.dma);
-	err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
-				       (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
+	err = saa7134_alsa_dma_init(dev,
+			       (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
 	if (0 != err)
 	if (0 != err)
 		return err;
 		return err;
 	return 0;
 	return 0;
@@ -310,7 +386,7 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
 {
 {
 	BUG_ON(!dev->dmasound.blksize);
 	BUG_ON(!dev->dmasound.blksize);
 
 
-	videobuf_dma_free(&dev->dmasound.dma);
+	saa7134_alsa_dma_free(&dev->dmasound);
 
 
 	dev->dmasound.blocks  = 0;
 	dev->dmasound.blocks  = 0;
 	dev->dmasound.blksize = 0;
 	dev->dmasound.blksize = 0;
@@ -632,7 +708,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
 	/* release the old buffer */
 	/* release the old buffer */
 	if (substream->runtime->dma_area) {
 	if (substream->runtime->dma_area) {
 		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
 		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
-		videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+		saa7134_alsa_dma_unmap(dev);
 		dsp_buffer_free(dev);
 		dsp_buffer_free(dev);
 		substream->runtime->dma_area = NULL;
 		substream->runtime->dma_area = NULL;
 	}
 	}
@@ -648,21 +724,22 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
 		return err;
 		return err;
 	}
 	}
 
 
-	if (0 != (err = videobuf_dma_map(&dev->pci->dev, &dev->dmasound.dma))) {
+	err = saa7134_alsa_dma_map(dev);
+	if (err) {
 		dsp_buffer_free(dev);
 		dsp_buffer_free(dev);
 		return err;
 		return err;
 	}
 	}
-	if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
-		videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+	err = saa7134_pgtable_alloc(dev->pci, &dev->dmasound.pt);
+	if (err) {
+		saa7134_alsa_dma_unmap(dev);
 		dsp_buffer_free(dev);
 		dsp_buffer_free(dev);
 		return err;
 		return err;
 	}
 	}
-	if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
-						dev->dmasound.dma.sglist,
-						dev->dmasound.dma.sglen,
-						0))) {
+	err = saa7134_pgtable_build(dev->pci, &dev->dmasound.pt,
+				dev->dmasound.sglist, dev->dmasound.sglen, 0);
+	if (err) {
 		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
 		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
-		videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+		saa7134_alsa_dma_unmap(dev);
 		dsp_buffer_free(dev);
 		dsp_buffer_free(dev);
 		return err;
 		return err;
 	}
 	}
@@ -671,7 +748,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
 	   byte, but it doesn't work. So I allocate the DMA using the
 	   byte, but it doesn't work. So I allocate the DMA using the
 	   V4L functions, and force ALSA to use that as the DMA area */
 	   V4L functions, and force ALSA to use that as the DMA area */
 
 
-	substream->runtime->dma_area = dev->dmasound.dma.vaddr;
+	substream->runtime->dma_area = dev->dmasound.vaddr;
 	substream->runtime->dma_bytes = dev->dmasound.bufsize;
 	substream->runtime->dma_bytes = dev->dmasound.bufsize;
 	substream->runtime->dma_addr = 0;
 	substream->runtime->dma_addr = 0;
 
 
@@ -698,7 +775,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
 
 
 	if (substream->runtime->dma_area) {
 	if (substream->runtime->dma_area) {
 		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
 		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
-		videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+		saa7134_alsa_dma_unmap(dev);
 		dsp_buffer_free(dev);
 		dsp_buffer_free(dev);
 		substream->runtime->dma_area = NULL;
 		substream->runtime->dma_area = NULL;
 	}
 	}

+ 67 - 63
drivers/media/pci/saa7134/saa7134-core.c

@@ -69,6 +69,10 @@ module_param_named(no_overlay, saa7134_no_overlay, int, 0444);
 MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
 MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
 		" [some VIA/SIS chipsets are known to have problem with overlay]");
 		" [some VIA/SIS chipsets are known to have problem with overlay]");
 
 
+bool saa7134_userptr;
+module_param(saa7134_userptr, bool, 0644);
+MODULE_PARM_DESC(saa7134_userptr, "enable page-aligned userptr support");
+
 static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int vbi_nr[]   = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int vbi_nr[]   = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
@@ -203,16 +207,16 @@ int saa7134_buffer_count(unsigned int size, unsigned int count)
 
 
 int saa7134_buffer_startpage(struct saa7134_buf *buf)
 int saa7134_buffer_startpage(struct saa7134_buf *buf)
 {
 {
-	return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i;
+	return saa7134_buffer_pages(vb2_plane_size(&buf->vb2, 0)) * buf->vb2.v4l2_buf.index;
 }
 }
 
 
 unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
 unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
 {
 {
 	unsigned long base;
 	unsigned long base;
-	struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
 
 
 	base  = saa7134_buffer_startpage(buf) * 4096;
 	base  = saa7134_buffer_startpage(buf) * 4096;
-	base += dma->sglist[0].offset;
+	base += dma->sgl[0].offset;
 	return base;
 	return base;
 }
 }
 
 
@@ -237,14 +241,16 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
 			  unsigned int startpage)
 			  unsigned int startpage)
 {
 {
 	__le32        *ptr;
 	__le32        *ptr;
-	unsigned int  i,p;
+	unsigned int  i, p;
 
 
 	BUG_ON(NULL == pt || NULL == pt->cpu);
 	BUG_ON(NULL == pt || NULL == pt->cpu);
 
 
 	ptr = pt->cpu + startpage;
 	ptr = pt->cpu + startpage;
-	for (i = 0; i < length; i++, list++)
+	for (i = 0; i < length; i++, list = sg_next(list)) {
 		for (p = 0; p * 4096 < list->length; p++, ptr++)
 		for (p = 0; p * 4096 < list->length; p++, ptr++)
-			*ptr = cpu_to_le32(sg_dma_address(list) - list->offset);
+			*ptr = cpu_to_le32(sg_dma_address(list) +
+						list->offset + p * 4096);
+	}
 	return 0;
 	return 0;
 }
 }
 
 
@@ -258,44 +264,31 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
 
 
-void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf)
-{
-	struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-	BUG_ON(in_interrupt());
-
-	videobuf_waiton(q, &buf->vb, 0, 0);
-	videobuf_dma_unmap(q->dev, dma);
-	videobuf_dma_free(dma);
-	buf->vb.state = VIDEOBUF_NEEDS_INIT;
-}
-
-/* ------------------------------------------------------------------ */
-
 int saa7134_buffer_queue(struct saa7134_dev *dev,
 int saa7134_buffer_queue(struct saa7134_dev *dev,
 			 struct saa7134_dmaqueue *q,
 			 struct saa7134_dmaqueue *q,
 			 struct saa7134_buf *buf)
 			 struct saa7134_buf *buf)
 {
 {
 	struct saa7134_buf *next = NULL;
 	struct saa7134_buf *next = NULL;
+	unsigned long flags;
 
 
-	assert_spin_locked(&dev->slock);
-	dprintk("buffer_queue %p\n",buf);
+	spin_lock_irqsave(&dev->slock, flags);
+	dprintk("buffer_queue %p\n", buf);
 	if (NULL == q->curr) {
 	if (NULL == q->curr) {
 		if (!q->need_two) {
 		if (!q->need_two) {
 			q->curr = buf;
 			q->curr = buf;
-			buf->activate(dev,buf,NULL);
+			buf->activate(dev, buf, NULL);
 		} else if (list_empty(&q->queue)) {
 		} else if (list_empty(&q->queue)) {
-			list_add_tail(&buf->vb.queue,&q->queue);
-			buf->vb.state = VIDEOBUF_QUEUED;
+			list_add_tail(&buf->entry, &q->queue);
 		} else {
 		} else {
-			next = list_entry(q->queue.next,struct saa7134_buf,
-					  vb.queue);
+			next = list_entry(q->queue.next, struct saa7134_buf,
+					  entry);
 			q->curr = buf;
 			q->curr = buf;
-			buf->activate(dev,buf,next);
+			buf->activate(dev, buf, next);
 		}
 		}
 	} else {
 	} else {
-		list_add_tail(&buf->vb.queue,&q->queue);
-		buf->vb.state = VIDEOBUF_QUEUED;
+		list_add_tail(&buf->entry, &q->queue);
 	}
 	}
+	spin_unlock_irqrestore(&dev->slock, flags);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -303,13 +296,12 @@ void saa7134_buffer_finish(struct saa7134_dev *dev,
 			   struct saa7134_dmaqueue *q,
 			   struct saa7134_dmaqueue *q,
 			   unsigned int state)
 			   unsigned int state)
 {
 {
-	assert_spin_locked(&dev->slock);
-	dprintk("buffer_finish %p\n",q->curr);
+	dprintk("buffer_finish %p\n", q->curr);
 
 
 	/* finish current buffer */
 	/* finish current buffer */
-	q->curr->vb.state = state;
-	v4l2_get_timestamp(&q->curr->vb.ts);
-	wake_up(&q->curr->vb.done);
+	v4l2_get_timestamp(&q->curr->vb2.v4l2_buf.timestamp);
+	q->curr->vb2.v4l2_buf.sequence = q->seq_nr++;
+	vb2_buffer_done(&q->curr->vb2, state);
 	q->curr = NULL;
 	q->curr = NULL;
 }
 }
 
 
@@ -323,36 +315,31 @@ void saa7134_buffer_next(struct saa7134_dev *dev,
 
 
 	if (!list_empty(&q->queue)) {
 	if (!list_empty(&q->queue)) {
 		/* activate next one from queue */
 		/* activate next one from queue */
-		buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue);
+		buf = list_entry(q->queue.next, struct saa7134_buf, entry);
 		dprintk("buffer_next %p [prev=%p/next=%p]\n",
 		dprintk("buffer_next %p [prev=%p/next=%p]\n",
-			buf,q->queue.prev,q->queue.next);
-		list_del(&buf->vb.queue);
+			buf, q->queue.prev, q->queue.next);
+		list_del(&buf->entry);
 		if (!list_empty(&q->queue))
 		if (!list_empty(&q->queue))
-			next = list_entry(q->queue.next,struct saa7134_buf,
-					  vb.queue);
+			next = list_entry(q->queue.next, struct saa7134_buf, entry);
 		q->curr = buf;
 		q->curr = buf;
-		buf->activate(dev,buf,next);
+		buf->activate(dev, buf, next);
 		dprintk("buffer_next #2 prev=%p/next=%p\n",
 		dprintk("buffer_next #2 prev=%p/next=%p\n",
-			q->queue.prev,q->queue.next);
+			q->queue.prev, q->queue.next);
 	} else {
 	} else {
 		/* nothing to do -- just stop DMA */
 		/* nothing to do -- just stop DMA */
-		dprintk("buffer_next %p\n",NULL);
+		dprintk("buffer_next %p\n", NULL);
 		saa7134_set_dmabits(dev);
 		saa7134_set_dmabits(dev);
 		del_timer(&q->timeout);
 		del_timer(&q->timeout);
-
-		if (card_has_mpeg(dev))
-			if (dev->ts_started)
-				saa7134_ts_stop(dev);
 	}
 	}
 }
 }
 
 
 void saa7134_buffer_timeout(unsigned long data)
 void saa7134_buffer_timeout(unsigned long data)
 {
 {
-	struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;
+	struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue *)data;
 	struct saa7134_dev *dev = q->dev;
 	struct saa7134_dev *dev = q->dev;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	spin_lock_irqsave(&dev->slock,flags);
+	spin_lock_irqsave(&dev->slock, flags);
 
 
 	/* try to reset the hardware (SWRST) */
 	/* try to reset the hardware (SWRST) */
 	saa_writeb(SAA7134_REGION_ENABLE, 0x00);
 	saa_writeb(SAA7134_REGION_ENABLE, 0x00);
@@ -362,13 +349,33 @@ void saa7134_buffer_timeout(unsigned long data)
 	/* flag current buffer as failed,
 	/* flag current buffer as failed,
 	   try to start over with the next one. */
 	   try to start over with the next one. */
 	if (q->curr) {
 	if (q->curr) {
-		dprintk("timeout on %p\n",q->curr);
-		saa7134_buffer_finish(dev,q,VIDEOBUF_ERROR);
+		dprintk("timeout on %p\n", q->curr);
+		saa7134_buffer_finish(dev, q, VB2_BUF_STATE_ERROR);
 	}
 	}
-	saa7134_buffer_next(dev,q);
-	spin_unlock_irqrestore(&dev->slock,flags);
+	saa7134_buffer_next(dev, q);
+	spin_unlock_irqrestore(&dev->slock, flags);
 }
 }
 
 
+void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q)
+{
+	unsigned long flags;
+	struct list_head *pos, *n;
+	struct saa7134_buf *tmp;
+
+	spin_lock_irqsave(&dev->slock, flags);
+	if (!list_empty(&q->queue)) {
+		list_for_each_safe(pos, n, &q->queue) {
+			 tmp = list_entry(pos, struct saa7134_buf, entry);
+			 vb2_buffer_done(&tmp->vb2, VB2_BUF_STATE_ERROR);
+			 list_del(pos);
+			 tmp = NULL;
+		}
+	}
+	spin_unlock_irqrestore(&dev->slock, flags);
+	saa7134_buffer_timeout((unsigned long)q); /* also calls del_timer(&q->timeout) */
+}
+EXPORT_SYMBOL_GPL(saa7134_stop_streaming);
+
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
 
 
 int saa7134_set_dmabits(struct saa7134_dev *dev)
 int saa7134_set_dmabits(struct saa7134_dev *dev)
@@ -388,12 +395,11 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
 		ctrl |= SAA7134_MAIN_CTRL_TE0;
 		ctrl |= SAA7134_MAIN_CTRL_TE0;
 		irq  |= SAA7134_IRQ1_INTE_RA0_1 |
 		irq  |= SAA7134_IRQ1_INTE_RA0_1 |
 			SAA7134_IRQ1_INTE_RA0_0;
 			SAA7134_IRQ1_INTE_RA0_0;
-		cap = dev->video_q.curr->vb.field;
+		cap = dev->field;
 	}
 	}
 
 
 	/* video capture -- dma 1+2 (planar modes) */
 	/* video capture -- dma 1+2 (planar modes) */
-	if (dev->video_q.curr &&
-	    dev->video_q.curr->fmt->planar) {
+	if (dev->video_q.curr && dev->fmt->planar) {
 		ctrl |= SAA7134_MAIN_CTRL_TE4 |
 		ctrl |= SAA7134_MAIN_CTRL_TE4 |
 			SAA7134_MAIN_CTRL_TE5;
 			SAA7134_MAIN_CTRL_TE5;
 	}
 	}
@@ -1047,6 +1053,8 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
 
 
 	dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
 	dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
 	dev->video_dev->ctrl_handler = &dev->ctrl_handler;
 	dev->video_dev->ctrl_handler = &dev->ctrl_handler;
+	dev->video_dev->lock = &dev->lock;
+	dev->video_dev->queue = &dev->video_vbq;
 	err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
 	err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
 				    video_nr[dev->nr]);
 				    video_nr[dev->nr]);
 	if (err < 0) {
 	if (err < 0) {
@@ -1059,6 +1067,8 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
 
 
 	dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
 	dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi");
 	dev->vbi_dev->ctrl_handler = &dev->ctrl_handler;
 	dev->vbi_dev->ctrl_handler = &dev->ctrl_handler;
+	dev->vbi_dev->lock = &dev->lock;
+	dev->vbi_dev->queue = &dev->vbi_vbq;
 
 
 	err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
 	err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
 				    vbi_nr[dev->nr]);
 				    vbi_nr[dev->nr]);
@@ -1070,6 +1080,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
 	if (card_has_radio(dev)) {
 	if (card_has_radio(dev)) {
 		dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
 		dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
 		dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler;
 		dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler;
+		dev->radio_dev->lock = &dev->lock;
 		err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
 		err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
 					    radio_nr[dev->nr]);
 					    radio_nr[dev->nr]);
 		if (err < 0)
 		if (err < 0)
@@ -1189,7 +1200,7 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev,
 
 
 	if (!list_empty(&q->queue))
 	if (!list_empty(&q->queue))
 		next = list_entry(q->queue.next, struct saa7134_buf,
 		next = list_entry(q->queue.next, struct saa7134_buf,
-					  vb.queue);
+					  entry);
 	buf->activate(dev, buf, next);
 	buf->activate(dev, buf, next);
 
 
 	return 0;
 	return 0;
@@ -1360,10 +1371,3 @@ EXPORT_SYMBOL(saa7134_pgtable_free);
 EXPORT_SYMBOL(saa7134_pgtable_build);
 EXPORT_SYMBOL(saa7134_pgtable_build);
 EXPORT_SYMBOL(saa7134_pgtable_alloc);
 EXPORT_SYMBOL(saa7134_pgtable_alloc);
 EXPORT_SYMBOL(saa7134_set_dmabits);
 EXPORT_SYMBOL(saa7134_set_dmabits);
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */

+ 27 - 23
drivers/media/pci/saa7134/saa7134-dvb.c

@@ -602,10 +602,10 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,
 				struct tda1004x_config *cdec_conf,
 				struct tda1004x_config *cdec_conf,
 				struct tda827x_config *tuner_conf)
 				struct tda827x_config *tuner_conf)
 {
 {
-	struct videobuf_dvb_frontend *fe0;
+	struct vb2_dvb_frontend *fe0;
 
 
 	/* Get the first frontend */
 	/* Get the first frontend */
-	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+	fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);
 
 
 	if (!fe0)
 	if (!fe0)
 		return -EINVAL;
 		return -EINVAL;
@@ -1215,29 +1215,38 @@ static int dvb_init(struct saa7134_dev *dev)
 {
 {
 	int ret;
 	int ret;
 	int attach_xc3028 = 0;
 	int attach_xc3028 = 0;
-	struct videobuf_dvb_frontend *fe0;
+	struct vb2_dvb_frontend *fe0;
+	struct vb2_queue *q;
 
 
 	/* FIXME: add support for multi-frontend */
 	/* FIXME: add support for multi-frontend */
 	mutex_init(&dev->frontends.lock);
 	mutex_init(&dev->frontends.lock);
 	INIT_LIST_HEAD(&dev->frontends.felist);
 	INIT_LIST_HEAD(&dev->frontends.felist);
 
 
 	printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
 	printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
-	fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, 1);
+	fe0 = vb2_dvb_alloc_frontend(&dev->frontends, 1);
 	if (!fe0) {
 	if (!fe0) {
 		printk(KERN_ERR "%s() failed to alloc\n", __func__);
 		printk(KERN_ERR "%s() failed to alloc\n", __func__);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	/* init struct videobuf_dvb */
+	/* init struct vb2_dvb */
 	dev->ts.nr_bufs    = 32;
 	dev->ts.nr_bufs    = 32;
 	dev->ts.nr_packets = 32*4;
 	dev->ts.nr_packets = 32*4;
 	fe0->dvb.name = dev->name;
 	fe0->dvb.name = dev->name;
-	videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops,
-			    &dev->pci->dev, &dev->slock,
-			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			    V4L2_FIELD_ALTERNATE,
-			    sizeof(struct saa7134_buf),
-			    dev, NULL);
+	q = &fe0->dvb.dvbq;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_READ;
+	q->drv_priv = &dev->ts_q;
+	q->ops = &saa7134_ts_qops;
+	q->mem_ops = &vb2_dma_sg_memops;
+	q->buf_struct_size = sizeof(struct saa7134_buf);
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->lock;
+	ret = vb2_queue_init(q);
+	if (ret) {
+		vb2_dvb_dealloc_frontends(&dev->frontends);
+		return ret;
+	}
 
 
 	switch (dev->board) {
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
 	case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
@@ -1876,7 +1885,7 @@ static int dvb_init(struct saa7134_dev *dev)
 	fe0->dvb.frontend->callback = saa7134_tuner_callback;
 	fe0->dvb.frontend->callback = saa7134_tuner_callback;
 
 
 	/* register everything else */
 	/* register everything else */
-	ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
+	ret = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
 					&dev->pci->dev, adapter_nr, 0);
 					&dev->pci->dev, adapter_nr, 0);
 
 
 	/* this sequence is necessary to make the tda1004x load its firmware
 	/* this sequence is necessary to make the tda1004x load its firmware
@@ -1893,16 +1902,17 @@ static int dvb_init(struct saa7134_dev *dev)
 	return ret;
 	return ret;
 
 
 detach_frontend:
 detach_frontend:
-	videobuf_dvb_dealloc_frontends(&dev->frontends);
+	vb2_dvb_dealloc_frontends(&dev->frontends);
+	vb2_queue_release(&fe0->dvb.dvbq);
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
 static int dvb_fini(struct saa7134_dev *dev)
 static int dvb_fini(struct saa7134_dev *dev)
 {
 {
-	struct videobuf_dvb_frontend *fe0;
+	struct vb2_dvb_frontend *fe0;
 
 
 	/* Get the first frontend */
 	/* Get the first frontend */
-	fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+	fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);
 	if (!fe0)
 	if (!fe0)
 		return -EINVAL;
 		return -EINVAL;
 
 
@@ -1933,7 +1943,8 @@ static int dvb_fini(struct saa7134_dev *dev)
 			}
 			}
 		}
 		}
 	}
 	}
-	videobuf_dvb_unregister_bus(&dev->frontends);
+	vb2_dvb_unregister_bus(&dev->frontends);
+	vb2_queue_release(&fe0->dvb.dvbq);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1955,10 +1966,3 @@ static void __exit dvb_unregister(void)
 
 
 module_init(dvb_register);
 module_init(dvb_register);
 module_exit(dvb_unregister);
 module_exit(dvb_unregister);
-
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */

+ 69 - 118
drivers/media/pci/saa7134/saa7134-empress.c

@@ -48,21 +48,16 @@ MODULE_PARM_DESC(debug,"enable debug messages");
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
 
 
-static void ts_reset_encoder(struct saa7134_dev* dev)
-{
-	if (!dev->empress_started)
-		return;
-
-	saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
-	msleep(10);
-	saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
-	msleep(100);
-	dev->empress_started = 0;
-}
-
-static int ts_init_encoder(struct saa7134_dev* dev)
+static int start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 {
+	struct saa7134_dmaqueue *dmaq = vq->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
 	u32 leading_null_bytes = 0;
 	u32 leading_null_bytes = 0;
+	int err;
+
+	err = saa7134_ts_start_streaming(vq, count);
+	if (err)
+		return err;
 
 
 	/* If more cards start to need this, then this
 	/* If more cards start to need this, then this
 	   should probably be added to the card definitions. */
 	   should probably be added to the card definitions. */
@@ -73,97 +68,43 @@ static int ts_init_encoder(struct saa7134_dev* dev)
 		leading_null_bytes = 1;
 		leading_null_bytes = 1;
 		break;
 		break;
 	}
 	}
-	ts_reset_encoder(dev);
 	saa_call_all(dev, core, init, leading_null_bytes);
 	saa_call_all(dev, core, init, leading_null_bytes);
-	dev->empress_started = 1;
-	return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int ts_open(struct file *file)
-{
-	struct video_device *vdev = video_devdata(file);
-	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh;
-
-	/* allocate + initialize per filehandle data */
-	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-	if (NULL == fh)
-		return -ENOMEM;
-
-	v4l2_fh_init(&fh->fh, vdev);
-	file->private_data = fh;
-	fh->is_empress = true;
-	v4l2_fh_add(&fh->fh);
-
 	/* Unmute audio */
 	/* Unmute audio */
 	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
 	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
-		saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
-
-	return 0;
-}
-
-static int ts_release(struct file *file)
-{
-	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh = file->private_data;
-
-	if (res_check(fh, RESOURCE_EMPRESS)) {
-		videobuf_stop(&dev->empress_tsq);
-		videobuf_mmap_free(&dev->empress_tsq);
-
-		/* stop the encoder */
-		ts_reset_encoder(dev);
-
-		/* Mute audio */
-		saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
-				saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
-	}
-
-	v4l2_fh_del(&fh->fh);
-	v4l2_fh_exit(&fh->fh);
+			saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
+	dev->empress_started = 1;
 	return 0;
 	return 0;
 }
 }
 
 
-static ssize_t
-ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
+static void stop_streaming(struct vb2_queue *vq)
 {
 {
-	struct saa7134_dev *dev = video_drvdata(file);
+	struct saa7134_dmaqueue *dmaq = vq->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
 
 
-	if (res_locked(dev, RESOURCE_EMPRESS))
-		return -EBUSY;
-	if (!dev->empress_started)
-		ts_init_encoder(dev);
-
-	return videobuf_read_stream(&dev->empress_tsq,
-				    data, count, ppos, 0,
-				    file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int
-ts_poll(struct file *file, struct poll_table_struct *wait)
-{
-	unsigned long req_events = poll_requested_events(wait);
-	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh = file->private_data;
-	unsigned int rc = 0;
-
-	if (v4l2_event_pending(&fh->fh))
-		rc = POLLPRI;
-	else if (req_events & POLLPRI)
-		poll_wait(file, &fh->fh.wait, wait);
-	return rc | videobuf_poll_stream(file, &dev->empress_tsq, wait);
+	saa7134_ts_stop_streaming(vq);
+	saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
+	msleep(20);
+	saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
+	msleep(100);
+	/* Mute audio */
+	saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
+			saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
+	dev->empress_started = 0;
 }
 }
 
 
+static struct vb2_ops saa7134_empress_qops = {
+	.queue_setup	= saa7134_ts_queue_setup,
+	.buf_init	= saa7134_ts_buffer_init,
+	.buf_prepare	= saa7134_ts_buffer_prepare,
+	.buf_finish	= saa7134_ts_buffer_finish,
+	.buf_queue	= saa7134_vb2_buffer_queue,
+	.wait_prepare	= vb2_ops_wait_prepare,
+	.wait_finish	= vb2_ops_wait_finish,
+	.start_streaming = start_streaming,
+	.stop_streaming = stop_streaming,
+};
 
 
-static int
-ts_mmap(struct file *file, struct vm_area_struct * vma)
-{
-	struct saa7134_dev *dev = video_drvdata(file);
-
-	return videobuf_mmap_mapper(&dev->empress_tsq, vma);
-}
+/* ------------------------------------------------------------------ */
 
 
 static int empress_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int empress_enum_fmt_vid_cap(struct file *file, void  *priv,
 					struct v4l2_fmtdesc *f)
 					struct v4l2_fmtdesc *f)
@@ -233,11 +174,11 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv,
 static const struct v4l2_file_operations ts_fops =
 static const struct v4l2_file_operations ts_fops =
 {
 {
 	.owner	  = THIS_MODULE,
 	.owner	  = THIS_MODULE,
-	.open	  = ts_open,
-	.release  = ts_release,
-	.read	  = ts_read,
-	.poll	  = ts_poll,
-	.mmap	  = ts_mmap,
+	.open	  = v4l2_fh_open,
+	.release  = vb2_fop_release,
+	.read	  = vb2_fop_read,
+	.poll	  = vb2_fop_poll,
+	.mmap	  = vb2_fop_mmap,
 	.ioctl	  = video_ioctl2,
 	.ioctl	  = video_ioctl2,
 };
 };
 
 
@@ -247,12 +188,12 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
 	.vidioc_try_fmt_vid_cap		= empress_try_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap		= empress_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap		= empress_s_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap		= empress_s_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap		= empress_g_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap		= empress_g_fmt_vid_cap,
-	.vidioc_reqbufs			= saa7134_reqbufs,
-	.vidioc_querybuf		= saa7134_querybuf,
-	.vidioc_qbuf			= saa7134_qbuf,
-	.vidioc_dqbuf			= saa7134_dqbuf,
-	.vidioc_streamon		= saa7134_streamon,
-	.vidioc_streamoff		= saa7134_streamoff,
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
 	.vidioc_g_frequency		= saa7134_g_frequency,
 	.vidioc_g_frequency		= saa7134_g_frequency,
 	.vidioc_s_frequency		= saa7134_s_frequency,
 	.vidioc_s_frequency		= saa7134_s_frequency,
 	.vidioc_g_tuner			= saa7134_g_tuner,
 	.vidioc_g_tuner			= saa7134_g_tuner,
@@ -262,6 +203,7 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
 	.vidioc_s_input			= saa7134_s_input,
 	.vidioc_s_input			= saa7134_s_input,
 	.vidioc_s_std			= saa7134_s_std,
 	.vidioc_s_std			= saa7134_s_std,
 	.vidioc_g_std			= saa7134_g_std,
 	.vidioc_g_std			= saa7134_g_std,
+	.vidioc_querystd		= saa7134_querystd,
 	.vidioc_log_status		= v4l2_ctrl_log_status,
 	.vidioc_log_status		= v4l2_ctrl_log_status,
 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
@@ -314,6 +256,7 @@ static bool empress_ctrl_filter(const struct v4l2_ctrl *ctrl)
 static int empress_init(struct saa7134_dev *dev)
 static int empress_init(struct saa7134_dev *dev)
 {
 {
 	struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler;
 	struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler;
+	struct vb2_queue *q;
 	int err;
 	int err;
 
 
 	dprintk("%s: %s\n",dev->name,__func__);
 	dprintk("%s: %s\n",dev->name,__func__);
@@ -323,6 +266,7 @@ static int empress_init(struct saa7134_dev *dev)
 	*(dev->empress_dev) = saa7134_empress_template;
 	*(dev->empress_dev) = saa7134_empress_template;
 	dev->empress_dev->v4l2_dev  = &dev->v4l2_dev;
 	dev->empress_dev->v4l2_dev  = &dev->v4l2_dev;
 	dev->empress_dev->release = video_device_release;
 	dev->empress_dev->release = video_device_release;
+	dev->empress_dev->lock = &dev->lock;
 	snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
 	snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
 		 "%s empress (%s)", dev->name,
 		 "%s empress (%s)", dev->name,
 		 saa7134_boards[dev->board].name);
 		 saa7134_boards[dev->board].name);
@@ -339,6 +283,26 @@ static int empress_init(struct saa7134_dev *dev)
 
 
 	INIT_WORK(&dev->empress_workqueue, empress_signal_update);
 	INIT_WORK(&dev->empress_workqueue, empress_signal_update);
 
 
+	q = &dev->empress_vbq;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	/*
+	 * Do not add VB2_USERPTR: the saa7134 DMA engine cannot handle
+	 * transfers that do not start at the beginning of a page. A USERPTR
+	 * can start anywhere in a page, so USERPTR support is a no-go.
+	 */
+	q->io_modes = VB2_MMAP | VB2_READ;
+	q->drv_priv = &dev->ts_q;
+	q->ops = &saa7134_empress_qops;
+	q->gfp_flags = GFP_DMA32;
+	q->mem_ops = &vb2_dma_sg_memops;
+	q->buf_struct_size = sizeof(struct saa7134_buf);
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->lock;
+	err = vb2_queue_init(q);
+	if (err)
+		return err;
+	dev->empress_dev->queue = q;
+
 	video_set_drvdata(dev->empress_dev, dev);
 	video_set_drvdata(dev->empress_dev, dev);
 	err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
 	err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
 				    empress_nr[dev->nr]);
 				    empress_nr[dev->nr]);
@@ -352,13 +316,6 @@ static int empress_init(struct saa7134_dev *dev)
 	printk(KERN_INFO "%s: registered device %s [mpeg]\n",
 	printk(KERN_INFO "%s: registered device %s [mpeg]\n",
 	       dev->name, video_device_node_name(dev->empress_dev));
 	       dev->name, video_device_node_name(dev->empress_dev));
 
 
-	videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops,
-			    &dev->pci->dev, &dev->slock,
-			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			    V4L2_FIELD_ALTERNATE,
-			    sizeof(struct saa7134_buf),
-			    dev, NULL);
-
 	empress_signal_update(&dev->empress_workqueue);
 	empress_signal_update(&dev->empress_workqueue);
 	return 0;
 	return 0;
 }
 }
@@ -371,6 +328,7 @@ static int empress_fini(struct saa7134_dev *dev)
 		return 0;
 		return 0;
 	flush_work(&dev->empress_workqueue);
 	flush_work(&dev->empress_workqueue);
 	video_unregister_device(dev->empress_dev);
 	video_unregister_device(dev->empress_dev);
+	vb2_queue_release(&dev->empress_vbq);
 	v4l2_ctrl_handler_free(&dev->empress_ctrl_handler);
 	v4l2_ctrl_handler_free(&dev->empress_ctrl_handler);
 	dev->empress_dev = NULL;
 	dev->empress_dev = NULL;
 	return 0;
 	return 0;
@@ -395,10 +353,3 @@ static void __exit empress_unregister(void)
 
 
 module_init(empress_register);
 module_init(empress_register);
 module_exit(empress_unregister);
 module_exit(empress_unregister);
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */

+ 0 - 7
drivers/media/pci/saa7134/saa7134-i2c.c

@@ -427,10 +427,3 @@ int saa7134_i2c_unregister(struct saa7134_dev *dev)
 	i2c_del_adapter(&dev->i2c_adap);
 	i2c_del_adapter(&dev->i2c_adap);
 	return 0;
 	return 0;
 }
 }
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */

+ 5 - 7
drivers/media/pci/saa7134/saa7134-reg.h

@@ -167,17 +167,22 @@
 #define SAA7134_HSYNC_START                     0x106
 #define SAA7134_HSYNC_START                     0x106
 #define SAA7134_HSYNC_STOP                      0x107
 #define SAA7134_HSYNC_STOP                      0x107
 #define SAA7134_SYNC_CTRL                       0x108
 #define SAA7134_SYNC_CTRL                       0x108
+#define   SAA7134_SYNC_CTRL_AUFD                (1 << 7)
 #define SAA7134_LUMA_CTRL                       0x109
 #define SAA7134_LUMA_CTRL                       0x109
+#define   SAA7134_LUMA_CTRL_LDEL                (1 << 5)
 #define SAA7134_DEC_LUMA_BRIGHT                 0x10a
 #define SAA7134_DEC_LUMA_BRIGHT                 0x10a
 #define SAA7134_DEC_LUMA_CONTRAST               0x10b
 #define SAA7134_DEC_LUMA_CONTRAST               0x10b
 #define SAA7134_DEC_CHROMA_SATURATION           0x10c
 #define SAA7134_DEC_CHROMA_SATURATION           0x10c
 #define SAA7134_DEC_CHROMA_HUE                  0x10d
 #define SAA7134_DEC_CHROMA_HUE                  0x10d
 #define SAA7134_CHROMA_CTRL1                    0x10e
 #define SAA7134_CHROMA_CTRL1                    0x10e
+#define   SAA7134_CHROMA_CTRL1_AUTO0            (1 << 1)
+#define   SAA7134_CHROMA_CTRL1_FCTC             (1 << 2)
 #define SAA7134_CHROMA_GAIN                     0x10f
 #define SAA7134_CHROMA_GAIN                     0x10f
 #define SAA7134_CHROMA_CTRL2                    0x110
 #define SAA7134_CHROMA_CTRL2                    0x110
 #define SAA7134_MODE_DELAY_CTRL                 0x111
 #define SAA7134_MODE_DELAY_CTRL                 0x111
 
 
 #define SAA7134_ANALOG_ADC                      0x114
 #define SAA7134_ANALOG_ADC                      0x114
+#define   SAA7134_ANALOG_ADC_AUTO1              (1 << 2)
 #define SAA7134_VGATE_START                     0x115
 #define SAA7134_VGATE_START                     0x115
 #define SAA7134_VGATE_STOP                      0x116
 #define SAA7134_VGATE_STOP                      0x116
 #define SAA7134_MISC_VGATE_MSB                  0x117
 #define SAA7134_MISC_VGATE_MSB                  0x117
@@ -369,10 +374,3 @@
 #define SAA7135_DSP_RWCLEAR_RERR		    1
 #define SAA7135_DSP_RWCLEAR_RERR		    1
 
 
 #define SAA7133_I2S_AUDIO_CONTROL               0x591
 #define SAA7133_I2S_AUDIO_CONTROL               0x591
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-

+ 108 - 83
drivers/media/pci/saa7134/saa7134-ts.c

@@ -39,26 +39,29 @@ MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
 	printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
 	printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
-
 static int buffer_activate(struct saa7134_dev *dev,
 static int buffer_activate(struct saa7134_dev *dev,
 			   struct saa7134_buf *buf,
 			   struct saa7134_buf *buf,
 			   struct saa7134_buf *next)
 			   struct saa7134_buf *next)
 {
 {
 
 
 	dprintk("buffer_activate [%p]",buf);
 	dprintk("buffer_activate [%p]",buf);
-	buf->vb.state = VIDEOBUF_ACTIVE;
 	buf->top_seen = 0;
 	buf->top_seen = 0;
 
 
+	if (!dev->ts_started)
+		dev->ts_field = V4L2_FIELD_TOP;
+
 	if (NULL == next)
 	if (NULL == next)
 		next = buf;
 		next = buf;
-	if (V4L2_FIELD_TOP == buf->vb.field) {
+	if (V4L2_FIELD_TOP == dev->ts_field) {
 		dprintk("- [top]     buf=%p next=%p\n",buf,next);
 		dprintk("- [top]     buf=%p next=%p\n",buf,next);
 		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
 		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
 		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
 		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
+		dev->ts_field = V4L2_FIELD_BOTTOM;
 	} else {
 	} else {
 		dprintk("- [bottom]  buf=%p next=%p\n",buf,next);
 		dprintk("- [bottom]  buf=%p next=%p\n",buf,next);
 		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
 		saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
 		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
 		saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
+		dev->ts_field = V4L2_FIELD_TOP;
 	}
 	}
 
 
 	/* start DMA */
 	/* start DMA */
@@ -72,96 +75,123 @@ static int buffer_activate(struct saa7134_dev *dev,
 	return 0;
 	return 0;
 }
 }
 
 
-static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
-		enum v4l2_field field)
+int saa7134_ts_buffer_init(struct vb2_buffer *vb2)
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+
+	dmaq->curr = NULL;
+	buf->activate = buffer_activate;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(saa7134_ts_buffer_init);
+
+int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2)
+{
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+	struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0);
 	unsigned int lines, llength, size;
 	unsigned int lines, llength, size;
-	int err;
+	int ret;
 
 
-	dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
+	dprintk("buffer_prepare [%p]\n", buf);
 
 
 	llength = TS_PACKET_SIZE;
 	llength = TS_PACKET_SIZE;
 	lines = dev->ts.nr_packets;
 	lines = dev->ts.nr_packets;
 
 
 	size = lines * llength;
 	size = lines * llength;
-	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
+	if (vb2_plane_size(vb2, 0) < size)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (buf->vb.size != size) {
-		saa7134_dma_free(q,buf);
-	}
-
-	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-
-		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
-		dprintk("buffer_prepare: needs_init\n");
-
-		buf->vb.width  = llength;
-		buf->vb.height = lines;
-		buf->vb.size   = size;
-		buf->pt        = &dev->ts.pt_ts;
-
-		err = videobuf_iolock(q,&buf->vb,NULL);
-		if (err)
-			goto oops;
-		err = saa7134_pgtable_build(dev->pci,buf->pt,
-					    dma->sglist,
-					    dma->sglen,
-					    saa7134_buffer_startpage(buf));
-		if (err)
-			goto oops;
-	}
-
-	buf->vb.state = VIDEOBUF_PREPARED;
-	buf->activate = buffer_activate;
-	buf->vb.field = field;
-	return 0;
+	vb2_set_plane_payload(vb2, 0, size);
+	vb2->v4l2_buf.field = dev->field;
 
 
- oops:
-	saa7134_dma_free(q,buf);
-	return err;
+	ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
+	if (!ret)
+		return -EIO;
+	return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
+				    saa7134_buffer_startpage(buf));
 }
 }
+EXPORT_SYMBOL_GPL(saa7134_ts_buffer_prepare);
 
 
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
+void saa7134_ts_buffer_finish(struct vb2_buffer *vb2)
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
 
 
-	*size = TS_PACKET_SIZE * dev->ts.nr_packets;
-	if (0 == *count)
-		*count = dev->ts.nr_bufs;
-	*count = saa7134_buffer_count(*size,*count);
+	dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
+}
+EXPORT_SYMBOL_GPL(saa7134_ts_buffer_finish);
 
 
+int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *nbuffers, unsigned int *nplanes,
+			   unsigned int sizes[], void *alloc_ctxs[])
+{
+	struct saa7134_dmaqueue *dmaq = q->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	int size = TS_PACKET_SIZE * dev->ts.nr_packets;
+
+	if (0 == *nbuffers)
+		*nbuffers = dev->ts.nr_bufs;
+	*nbuffers = saa7134_buffer_count(size, *nbuffers);
+	if (*nbuffers < 3)
+		*nbuffers = 3;
+	*nplanes = 1;
+	sizes[0] = size;
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL_GPL(saa7134_ts_queue_setup);
 
 
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
-
-	saa7134_buffer_queue(dev,&dev->ts_q,buf);
+	struct saa7134_dmaqueue *dmaq = vq->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+
+	/*
+	 * Planar video capture and TS share the same DMA channel,
+	 * so only one can be active at a time.
+	 */
+	if (vb2_is_busy(&dev->video_vbq) && dev->fmt->planar) {
+		struct saa7134_buf *buf, *tmp;
+
+		list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) {
+			list_del(&buf->entry);
+			vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED);
+		}
+		if (dmaq->curr) {
+			vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED);
+			dmaq->curr = NULL;
+		}
+		return -EBUSY;
+	}
+	dmaq->seq_nr = 0;
+	return 0;
 }
 }
+EXPORT_SYMBOL_GPL(saa7134_ts_start_streaming);
 
 
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+void saa7134_ts_stop_streaming(struct vb2_queue *vq)
 {
 {
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
-	struct saa7134_dev *dev = q->priv_data;
-
-	if (dev->ts_started)
-		saa7134_ts_stop(dev);
+	struct saa7134_dmaqueue *dmaq = vq->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
 
 
-	saa7134_dma_free(q,buf);
+	saa7134_ts_stop(dev);
+	saa7134_stop_streaming(dev, dmaq);
 }
 }
-
-struct videobuf_queue_ops saa7134_ts_qops = {
-	.buf_setup    = buffer_setup,
-	.buf_prepare  = buffer_prepare,
-	.buf_queue    = buffer_queue,
-	.buf_release  = buffer_release,
+EXPORT_SYMBOL_GPL(saa7134_ts_stop_streaming);
+
+struct vb2_ops saa7134_ts_qops = {
+	.queue_setup	= saa7134_ts_queue_setup,
+	.buf_init	= saa7134_ts_buffer_init,
+	.buf_prepare	= saa7134_ts_buffer_prepare,
+	.buf_finish	= saa7134_ts_buffer_finish,
+	.buf_queue	= saa7134_vb2_buffer_queue,
+	.wait_prepare	= vb2_ops_wait_prepare,
+	.wait_finish	= vb2_ops_wait_finish,
+	.stop_streaming = saa7134_ts_stop_streaming,
 };
 };
 EXPORT_SYMBOL_GPL(saa7134_ts_qops);
 EXPORT_SYMBOL_GPL(saa7134_ts_qops);
 
 
@@ -213,7 +243,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
 	dev->ts_q.dev              = dev;
 	dev->ts_q.dev              = dev;
 	dev->ts_q.need_two         = 1;
 	dev->ts_q.need_two         = 1;
 	dev->ts_started            = 0;
 	dev->ts_started            = 0;
-	saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
+	saa7134_pgtable_alloc(dev->pci, &dev->ts_q.pt);
 
 
 	/* init TS hw */
 	/* init TS hw */
 	saa7134_ts_init_hw(dev);
 	saa7134_ts_init_hw(dev);
@@ -226,7 +256,8 @@ int saa7134_ts_stop(struct saa7134_dev *dev)
 {
 {
 	dprintk("TS stop\n");
 	dprintk("TS stop\n");
 
 
-	BUG_ON(!dev->ts_started);
+	if (!dev->ts_started)
+		return 0;
 
 
 	/* Stop TS stream */
 	/* Stop TS stream */
 	switch (saa7134_boards[dev->board].ts_type) {
 	switch (saa7134_boards[dev->board].ts_type) {
@@ -247,7 +278,8 @@ int saa7134_ts_start(struct saa7134_dev *dev)
 {
 {
 	dprintk("TS start\n");
 	dprintk("TS start\n");
 
 
-	BUG_ON(dev->ts_started);
+	if (WARN_ON(dev->ts_started))
+		return 0;
 
 
 	/* dma: setup channel 5 (= TS) */
 	/* dma: setup channel 5 (= TS) */
 	saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
 	saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff);
@@ -259,7 +291,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)
 	saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
 	saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE);
 	saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
 	saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 |
 					  SAA7134_RS_CONTROL_ME |
 					  SAA7134_RS_CONTROL_ME |
-					  (dev->ts.pt_ts.dma >> 12));
+					  (dev->ts_q.pt.dma >> 12));
 
 
 	/* reset hardware TS buffers */
 	/* reset hardware TS buffers */
 	saa_writeb(SAA7134_TS_SERIAL1, 0x00);
 	saa_writeb(SAA7134_TS_SERIAL1, 0x00);
@@ -293,7 +325,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)
 
 
 int saa7134_ts_fini(struct saa7134_dev *dev)
 int saa7134_ts_fini(struct saa7134_dev *dev)
 {
 {
-	saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
+	saa7134_pgtable_free(dev->pci, &dev->ts_q.pt);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -303,25 +335,18 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
 
 
 	spin_lock(&dev->slock);
 	spin_lock(&dev->slock);
 	if (dev->ts_q.curr) {
 	if (dev->ts_q.curr) {
-		field = dev->ts_q.curr->vb.field;
-		if (field == V4L2_FIELD_TOP) {
+		field = dev->ts_field;
+		if (field != V4L2_FIELD_TOP) {
 			if ((status & 0x100000) != 0x000000)
 			if ((status & 0x100000) != 0x000000)
 				goto done;
 				goto done;
 		} else {
 		} else {
 			if ((status & 0x100000) != 0x100000)
 			if ((status & 0x100000) != 0x100000)
 				goto done;
 				goto done;
 		}
 		}
-		saa7134_buffer_finish(dev,&dev->ts_q,VIDEOBUF_DONE);
+		saa7134_buffer_finish(dev, &dev->ts_q, VB2_BUF_STATE_DONE);
 	}
 	}
 	saa7134_buffer_next(dev,&dev->ts_q);
 	saa7134_buffer_next(dev,&dev->ts_q);
 
 
  done:
  done:
 	spin_unlock(&dev->slock);
 	spin_unlock(&dev->slock);
 }
 }
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */

+ 0 - 7
drivers/media/pci/saa7134/saa7134-tvaudio.c

@@ -1079,10 +1079,3 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
 
 
 EXPORT_SYMBOL(saa_dsp_writel);
 EXPORT_SYMBOL(saa_dsp_writel);
 EXPORT_SYMBOL(saa7134_tvaudio_setmute);
 EXPORT_SYMBOL(saa7134_tvaudio_setmute);
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */

+ 79 - 96
drivers/media/pci/saa7134/saa7134-vbi.c

@@ -67,10 +67,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
 	saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task),   0x00);
 	saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task),   0x00);
 	saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
 	saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
 
 
-	saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width   & 0xff);
-	saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width   >> 8);
-	saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height  & 0xff);
-	saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height  >> 8);
+	saa_writeb(SAA7134_VBI_H_LEN1(task), dev->vbi_hlen & 0xff);
+	saa_writeb(SAA7134_VBI_H_LEN2(task), dev->vbi_hlen >> 8);
+	saa_writeb(SAA7134_VBI_V_LEN1(task), dev->vbi_vlen & 0xff);
+	saa_writeb(SAA7134_VBI_V_LEN2(task), dev->vbi_vlen >> 8);
 
 
 	saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
 	saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
 }
 }
@@ -81,14 +81,14 @@ static int buffer_activate(struct saa7134_dev *dev,
 			   struct saa7134_buf *buf,
 			   struct saa7134_buf *buf,
 			   struct saa7134_buf *next)
 			   struct saa7134_buf *next)
 {
 {
-	unsigned long control,base;
+	struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv;
+	unsigned long control, base;
 
 
-	dprintk("buffer_activate [%p]\n",buf);
-	buf->vb.state = VIDEOBUF_ACTIVE;
+	dprintk("buffer_activate [%p]\n", buf);
 	buf->top_seen = 0;
 	buf->top_seen = 0;
 
 
-	task_init(dev,buf,TASK_A);
-	task_init(dev,buf,TASK_B);
+	task_init(dev, buf, TASK_A);
+	task_init(dev, buf, TASK_B);
 	saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
 	saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
 	saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
 	saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
 
 
@@ -96,107 +96,99 @@ static int buffer_activate(struct saa7134_dev *dev,
 	base    = saa7134_buffer_base(buf);
 	base    = saa7134_buffer_base(buf);
 	control = SAA7134_RS_CONTROL_BURST_16 |
 	control = SAA7134_RS_CONTROL_BURST_16 |
 		SAA7134_RS_CONTROL_ME |
 		SAA7134_RS_CONTROL_ME |
-		(buf->pt->dma >> 12);
-	saa_writel(SAA7134_RS_BA1(2),base);
-	saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2);
-	saa_writel(SAA7134_RS_PITCH(2),buf->vb.width);
-	saa_writel(SAA7134_RS_CONTROL(2),control);
-	saa_writel(SAA7134_RS_BA1(3),base);
-	saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2);
-	saa_writel(SAA7134_RS_PITCH(3),buf->vb.width);
-	saa_writel(SAA7134_RS_CONTROL(3),control);
+		(dmaq->pt.dma >> 12);
+	saa_writel(SAA7134_RS_BA1(2), base);
+	saa_writel(SAA7134_RS_BA2(2), base + dev->vbi_hlen * dev->vbi_vlen);
+	saa_writel(SAA7134_RS_PITCH(2), dev->vbi_hlen);
+	saa_writel(SAA7134_RS_CONTROL(2), control);
+	saa_writel(SAA7134_RS_BA1(3), base);
+	saa_writel(SAA7134_RS_BA2(3), base + dev->vbi_hlen * dev->vbi_vlen);
+	saa_writel(SAA7134_RS_PITCH(3), dev->vbi_hlen);
+	saa_writel(SAA7134_RS_CONTROL(3), control);
 
 
 	/* start DMA */
 	/* start DMA */
 	saa7134_set_dmabits(dev);
 	saa7134_set_dmabits(dev);
-	mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
+	mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int buffer_prepare(struct videobuf_queue *q,
-			  struct videobuf_buffer *vb,
-			  enum v4l2_field field)
+static int buffer_prepare(struct vb2_buffer *vb2)
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
-	struct saa7134_tvnorm *norm = dev->tvnorm;
-	unsigned int lines, llength, size;
-	int err;
-
-	lines   = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
-	if (lines > VBI_LINE_COUNT)
-		lines = VBI_LINE_COUNT;
-	llength = VBI_LINE_LENGTH;
-	size = lines * llength * 2;
-	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
+	unsigned int size;
+	int ret;
+
+	if (dma->sgl->offset) {
+		pr_err("The buffer is not page-aligned\n");
 		return -EINVAL;
 		return -EINVAL;
-
-	if (buf->vb.size != size)
-		saa7134_dma_free(q,buf);
-
-	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
-		buf->vb.width  = llength;
-		buf->vb.height = lines;
-		buf->vb.size   = size;
-		buf->pt        = &dev->pt_vbi;
-
-		err = videobuf_iolock(q,&buf->vb,NULL);
-		if (err)
-			goto oops;
-		err = saa7134_pgtable_build(dev->pci,buf->pt,
-					    dma->sglist,
-					    dma->sglen,
-					    saa7134_buffer_startpage(buf));
-		if (err)
-			goto oops;
 	}
 	}
-	buf->vb.state = VIDEOBUF_PREPARED;
-	buf->activate = buffer_activate;
-	buf->vb.field = field;
-	return 0;
+	size = dev->vbi_hlen * dev->vbi_vlen * 2;
+	if (vb2_plane_size(vb2, 0) < size)
+		return -EINVAL;
+
+	vb2_set_plane_payload(vb2, 0, size);
 
 
- oops:
-	saa7134_dma_free(q,buf);
-	return err;
+	ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
+	if (!ret)
+		return -EIO;
+	return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
+				    saa7134_buffer_startpage(buf));
 }
 }
 
 
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *nbuffers, unsigned int *nplanes,
+			   unsigned int sizes[], void *alloc_ctxs[])
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
-	int llength,lines;
-
-	lines   = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
-	llength = VBI_LINE_LENGTH;
-	*size = lines * llength * 2;
-	if (0 == *count)
-		*count = vbibufs;
-	*count = saa7134_buffer_count(*size,*count);
+	struct saa7134_dmaqueue *dmaq = q->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	unsigned int size;
+
+	dev->vbi_vlen = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 + 1;
+	if (dev->vbi_vlen > VBI_LINE_COUNT)
+		dev->vbi_vlen = VBI_LINE_COUNT;
+	dev->vbi_hlen = VBI_LINE_LENGTH;
+	size = dev->vbi_hlen * dev->vbi_vlen * 2;
+
+	*nbuffers = saa7134_buffer_count(size, *nbuffers);
+	*nplanes = 1;
+	sizes[0] = size;
 	return 0;
 	return 0;
 }
 }
 
 
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+static int buffer_init(struct vb2_buffer *vb2)
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
 
 
-	saa7134_buffer_queue(dev,&dev->vbi_q,buf);
+	dmaq->curr = NULL;
+	buf->activate = buffer_activate;
+	return 0;
 }
 }
 
 
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb2)
 {
 {
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
 
 
-	saa7134_dma_free(q,buf);
+	dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
 }
 }
 
 
-struct videobuf_queue_ops saa7134_vbi_qops = {
-	.buf_setup    = buffer_setup,
-	.buf_prepare  = buffer_prepare,
-	.buf_queue    = buffer_queue,
-	.buf_release  = buffer_release,
+struct vb2_ops saa7134_vbi_qops = {
+	.queue_setup	= queue_setup,
+	.buf_init	= buffer_init,
+	.buf_prepare	= buffer_prepare,
+	.buf_finish	= buffer_finish,
+	.buf_queue	= saa7134_vb2_buffer_queue,
+	.wait_prepare	= vb2_ops_wait_prepare,
+	.wait_finish	= vb2_ops_wait_finish,
+	.start_streaming = saa7134_vb2_start_streaming,
+	.stop_streaming = saa7134_vb2_stop_streaming,
 };
 };
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
@@ -226,7 +218,6 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
 {
 {
 	spin_lock(&dev->slock);
 	spin_lock(&dev->slock);
 	if (dev->vbi_q.curr) {
 	if (dev->vbi_q.curr) {
-		dev->vbi_fieldcount++;
 		/* make sure we have seen both fields */
 		/* make sure we have seen both fields */
 		if ((status & 0x10) == 0x00) {
 		if ((status & 0x10) == 0x00) {
 			dev->vbi_q.curr->top_seen = 1;
 			dev->vbi_q.curr->top_seen = 1;
@@ -235,18 +226,10 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
 		if (!dev->vbi_q.curr->top_seen)
 		if (!dev->vbi_q.curr->top_seen)
 			goto done;
 			goto done;
 
 
-		dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
-		saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE);
+		saa7134_buffer_finish(dev, &dev->vbi_q, VB2_BUF_STATE_DONE);
 	}
 	}
-	saa7134_buffer_next(dev,&dev->vbi_q);
+	saa7134_buffer_next(dev, &dev->vbi_q);
 
 
  done:
  done:
 	spin_unlock(&dev->slock);
 	spin_unlock(&dev->slock);
 }
 }
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */

+ 279 - 418
drivers/media/pci/saa7134/saa7134-video.c

@@ -381,42 +381,6 @@ static struct saa7134_format* format_by_fourcc(unsigned int fourcc)
 	return NULL;
 	return NULL;
 }
 }
 
 
-/* ----------------------------------------------------------------------- */
-/* resource management                                                     */
-
-static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit)
-{
-	if (fh->resources & bit)
-		/* have it already allocated */
-		return 1;
-
-	/* is it free? */
-	mutex_lock(&dev->lock);
-	if (dev->resources & bit) {
-		/* no, someone else uses it */
-		mutex_unlock(&dev->lock);
-		return 0;
-	}
-	/* it's free, grab it */
-	fh->resources  |= bit;
-	dev->resources |= bit;
-	dprintk("res: get %d\n",bit);
-	mutex_unlock(&dev->lock);
-	return 1;
-}
-
-static
-void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
-{
-	BUG_ON((fh->resources & bits) != bits);
-
-	mutex_lock(&dev->lock);
-	fh->resources  &= ~bits;
-	dev->resources &= ~bits;
-	dprintk("res: put %d\n",bits);
-	mutex_unlock(&dev->lock);
-}
-
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
 
 
 static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
 static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
@@ -452,19 +416,26 @@ static void video_mux(struct saa7134_dev *dev, int input)
 
 
 static void saa7134_set_decoder(struct saa7134_dev *dev)
 static void saa7134_set_decoder(struct saa7134_dev *dev)
 {
 {
-	int luma_control, sync_control, mux;
+	int luma_control, sync_control, chroma_ctrl1, mux;
 
 
 	struct saa7134_tvnorm *norm = dev->tvnorm;
 	struct saa7134_tvnorm *norm = dev->tvnorm;
 	mux = card_in(dev, dev->ctl_input).vmux;
 	mux = card_in(dev, dev->ctl_input).vmux;
 
 
 	luma_control = norm->luma_control;
 	luma_control = norm->luma_control;
 	sync_control = norm->sync_control;
 	sync_control = norm->sync_control;
+	chroma_ctrl1 = norm->chroma_ctrl1;
 
 
 	if (mux > 5)
 	if (mux > 5)
 		luma_control |= 0x80; /* svideo */
 		luma_control |= 0x80; /* svideo */
 	if (noninterlaced || dev->nosignal)
 	if (noninterlaced || dev->nosignal)
 		sync_control |= 0x20;
 		sync_control |= 0x20;
 
 
+	/* switch on auto standard detection */
+	sync_control |= SAA7134_SYNC_CTRL_AUFD;
+	chroma_ctrl1 |= SAA7134_CHROMA_CTRL1_AUTO0;
+	chroma_ctrl1 &= ~SAA7134_CHROMA_CTRL1_FCTC;
+	luma_control &= ~SAA7134_LUMA_CTRL_LDEL;
+
 	/* setup video decoder */
 	/* setup video decoder */
 	saa_writeb(SAA7134_INCR_DELAY,            0x08);
 	saa_writeb(SAA7134_INCR_DELAY,            0x08);
 	saa_writeb(SAA7134_ANALOG_IN_CTRL1,       0xc0 | mux);
 	saa_writeb(SAA7134_ANALOG_IN_CTRL1,       0xc0 | mux);
@@ -487,7 +458,7 @@ static void saa7134_set_decoder(struct saa7134_dev *dev)
 		dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
 		dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
 
 
 	saa_writeb(SAA7134_DEC_CHROMA_HUE,        dev->ctl_hue);
 	saa_writeb(SAA7134_DEC_CHROMA_HUE,        dev->ctl_hue);
-	saa_writeb(SAA7134_CHROMA_CTRL1,          norm->chroma_ctrl1);
+	saa_writeb(SAA7134_CHROMA_CTRL1,          chroma_ctrl1);
 	saa_writeb(SAA7134_CHROMA_GAIN,           norm->chroma_gain);
 	saa_writeb(SAA7134_CHROMA_GAIN,           norm->chroma_gain);
 
 
 	saa_writeb(SAA7134_CHROMA_CTRL2,          norm->chroma_ctrl2);
 	saa_writeb(SAA7134_CHROMA_CTRL2,          norm->chroma_ctrl2);
@@ -506,10 +477,10 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
 	saa7134_set_decoder(dev);
 	saa7134_set_decoder(dev);
 
 
 	if (card_in(dev, dev->ctl_input).tv)
 	if (card_in(dev, dev->ctl_input).tv)
-		saa_call_all(dev, core, s_std, dev->tvnorm->id);
+		saa_call_all(dev, video, s_std, dev->tvnorm->id);
 	/* Set the correct norm for the saa6752hs. This function
 	/* Set the correct norm for the saa6752hs. This function
 	   does nothing if there is no saa6752hs. */
 	   does nothing if there is no saa6752hs. */
-	saa_call_empress(dev, core, s_std, dev->tvnorm->id);
+	saa_call_empress(dev, video, s_std, dev->tvnorm->id);
 }
 }
 
 
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
@@ -817,35 +788,35 @@ static int buffer_activate(struct saa7134_dev *dev,
 			   struct saa7134_buf *buf,
 			   struct saa7134_buf *buf,
 			   struct saa7134_buf *next)
 			   struct saa7134_buf *next)
 {
 {
+	struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv;
 	unsigned long base,control,bpl;
 	unsigned long base,control,bpl;
 	unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
 	unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
 
 
 	dprintk("buffer_activate buf=%p\n",buf);
 	dprintk("buffer_activate buf=%p\n",buf);
-	buf->vb.state = VIDEOBUF_ACTIVE;
 	buf->top_seen = 0;
 	buf->top_seen = 0;
 
 
-	set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
-		 V4L2_FIELD_HAS_BOTH(buf->vb.field));
-	if (buf->fmt->yuv)
+	set_size(dev, TASK_A, dev->width, dev->height,
+		 V4L2_FIELD_HAS_BOTH(dev->field));
+	if (dev->fmt->yuv)
 		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);
 		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);
 	else
 	else
 		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01);
 		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01);
-	saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm);
+	saa_writeb(SAA7134_OFMT_VIDEO_A, dev->fmt->pm);
 
 
 	/* DMA: setup channel 0 (= Video Task A0) */
 	/* DMA: setup channel 0 (= Video Task A0) */
 	base  = saa7134_buffer_base(buf);
 	base  = saa7134_buffer_base(buf);
-	if (buf->fmt->planar)
-		bpl = buf->vb.width;
+	if (dev->fmt->planar)
+		bpl = dev->width;
 	else
 	else
-		bpl = (buf->vb.width * buf->fmt->depth) / 8;
+		bpl = (dev->width * dev->fmt->depth) / 8;
 	control = SAA7134_RS_CONTROL_BURST_16 |
 	control = SAA7134_RS_CONTROL_BURST_16 |
 		SAA7134_RS_CONTROL_ME |
 		SAA7134_RS_CONTROL_ME |
-		(buf->pt->dma >> 12);
-	if (buf->fmt->bswap)
+		(dmaq->pt.dma >> 12);
+	if (dev->fmt->bswap)
 		control |= SAA7134_RS_CONTROL_BSWAP;
 		control |= SAA7134_RS_CONTROL_BSWAP;
-	if (buf->fmt->wswap)
+	if (dev->fmt->wswap)
 		control |= SAA7134_RS_CONTROL_WSWAP;
 		control |= SAA7134_RS_CONTROL_WSWAP;
-	if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
+	if (V4L2_FIELD_HAS_BOTH(dev->field)) {
 		/* interlaced */
 		/* interlaced */
 		saa_writel(SAA7134_RS_BA1(0),base);
 		saa_writel(SAA7134_RS_BA1(0),base);
 		saa_writel(SAA7134_RS_BA2(0),base+bpl);
 		saa_writel(SAA7134_RS_BA2(0),base+bpl);
@@ -858,17 +829,17 @@ static int buffer_activate(struct saa7134_dev *dev,
 	}
 	}
 	saa_writel(SAA7134_RS_CONTROL(0),control);
 	saa_writel(SAA7134_RS_CONTROL(0),control);
 
 
-	if (buf->fmt->planar) {
+	if (dev->fmt->planar) {
 		/* DMA: setup channel 4+5 (= planar task A) */
 		/* DMA: setup channel 4+5 (= planar task A) */
-		bpl_uv   = bpl >> buf->fmt->hshift;
-		lines_uv = buf->vb.height >> buf->fmt->vshift;
-		base2    = base + bpl * buf->vb.height;
+		bpl_uv   = bpl >> dev->fmt->hshift;
+		lines_uv = dev->height >> dev->fmt->vshift;
+		base2    = base + bpl * dev->height;
 		base3    = base2 + bpl_uv * lines_uv;
 		base3    = base2 + bpl_uv * lines_uv;
-		if (buf->fmt->uvswap)
+		if (dev->fmt->uvswap)
 			tmp = base2, base2 = base3, base3 = tmp;
 			tmp = base2, base2 = base3, base3 = tmp;
 		dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
 		dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
 			bpl_uv,lines_uv,base2,base3);
 			bpl_uv,lines_uv,base2,base3);
-		if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
+		if (V4L2_FIELD_HAS_BOTH(dev->field)) {
 			/* interlaced */
 			/* interlaced */
 			saa_writel(SAA7134_RS_BA1(4),base2);
 			saa_writel(SAA7134_RS_BA1(4),base2);
 			saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv);
 			saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv);
@@ -891,22 +862,65 @@ static int buffer_activate(struct saa7134_dev *dev,
 
 
 	/* start DMA */
 	/* start DMA */
 	saa7134_set_dmabits(dev);
 	saa7134_set_dmabits(dev);
-	mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
+	mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT);
+	return 0;
+}
+
+static int buffer_init(struct vb2_buffer *vb2)
+{
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+
+	dmaq->curr = NULL;
+	buf->activate = buffer_activate;
 	return 0;
 	return 0;
 }
 }
 
 
-static int buffer_prepare(struct videobuf_queue *q,
-			  struct videobuf_buffer *vb,
-			  enum v4l2_field field)
+static int buffer_prepare(struct vb2_buffer *vb2)
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
 	unsigned int size;
 	unsigned int size;
-	int err;
+	int ret;
 
 
-	/* sanity checks */
-	if (NULL == dev->fmt)
+	if (dma->sgl->offset) {
+		pr_err("The buffer is not page-aligned\n");
 		return -EINVAL;
 		return -EINVAL;
+	}
+	size = (dev->width * dev->height * dev->fmt->depth) >> 3;
+	if (vb2_plane_size(vb2, 0) < size)
+		return -EINVAL;
+
+	vb2_set_plane_payload(vb2, 0, size);
+	vb2->v4l2_buf.field = dev->field;
+
+	ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
+	if (!ret)
+		return -EIO;
+	return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents,
+				    saa7134_buffer_startpage(buf));
+}
+
+static void buffer_finish(struct vb2_buffer *vb2)
+{
+	struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2);
+	struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0);
+
+	dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
+}
+
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *nbuffers, unsigned int *nplanes,
+			   unsigned int sizes[], void *alloc_ctxs[])
+{
+	struct saa7134_dmaqueue *dmaq = q->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	int size = dev->fmt->depth * dev->width * dev->height >> 3;
+
 	if (dev->width    < 48 ||
 	if (dev->width    < 48 ||
 	    dev->height   < 32 ||
 	    dev->height   < 32 ||
 	    dev->width/4  > dev->crop_current.width  ||
 	    dev->width/4  > dev->crop_current.width  ||
@@ -914,83 +928,88 @@ static int buffer_prepare(struct videobuf_queue *q,
 	    dev->width    > dev->crop_bounds.width  ||
 	    dev->width    > dev->crop_bounds.width  ||
 	    dev->height   > dev->crop_bounds.height)
 	    dev->height   > dev->crop_bounds.height)
 		return -EINVAL;
 		return -EINVAL;
-	size = (dev->width * dev->height * dev->fmt->depth) >> 3;
-	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
-		return -EINVAL;
-
-	dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
-		vb->i, dev->width, dev->height, size, v4l2_field_names[field],
-		dev->fmt->name);
-	if (buf->vb.width  != dev->width  ||
-	    buf->vb.height != dev->height ||
-	    buf->vb.size   != size       ||
-	    buf->vb.field  != field      ||
-	    buf->fmt       != dev->fmt) {
-		saa7134_dma_free(q,buf);
-	}
 
 
-	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
-		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
-
-		buf->vb.width  = dev->width;
-		buf->vb.height = dev->height;
-		buf->vb.size   = size;
-		buf->vb.field  = field;
-		buf->fmt       = dev->fmt;
-		buf->pt        = &dev->pt_cap;
-		dev->video_q.curr = NULL;
-
-		err = videobuf_iolock(q,&buf->vb,&dev->ovbuf);
-		if (err)
-			goto oops;
-		err = saa7134_pgtable_build(dev->pci,buf->pt,
-					    dma->sglist,
-					    dma->sglen,
-					    saa7134_buffer_startpage(buf));
-		if (err)
-			goto oops;
-	}
-	buf->vb.state = VIDEOBUF_PREPARED;
-	buf->activate = buffer_activate;
+	*nbuffers = saa7134_buffer_count(size, *nbuffers);
+	*nplanes = 1;
+	sizes[0] = size;
 	return 0;
 	return 0;
-
- oops:
-	saa7134_dma_free(q,buf);
-	return err;
 }
 }
 
 
-static int
-buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
+/*
+ * move buffer to hardware queue
+ */
+void saa7134_vb2_buffer_queue(struct vb2_buffer *vb)
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
+	struct saa7134_dmaqueue *dmaq = vb->vb2_queue->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+	struct saa7134_buf *buf = container_of(vb, struct saa7134_buf, vb2);
 
 
-	*size = dev->fmt->depth * dev->width * dev->height >> 3;
-	if (0 == *count)
-		*count = gbuffers;
-	*count = saa7134_buffer_count(*size,*count);
-	return 0;
+	saa7134_buffer_queue(dev, dmaq, buf);
 }
 }
+EXPORT_SYMBOL_GPL(saa7134_vb2_buffer_queue);
 
 
-static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+int saa7134_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 {
-	struct saa7134_dev *dev = q->priv_data;
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
+	struct saa7134_dmaqueue *dmaq = vq->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+
+	/*
+	 * Planar video capture and TS share the same DMA channel,
+	 * so only one can be active at a time.
+	 */
+	if (card_is_empress(dev) && vb2_is_busy(&dev->empress_vbq) &&
+	    dmaq == &dev->video_q && dev->fmt->planar) {
+		struct saa7134_buf *buf, *tmp;
 
 
-	saa7134_buffer_queue(dev, &dev->video_q, buf);
+		list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) {
+			list_del(&buf->entry);
+			vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED);
+		}
+		if (dmaq->curr) {
+			vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED);
+			dmaq->curr = NULL;
+		}
+		return -EBUSY;
+	}
+
+	/* The SAA7134 has a 1K FIFO; the datasheet suggests that when
+	 * configured conservatively, there's 22 usec of buffering for video.
+	 * We therefore request a DMA latency of 20 usec, giving us 2 usec of
+	 * margin in case the FIFO is configured differently to the datasheet.
+	 * Unfortunately, I lack register-level documentation to check the
+	 * Linux FIFO setup and confirm the perfect value.
+	 */
+	if ((dmaq == &dev->video_q && !vb2_is_streaming(&dev->vbi_vbq)) ||
+	    (dmaq == &dev->vbi_q && !vb2_is_streaming(&dev->video_vbq)))
+		pm_qos_add_request(&dev->qos_request,
+			PM_QOS_CPU_DMA_LATENCY, 20);
+	dmaq->seq_nr = 0;
+
+	return 0;
 }
 }
 
 
-static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+void saa7134_vb2_stop_streaming(struct vb2_queue *vq)
 {
 {
-	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
+	struct saa7134_dmaqueue *dmaq = vq->drv_priv;
+	struct saa7134_dev *dev = dmaq->dev;
+
+	saa7134_stop_streaming(dev, dmaq);
 
 
-	saa7134_dma_free(q,buf);
+	if ((dmaq == &dev->video_q && !vb2_is_streaming(&dev->vbi_vbq)) ||
+	    (dmaq == &dev->vbi_q && !vb2_is_streaming(&dev->video_vbq)))
+		pm_qos_remove_request(&dev->qos_request);
 }
 }
 
 
-static struct videobuf_queue_ops video_qops = {
-	.buf_setup    = buffer_setup,
-	.buf_prepare  = buffer_prepare,
-	.buf_queue    = buffer_queue,
-	.buf_release  = buffer_release,
+static struct vb2_ops vb2_qops = {
+	.queue_setup	= queue_setup,
+	.buf_init	= buffer_init,
+	.buf_prepare	= buffer_prepare,
+	.buf_finish	= buffer_finish,
+	.buf_queue	= saa7134_vb2_buffer_queue,
+	.wait_prepare	= vb2_ops_wait_prepare,
+	.wait_finish	= vb2_ops_wait_finish,
+	.start_streaming = saa7134_vb2_start_streaming,
+	.stop_streaming = saa7134_vb2_stop_streaming,
 };
 };
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
@@ -1068,7 +1087,7 @@ static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl)
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	if (restart_overlay && res_locked(dev, RESOURCE_OVERLAY)) {
+	if (restart_overlay && dev->overlay_owner) {
 		spin_lock_irqsave(&dev->slock, flags);
 		spin_lock_irqsave(&dev->slock, flags);
 		stop_preview(dev);
 		stop_preview(dev);
 		start_preview(dev);
 		start_preview(dev);
@@ -1079,182 +1098,57 @@ static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl)
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
 
 
-static struct videobuf_queue *saa7134_queue(struct file *file)
+static inline struct vb2_queue *saa7134_queue(struct file *file)
 {
 {
-	struct video_device *vdev = video_devdata(file);
-	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh = file->private_data;
-	struct videobuf_queue *q = NULL;
-
-	switch (vdev->vfl_type) {
-	case VFL_TYPE_GRABBER:
-		q = fh->is_empress ? &dev->empress_tsq : &dev->cap;
-		break;
-	case VFL_TYPE_VBI:
-		q = &dev->vbi;
-		break;
-	default:
-		BUG();
-	}
-	return q;
-}
-
-static int saa7134_resource(struct file *file)
-{
-	struct video_device *vdev = video_devdata(file);
-	struct saa7134_fh *fh = file->private_data;
-
-	if (vdev->vfl_type == VFL_TYPE_GRABBER)
-		return fh->is_empress ? RESOURCE_EMPRESS : RESOURCE_VIDEO;
-
-	if (vdev->vfl_type == VFL_TYPE_VBI)
-		return RESOURCE_VBI;
-
-	BUG();
-	return 0;
+	return video_devdata(file)->queue;
 }
 }
 
 
 static int video_open(struct file *file)
 static int video_open(struct file *file)
 {
 {
 	struct video_device *vdev = video_devdata(file);
 	struct video_device *vdev = video_devdata(file);
 	struct saa7134_dev *dev = video_drvdata(file);
 	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh;
-
-	/* allocate + initialize per filehandle data */
-	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
-	if (NULL == fh)
-		return -ENOMEM;
+	int ret = v4l2_fh_open(file);
 
 
-	v4l2_fh_init(&fh->fh, vdev);
-	file->private_data = fh;
+	if (ret < 0)
+		return ret;
 
 
+	mutex_lock(&dev->lock);
 	if (vdev->vfl_type == VFL_TYPE_RADIO) {
 	if (vdev->vfl_type == VFL_TYPE_RADIO) {
 		/* switch to radio mode */
 		/* switch to radio mode */
-		saa7134_tvaudio_setinput(dev,&card(dev).radio);
+		saa7134_tvaudio_setinput(dev, &card(dev).radio);
 		saa_call_all(dev, tuner, s_radio);
 		saa_call_all(dev, tuner, s_radio);
 	} else {
 	} else {
 		/* switch to video/vbi mode */
 		/* switch to video/vbi mode */
-		video_mux(dev,dev->ctl_input);
+		video_mux(dev, dev->ctl_input);
 	}
 	}
-	v4l2_fh_add(&fh->fh);
+	mutex_unlock(&dev->lock);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static ssize_t
-video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
-{
-	struct video_device *vdev = video_devdata(file);
-	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh = file->private_data;
-
-	switch (vdev->vfl_type) {
-	case VFL_TYPE_GRABBER:
-		if (res_locked(dev, RESOURCE_VIDEO))
-			return -EBUSY;
-		return videobuf_read_one(saa7134_queue(file),
-					 data, count, ppos,
-					 file->f_flags & O_NONBLOCK);
-	case VFL_TYPE_VBI:
-		if (!res_get(dev, fh, RESOURCE_VBI))
-			return -EBUSY;
-		return videobuf_read_stream(saa7134_queue(file),
-					    data, count, ppos, 1,
-					    file->f_flags & O_NONBLOCK);
-		break;
-	default:
-		BUG();
-		return 0;
-	}
-}
-
-static unsigned int
-video_poll(struct file *file, struct poll_table_struct *wait)
-{
-	unsigned long req_events = poll_requested_events(wait);
-	struct video_device *vdev = video_devdata(file);
-	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh = file->private_data;
-	struct videobuf_buffer *buf = NULL;
-	unsigned int rc = 0;
-
-	if (v4l2_event_pending(&fh->fh))
-		rc = POLLPRI;
-	else if (req_events & POLLPRI)
-		poll_wait(file, &fh->fh.wait, wait);
-
-	if (vdev->vfl_type == VFL_TYPE_VBI)
-		return rc | videobuf_poll_stream(file, &dev->vbi, wait);
-
-	if (res_check(fh, RESOURCE_VIDEO)) {
-		mutex_lock(&dev->cap.vb_lock);
-		if (!list_empty(&dev->cap.stream))
-			buf = list_entry(dev->cap.stream.next, struct videobuf_buffer, stream);
-	} else {
-		mutex_lock(&dev->cap.vb_lock);
-		if (UNSET == dev->cap.read_off) {
-			/* need to capture a new frame */
-			if (res_locked(dev, RESOURCE_VIDEO))
-				goto err;
-			if (0 != dev->cap.ops->buf_prepare(&dev->cap,
-					dev->cap.read_buf, dev->cap.field))
-				goto err;
-			dev->cap.ops->buf_queue(&dev->cap, dev->cap.read_buf);
-			dev->cap.read_off = 0;
-		}
-		buf = dev->cap.read_buf;
-	}
-
-	if (!buf)
-		goto err;
-
-	poll_wait(file, &buf->done, wait);
-	if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR)
-		rc |= POLLIN | POLLRDNORM;
-	mutex_unlock(&dev->cap.vb_lock);
-	return rc;
-
-err:
-	mutex_unlock(&dev->cap.vb_lock);
-	return rc | POLLERR;
-}
-
 static int video_release(struct file *file)
 static int video_release(struct file *file)
 {
 {
 	struct video_device *vdev = video_devdata(file);
 	struct video_device *vdev = video_devdata(file);
 	struct saa7134_dev *dev = video_drvdata(file);
 	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh = file->private_data;
+	struct v4l2_fh *fh = file->private_data;
 	struct saa6588_command cmd;
 	struct saa6588_command cmd;
 	unsigned long flags;
 	unsigned long flags;
 
 
+	mutex_lock(&dev->lock);
 	saa7134_tvaudio_close(dev);
 	saa7134_tvaudio_close(dev);
 
 
 	/* turn off overlay */
 	/* turn off overlay */
-	if (res_check(fh, RESOURCE_OVERLAY)) {
+	if (fh == dev->overlay_owner) {
 		spin_lock_irqsave(&dev->slock,flags);
 		spin_lock_irqsave(&dev->slock,flags);
 		stop_preview(dev);
 		stop_preview(dev);
 		spin_unlock_irqrestore(&dev->slock,flags);
 		spin_unlock_irqrestore(&dev->slock,flags);
-		res_free(dev, fh, RESOURCE_OVERLAY);
-	}
-
-	/* stop video capture */
-	if (res_check(fh, RESOURCE_VIDEO)) {
-		pm_qos_remove_request(&dev->qos_request);
-		videobuf_streamoff(&dev->cap);
-		res_free(dev, fh, RESOURCE_VIDEO);
-		videobuf_mmap_free(&dev->cap);
-	}
-	if (dev->cap.read_buf) {
-		buffer_release(&dev->cap, dev->cap.read_buf);
-		kfree(dev->cap.read_buf);
+		dev->overlay_owner = NULL;
 	}
 	}
 
 
-	/* stop vbi capture */
-	if (res_check(fh, RESOURCE_VBI)) {
-		videobuf_stop(&dev->vbi);
-		res_free(dev, fh, RESOURCE_VBI);
-		videobuf_mmap_free(&dev->vbi);
-	}
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
+		v4l2_fh_release(file);
+	else
+		_vb2_fop_release(file, NULL);
 
 
 	/* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
 	/* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
 	saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0);
 	saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0);
@@ -1265,19 +1159,11 @@ static int video_release(struct file *file)
 	saa_call_all(dev, core, s_power, 0);
 	saa_call_all(dev, core, s_power, 0);
 	if (vdev->vfl_type == VFL_TYPE_RADIO)
 	if (vdev->vfl_type == VFL_TYPE_RADIO)
 		saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
 		saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
+	mutex_unlock(&dev->lock);
 
 
-	v4l2_fh_del(&fh->fh);
-	v4l2_fh_exit(&fh->fh);
-	file->private_data = NULL;
-	kfree(fh);
 	return 0;
 	return 0;
 }
 }
 
 
-static int video_mmap(struct file *file, struct vm_area_struct * vma)
-{
-	return videobuf_mmap_mapper(saa7134_queue(file), vma);
-}
-
 static ssize_t radio_read(struct file *file, char __user *data,
 static ssize_t radio_read(struct file *file, char __user *data,
 			 size_t count, loff_t *ppos)
 			 size_t count, loff_t *ppos)
 {
 {
@@ -1290,7 +1176,9 @@ static ssize_t radio_read(struct file *file, char __user *data,
 	cmd.instance = file;
 	cmd.instance = file;
 	cmd.result = -ENODEV;
 	cmd.result = -ENODEV;
 
 
+	mutex_lock(&dev->lock);
 	saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd);
 	saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd);
+	mutex_unlock(&dev->lock);
 
 
 	return cmd.result;
 	return cmd.result;
 }
 }
@@ -1304,7 +1192,9 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)
 	cmd.instance = file;
 	cmd.instance = file;
 	cmd.event_list = wait;
 	cmd.event_list = wait;
 	cmd.result = 0;
 	cmd.result = 0;
+	mutex_lock(&dev->lock);
 	saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
 	saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd);
+	mutex_unlock(&dev->lock);
 
 
 	return rc | cmd.result;
 	return rc | cmd.result;
 }
 }
@@ -1338,7 +1228,7 @@ static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
 
 
 	f->fmt.pix.width        = dev->width;
 	f->fmt.pix.width        = dev->width;
 	f->fmt.pix.height       = dev->height;
 	f->fmt.pix.height       = dev->height;
-	f->fmt.pix.field        = dev->cap.field;
+	f->fmt.pix.field        = dev->field;
 	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
 	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
 	f->fmt.pix.bytesperline =
 	f->fmt.pix.bytesperline =
 		(f->fmt.pix.width * dev->fmt->depth) >> 3;
 		(f->fmt.pix.width * dev->fmt->depth) >> 3;
@@ -1362,7 +1252,6 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
 		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
 		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	mutex_lock(&dev->lock);
 	f->fmt.win = dev->win;
 	f->fmt.win = dev->win;
 	f->fmt.win.clips = clips;
 	f->fmt.win.clips = clips;
 	if (clips == NULL)
 	if (clips == NULL)
@@ -1376,7 +1265,6 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
 					sizeof(struct v4l2_rect)))
 					sizeof(struct v4l2_rect)))
 			err = -EFAULT;
 			err = -EFAULT;
 	}
 	}
-	mutex_unlock(&dev->lock);
 
 
 	return err;
 	return err;
 }
 }
@@ -1457,10 +1345,10 @@ static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
 	if (0 != err)
 	if (0 != err)
 		return err;
 		return err;
 
 
-	dev->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);
-	dev->width     = f->fmt.pix.width;
-	dev->height    = f->fmt.pix.height;
-	dev->cap.field = f->fmt.pix.field;
+	dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	dev->width = f->fmt.pix.width;
+	dev->height = f->fmt.pix.height;
+	dev->field = f->fmt.pix.field;
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1481,25 +1369,20 @@ static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,
 	if (0 != err)
 	if (0 != err)
 		return err;
 		return err;
 
 
-	mutex_lock(&dev->lock);
-
 	dev->win    = f->fmt.win;
 	dev->win    = f->fmt.win;
 	dev->nclips = f->fmt.win.clipcount;
 	dev->nclips = f->fmt.win.clipcount;
 
 
 	if (copy_from_user(dev->clips, f->fmt.win.clips,
 	if (copy_from_user(dev->clips, f->fmt.win.clips,
-			   sizeof(struct v4l2_clip) * dev->nclips)) {
-		mutex_unlock(&dev->lock);
+			   sizeof(struct v4l2_clip) * dev->nclips))
 		return -EFAULT;
 		return -EFAULT;
-	}
 
 
-	if (res_check(priv, RESOURCE_OVERLAY)) {
+	if (priv == dev->overlay_owner) {
 		spin_lock_irqsave(&dev->slock, flags);
 		spin_lock_irqsave(&dev->slock, flags);
 		stop_preview(dev);
 		stop_preview(dev);
 		start_preview(dev);
 		start_preview(dev);
 		spin_unlock_irqrestore(&dev->slock, flags);
 		spin_unlock_irqrestore(&dev->slock, flags);
 	}
 	}
 
 
-	mutex_unlock(&dev->lock);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1551,9 +1434,7 @@ int saa7134_s_input(struct file *file, void *priv, unsigned int i)
 		return -EINVAL;
 		return -EINVAL;
 	if (NULL == card_in(dev, i).name)
 	if (NULL == card_in(dev, i).name)
 		return -EINVAL;
 		return -EINVAL;
-	mutex_lock(&dev->lock);
 	video_mux(dev, i);
 	video_mux(dev, i);
-	mutex_unlock(&dev->lock);
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(saa7134_s_input);
 EXPORT_SYMBOL_GPL(saa7134_s_input);
@@ -1563,7 +1444,6 @@ int saa7134_querycap(struct file *file, void *priv,
 {
 {
 	struct saa7134_dev *dev = video_drvdata(file);
 	struct saa7134_dev *dev = video_drvdata(file);
 	struct video_device *vdev = video_devdata(file);
 	struct video_device *vdev = video_devdata(file);
-	struct saa7134_fh *fh = priv;
 	u32 radio_caps, video_caps, vbi_caps;
 	u32 radio_caps, video_caps, vbi_caps;
 
 
 	unsigned int tuner_type = dev->tuner_type;
 	unsigned int tuner_type = dev->tuner_type;
@@ -1582,7 +1462,7 @@ int saa7134_querycap(struct file *file, void *priv,
 		radio_caps |= V4L2_CAP_RDS_CAPTURE;
 		radio_caps |= V4L2_CAP_RDS_CAPTURE;
 
 
 	video_caps = V4L2_CAP_VIDEO_CAPTURE;
 	video_caps = V4L2_CAP_VIDEO_CAPTURE;
-	if (saa7134_no_overlay <= 0 && !fh->is_empress)
+	if (saa7134_no_overlay <= 0 && !is_empress(file))
 		video_caps |= V4L2_CAP_VIDEO_OVERLAY;
 		video_caps |= V4L2_CAP_VIDEO_OVERLAY;
 
 
 	vbi_caps = V4L2_CAP_VBI_CAPTURE;
 	vbi_caps = V4L2_CAP_VBI_CAPTURE;
@@ -1613,12 +1493,12 @@ EXPORT_SYMBOL_GPL(saa7134_querycap);
 int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id)
 int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id)
 {
 {
 	struct saa7134_dev *dev = video_drvdata(file);
 	struct saa7134_dev *dev = video_drvdata(file);
-	struct saa7134_fh *fh = priv;
+	struct v4l2_fh *fh = priv;
 	unsigned long flags;
 	unsigned long flags;
 	unsigned int i;
 	unsigned int i;
 	v4l2_std_id fixup;
 	v4l2_std_id fixup;
 
 
-	if (fh->is_empress && res_locked(dev, RESOURCE_OVERLAY)) {
+	if (is_empress(file) && dev->overlay_owner) {
 		/* Don't change the std from the mpeg device
 		/* Don't change the std from the mpeg device
 		   if overlay is active. */
 		   if overlay is active. */
 		return -EBUSY;
 		return -EBUSY;
@@ -1657,8 +1537,7 @@ int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id)
 
 
 	id = tvnorms[i].id;
 	id = tvnorms[i].id;
 
 
-	mutex_lock(&dev->lock);
-	if (!fh->is_empress && res_check(fh, RESOURCE_OVERLAY)) {
+	if (!is_empress(file) && fh == dev->overlay_owner) {
 		spin_lock_irqsave(&dev->slock, flags);
 		spin_lock_irqsave(&dev->slock, flags);
 		stop_preview(dev);
 		stop_preview(dev);
 		spin_unlock_irqrestore(&dev->slock, flags);
 		spin_unlock_irqrestore(&dev->slock, flags);
@@ -1672,7 +1551,6 @@ int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id)
 		set_tvnorm(dev, &tvnorms[i]);
 		set_tvnorm(dev, &tvnorms[i]);
 
 
 	saa7134_tvaudio_do_scan(dev);
 	saa7134_tvaudio_do_scan(dev);
-	mutex_unlock(&dev->lock);
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(saa7134_s_std);
 EXPORT_SYMBOL_GPL(saa7134_s_std);
@@ -1686,6 +1564,35 @@ int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id)
 }
 }
 EXPORT_SYMBOL_GPL(saa7134_g_std);
 EXPORT_SYMBOL_GPL(saa7134_g_std);
 
 
+static v4l2_std_id saa7134_read_std(struct saa7134_dev *dev)
+{
+	static v4l2_std_id stds[] = {
+		V4L2_STD_UNKNOWN,
+		V4L2_STD_NTSC,
+		V4L2_STD_PAL,
+		V4L2_STD_SECAM };
+
+	v4l2_std_id result = 0;
+
+	u8 st1 = saa_readb(SAA7134_STATUS_VIDEO1);
+	u8 st2 = saa_readb(SAA7134_STATUS_VIDEO2);
+
+	if (!(st2 & 0x1)) /* RDCAP == 0 */
+		result = V4L2_STD_UNKNOWN;
+	else
+		result = stds[st1 & 0x03];
+
+	return result;
+}
+
+int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std)
+{
+	struct saa7134_dev *dev = video_drvdata(file);
+	*std &= saa7134_read_std(dev);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(saa7134_querystd);
+
 static int saa7134_cropcap(struct file *file, void *priv,
 static int saa7134_cropcap(struct file *file, void *priv,
 					struct v4l2_cropcap *cap)
 					struct v4l2_cropcap *cap)
 {
 {
@@ -1730,9 +1637,9 @@ static int saa7134_s_crop(struct file *file, void *f, const struct v4l2_crop *cr
 	    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
 	    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (res_locked(dev, RESOURCE_OVERLAY))
+	if (dev->overlay_owner)
 		return -EBUSY;
 		return -EBUSY;
-	if (res_locked(dev, RESOURCE_VIDEO))
+	if (vb2_is_streaming(&dev->video_vbq))
 		return -EBUSY;
 		return -EBUSY;
 
 
 	*c = crop->c;
 	*c = crop->c;
@@ -1826,12 +1733,10 @@ int saa7134_s_frequency(struct file *file, void *priv,
 
 
 	if (0 != f->tuner)
 	if (0 != f->tuner)
 		return -EINVAL;
 		return -EINVAL;
-	mutex_lock(&dev->lock);
 
 
 	saa_call_all(dev, tuner, s_frequency, f);
 	saa_call_all(dev, tuner, s_frequency, f);
 
 
 	saa7134_tvaudio_do_scan(dev);
 	saa7134_tvaudio_do_scan(dev);
-	mutex_unlock(&dev->lock);
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(saa7134_s_frequency);
 EXPORT_SYMBOL_GPL(saa7134_s_frequency);
@@ -1915,92 +1820,24 @@ static int saa7134_overlay(struct file *file, void *priv, unsigned int on)
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 
 
-		if (!res_get(dev, priv, RESOURCE_OVERLAY))
+		if (dev->overlay_owner && priv != dev->overlay_owner)
 			return -EBUSY;
 			return -EBUSY;
+		dev->overlay_owner = priv;
 		spin_lock_irqsave(&dev->slock, flags);
 		spin_lock_irqsave(&dev->slock, flags);
 		start_preview(dev);
 		start_preview(dev);
 		spin_unlock_irqrestore(&dev->slock, flags);
 		spin_unlock_irqrestore(&dev->slock, flags);
 	}
 	}
 	if (!on) {
 	if (!on) {
-		if (!res_check(priv, RESOURCE_OVERLAY))
+		if (priv != dev->overlay_owner)
 			return -EINVAL;
 			return -EINVAL;
 		spin_lock_irqsave(&dev->slock, flags);
 		spin_lock_irqsave(&dev->slock, flags);
 		stop_preview(dev);
 		stop_preview(dev);
 		spin_unlock_irqrestore(&dev->slock, flags);
 		spin_unlock_irqrestore(&dev->slock, flags);
-		res_free(dev, priv, RESOURCE_OVERLAY);
+		dev->overlay_owner = NULL;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
-int saa7134_reqbufs(struct file *file, void *priv,
-					struct v4l2_requestbuffers *p)
-{
-	return videobuf_reqbufs(saa7134_queue(file), p);
-}
-EXPORT_SYMBOL_GPL(saa7134_reqbufs);
-
-int saa7134_querybuf(struct file *file, void *priv,
-					struct v4l2_buffer *b)
-{
-	return videobuf_querybuf(saa7134_queue(file), b);
-}
-EXPORT_SYMBOL_GPL(saa7134_querybuf);
-
-int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
-	return videobuf_qbuf(saa7134_queue(file), b);
-}
-EXPORT_SYMBOL_GPL(saa7134_qbuf);
-
-int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
-	return videobuf_dqbuf(saa7134_queue(file), b,
-				file->f_flags & O_NONBLOCK);
-}
-EXPORT_SYMBOL_GPL(saa7134_dqbuf);
-
-int saa7134_streamon(struct file *file, void *priv,
-					enum v4l2_buf_type type)
-{
-	struct saa7134_dev *dev = video_drvdata(file);
-	int res = saa7134_resource(file);
-
-	if (!res_get(dev, priv, res))
-		return -EBUSY;
-
-	/* The SAA7134 has a 1K FIFO; the datasheet suggests that when
-	 * configured conservatively, there's 22 usec of buffering for video.
-	 * We therefore request a DMA latency of 20 usec, giving us 2 usec of
-	 * margin in case the FIFO is configured differently to the datasheet.
-	 * Unfortunately, I lack register-level documentation to check the
-	 * Linux FIFO setup and confirm the perfect value.
-	 */
-	if (res != RESOURCE_EMPRESS)
-		pm_qos_add_request(&dev->qos_request,
-			   PM_QOS_CPU_DMA_LATENCY, 20);
-
-	return videobuf_streamon(saa7134_queue(file));
-}
-EXPORT_SYMBOL_GPL(saa7134_streamon);
-
-int saa7134_streamoff(struct file *file, void *priv,
-					enum v4l2_buf_type type)
-{
-	struct saa7134_dev *dev = video_drvdata(file);
-	int err;
-	int res = saa7134_resource(file);
-
-	if (res != RESOURCE_EMPRESS)
-		pm_qos_remove_request(&dev->qos_request);
-
-	err = videobuf_streamoff(saa7134_queue(file));
-	if (err < 0)
-		return err;
-	res_free(dev, priv, res);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(saa7134_streamoff);
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vidioc_g_register (struct file *file, void *priv,
 static int vidioc_g_register (struct file *file, void *priv,
 			      struct v4l2_dbg_register *reg)
 			      struct v4l2_dbg_register *reg)
@@ -2058,10 +1895,10 @@ static const struct v4l2_file_operations video_fops =
 	.owner	  = THIS_MODULE,
 	.owner	  = THIS_MODULE,
 	.open	  = video_open,
 	.open	  = video_open,
 	.release  = video_release,
 	.release  = video_release,
-	.read	  = video_read,
-	.poll     = video_poll,
-	.mmap	  = video_mmap,
-	.ioctl	  = video_ioctl2,
+	.read	  = vb2_fop_read,
+	.poll     = vb2_fop_poll,
+	.mmap	  = vb2_fop_mmap,
+	.unlocked_ioctl	  = video_ioctl2,
 };
 };
 
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -2078,17 +1915,18 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_try_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap,
 	.vidioc_try_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap,
 	.vidioc_s_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap,
 	.vidioc_s_fmt_vbi_cap		= saa7134_try_get_set_fmt_vbi_cap,
 	.vidioc_cropcap			= saa7134_cropcap,
 	.vidioc_cropcap			= saa7134_cropcap,
-	.vidioc_reqbufs			= saa7134_reqbufs,
-	.vidioc_querybuf		= saa7134_querybuf,
-	.vidioc_qbuf			= saa7134_qbuf,
-	.vidioc_dqbuf			= saa7134_dqbuf,
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
 	.vidioc_s_std			= saa7134_s_std,
 	.vidioc_s_std			= saa7134_s_std,
 	.vidioc_g_std			= saa7134_g_std,
 	.vidioc_g_std			= saa7134_g_std,
+	.vidioc_querystd		= saa7134_querystd,
 	.vidioc_enum_input		= saa7134_enum_input,
 	.vidioc_enum_input		= saa7134_enum_input,
 	.vidioc_g_input			= saa7134_g_input,
 	.vidioc_g_input			= saa7134_g_input,
 	.vidioc_s_input			= saa7134_s_input,
 	.vidioc_s_input			= saa7134_s_input,
-	.vidioc_streamon		= saa7134_streamon,
-	.vidioc_streamoff		= saa7134_streamoff,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
 	.vidioc_g_tuner			= saa7134_g_tuner,
 	.vidioc_g_tuner			= saa7134_g_tuner,
 	.vidioc_s_tuner			= saa7134_s_tuner,
 	.vidioc_s_tuner			= saa7134_s_tuner,
 	.vidioc_g_crop			= saa7134_g_crop,
 	.vidioc_g_crop			= saa7134_g_crop,
@@ -2112,7 +1950,7 @@ static const struct v4l2_file_operations radio_fops = {
 	.open	  = video_open,
 	.open	  = video_open,
 	.read     = radio_read,
 	.read     = radio_read,
 	.release  = video_release,
 	.release  = video_release,
-	.ioctl	  = video_ioctl2,
+	.unlocked_ioctl	= video_ioctl2,
 	.poll     = radio_poll,
 	.poll     = radio_poll,
 };
 };
 
 
@@ -2190,6 +2028,8 @@ static const struct v4l2_ctrl_config saa7134_ctrl_automute = {
 int saa7134_video_init1(struct saa7134_dev *dev)
 int saa7134_video_init1(struct saa7134_dev *dev)
 {
 {
 	struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
 	struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
+	struct vb2_queue *q;
+	int ret;
 
 
 	/* sanitycheck insmod options */
 	/* sanitycheck insmod options */
 	if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
 	if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
@@ -2241,6 +2081,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
 	dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
 	dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
 	dev->width    = 720;
 	dev->width    = 720;
 	dev->height   = 576;
 	dev->height   = 576;
+	dev->field = V4L2_FIELD_INTERLACED;
 	dev->win.w.width = dev->width;
 	dev->win.w.width = dev->width;
 	dev->win.w.height = dev->height;
 	dev->win.w.height = dev->height;
 	dev->win.field = V4L2_FIELD_INTERLACED;
 	dev->win.field = V4L2_FIELD_INTERLACED;
@@ -2252,20 +2093,47 @@ int saa7134_video_init1(struct saa7134_dev *dev)
 	if (saa7134_boards[dev->board].video_out)
 	if (saa7134_boards[dev->board].video_out)
 		saa7134_videoport_init(dev);
 		saa7134_videoport_init(dev);
 
 
-	videobuf_queue_sg_init(&dev->cap, &video_qops,
-			    &dev->pci->dev, &dev->slock,
-			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			    V4L2_FIELD_INTERLACED,
-			    sizeof(struct saa7134_buf),
-			    dev, NULL);
-	videobuf_queue_sg_init(&dev->vbi, &saa7134_vbi_qops,
-			    &dev->pci->dev, &dev->slock,
-			    V4L2_BUF_TYPE_VBI_CAPTURE,
-			    V4L2_FIELD_SEQ_TB,
-			    sizeof(struct saa7134_buf),
-			    dev, NULL);
-	saa7134_pgtable_alloc(dev->pci, &dev->pt_cap);
-	saa7134_pgtable_alloc(dev->pci, &dev->pt_vbi);
+	q = &dev->video_vbq;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	/*
+	 * Do not add VB2_USERPTR unless explicitly requested: the saa7134 DMA
+	 * engine cannot handle transfers that do not start at the beginning
+	 * of a page. A user-provided pointer can start anywhere in a page, so
+	 * USERPTR support is a no-go unless the application knows about these
+	 * limitations and has special support for this.
+	 */
+	q->io_modes = VB2_MMAP | VB2_READ;
+	if (saa7134_userptr)
+		q->io_modes |= VB2_USERPTR;
+	q->drv_priv = &dev->video_q;
+	q->ops = &vb2_qops;
+	q->gfp_flags = GFP_DMA32;
+	q->mem_ops = &vb2_dma_sg_memops;
+	q->buf_struct_size = sizeof(struct saa7134_buf);
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->lock;
+	ret = vb2_queue_init(q);
+	if (ret)
+		return ret;
+	saa7134_pgtable_alloc(dev->pci, &dev->video_q.pt);
+
+	q = &dev->vbi_vbq;
+	q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+	/* Don't add VB2_USERPTR, see comment above */
+	q->io_modes = VB2_MMAP | VB2_READ;
+	if (saa7134_userptr)
+		q->io_modes |= VB2_USERPTR;
+	q->drv_priv = &dev->vbi_q;
+	q->ops = &saa7134_vbi_qops;
+	q->gfp_flags = GFP_DMA32;
+	q->mem_ops = &vb2_dma_sg_memops;
+	q->buf_struct_size = sizeof(struct saa7134_buf);
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->lock;
+	ret = vb2_queue_init(q);
+	if (ret)
+		return ret;
+	saa7134_pgtable_alloc(dev->pci, &dev->vbi_q.pt);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -2273,8 +2141,10 @@ int saa7134_video_init1(struct saa7134_dev *dev)
 void saa7134_video_fini(struct saa7134_dev *dev)
 void saa7134_video_fini(struct saa7134_dev *dev)
 {
 {
 	/* free stuff */
 	/* free stuff */
-	saa7134_pgtable_free(dev->pci, &dev->pt_cap);
-	saa7134_pgtable_free(dev->pci, &dev->pt_vbi);
+	vb2_queue_release(&dev->video_vbq);
+	saa7134_pgtable_free(dev->pci, &dev->video_q.pt);
+	vb2_queue_release(&dev->vbi_vbq);
+	saa7134_pgtable_free(dev->pci, &dev->vbi_q.pt);
 	v4l2_ctrl_handler_free(&dev->ctrl_handler);
 	v4l2_ctrl_handler_free(&dev->ctrl_handler);
 	if (card_has_radio(dev))
 	if (card_has_radio(dev))
 		v4l2_ctrl_handler_free(&dev->radio_ctrl_handler);
 		v4l2_ctrl_handler_free(&dev->radio_ctrl_handler);
@@ -2367,8 +2237,7 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
 
 
 	spin_lock(&dev->slock);
 	spin_lock(&dev->slock);
 	if (dev->video_q.curr) {
 	if (dev->video_q.curr) {
-		dev->video_fieldcount++;
-		field = dev->video_q.curr->vb.field;
+		field = dev->field;
 		if (V4L2_FIELD_HAS_BOTH(field)) {
 		if (V4L2_FIELD_HAS_BOTH(field)) {
 			/* make sure we have seen both fields */
 			/* make sure we have seen both fields */
 			if ((status & 0x10) == 0x00) {
 			if ((status & 0x10) == 0x00) {
@@ -2384,18 +2253,10 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
 			if ((status & 0x10) != 0x00)
 			if ((status & 0x10) != 0x00)
 				goto done;
 				goto done;
 		}
 		}
-		dev->video_q.curr->vb.field_count = dev->video_fieldcount;
-		saa7134_buffer_finish(dev,&dev->video_q,VIDEOBUF_DONE);
+		saa7134_buffer_finish(dev, &dev->video_q, VB2_BUF_STATE_DONE);
 	}
 	}
-	saa7134_buffer_next(dev,&dev->video_q);
+	saa7134_buffer_next(dev, &dev->video_q);
 
 
  done:
  done:
 	spin_unlock(&dev->slock);
 	spin_unlock(&dev->slock);
 }
 }
-
-/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */

+ 53 - 55
drivers/media/pci/saa7134/saa7134.h

@@ -41,11 +41,11 @@
 #include <media/tuner.h>
 #include <media/tuner.h>
 #include <media/rc-core.h>
 #include <media/rc-core.h>
 #include <media/ir-kbd-i2c.h>
 #include <media/ir-kbd-i2c.h>
-#include <media/videobuf-dma-sg.h>
+#include <media/videobuf2-dma-sg.h>
 #include <sound/core.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm.h>
 #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)
 #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)
-#include <media/videobuf-dvb.h>
+#include <media/videobuf2-dvb.h>
 #endif
 #endif
 #include "tda8290.h"
 #include "tda8290.h"
 
 
@@ -453,17 +453,15 @@ struct saa7134_thread {
 /* buffer for one video/vbi/ts frame */
 /* buffer for one video/vbi/ts frame */
 struct saa7134_buf {
 struct saa7134_buf {
 	/* common v4l buffer stuff -- must be first */
 	/* common v4l buffer stuff -- must be first */
-	struct videobuf_buffer vb;
+	struct vb2_buffer vb2;
 
 
 	/* saa7134 specific */
 	/* saa7134 specific */
-	struct saa7134_format   *fmt;
 	unsigned int            top_seen;
 	unsigned int            top_seen;
 	int (*activate)(struct saa7134_dev *dev,
 	int (*activate)(struct saa7134_dev *dev,
 			struct saa7134_buf *buf,
 			struct saa7134_buf *buf,
 			struct saa7134_buf *next);
 			struct saa7134_buf *next);
 
 
-	/* page tables */
-	struct saa7134_pgtable  *pt;
+	struct list_head	entry;
 };
 };
 
 
 struct saa7134_dmaqueue {
 struct saa7134_dmaqueue {
@@ -472,13 +470,8 @@ struct saa7134_dmaqueue {
 	struct list_head           queue;
 	struct list_head           queue;
 	struct timer_list          timeout;
 	struct timer_list          timeout;
 	unsigned int               need_two;
 	unsigned int               need_two;
-};
-
-/* video filehandle status */
-struct saa7134_fh {
-	struct v4l2_fh             fh;
-	bool			   is_empress;
-	unsigned int               resources;
+	unsigned int               seq_nr;
+	struct saa7134_pgtable     pt;
 };
 };
 
 
 /* dmasound dsp status */
 /* dmasound dsp status */
@@ -504,7 +497,10 @@ struct saa7134_dmasound {
 	unsigned int               blksize;
 	unsigned int               blksize;
 	unsigned int               bufsize;
 	unsigned int               bufsize;
 	struct saa7134_pgtable     pt;
 	struct saa7134_pgtable     pt;
-	struct videobuf_dmabuf     dma;
+	void			   *vaddr;
+	struct scatterlist	   *sglist;
+	int                        sglen;
+	int                        nr_pages;
 	unsigned int               dma_blk;
 	unsigned int               dma_blk;
 	unsigned int               read_offset;
 	unsigned int               read_offset;
 	unsigned int               read_count;
 	unsigned int               read_count;
@@ -515,7 +511,6 @@ struct saa7134_dmasound {
 /* ts/mpeg status */
 /* ts/mpeg status */
 struct saa7134_ts {
 struct saa7134_ts {
 	/* TS capture */
 	/* TS capture */
-	struct saa7134_pgtable     pt_ts;
 	int                        nr_packets;
 	int                        nr_packets;
 	int                        nr_bufs;
 	int                        nr_bufs;
 };
 };
@@ -584,21 +579,35 @@ struct saa7134_dev {
 	struct v4l2_window         win;
 	struct v4l2_window         win;
 	struct v4l2_clip           clips[8];
 	struct v4l2_clip           clips[8];
 	unsigned int               nclips;
 	unsigned int               nclips;
+	struct v4l2_fh		   *overlay_owner;
 
 
 
 
 	/* video+ts+vbi capture */
 	/* video+ts+vbi capture */
 	struct saa7134_dmaqueue    video_q;
 	struct saa7134_dmaqueue    video_q;
-	struct videobuf_queue      cap;
-	struct saa7134_pgtable     pt_cap;
+	struct vb2_queue           video_vbq;
 	struct saa7134_dmaqueue    vbi_q;
 	struct saa7134_dmaqueue    vbi_q;
-	struct videobuf_queue      vbi;
-	struct saa7134_pgtable     pt_vbi;
-	unsigned int               video_fieldcount;
-	unsigned int               vbi_fieldcount;
+	struct vb2_queue           vbi_vbq;
+	enum v4l2_field		   field;
 	struct saa7134_format      *fmt;
 	struct saa7134_format      *fmt;
 	unsigned int               width, height;
 	unsigned int               width, height;
+	unsigned int               vbi_hlen, vbi_vlen;
 	struct pm_qos_request	   qos_request;
 	struct pm_qos_request	   qos_request;
 
 
+	/* SAA7134_MPEG_* */
+	struct saa7134_ts          ts;
+	struct saa7134_dmaqueue    ts_q;
+	enum v4l2_field		   ts_field;
+	int                        ts_started;
+	struct saa7134_mpeg_ops    *mops;
+
+	/* SAA7134_MPEG_EMPRESS only */
+	struct video_device        *empress_dev;
+	struct v4l2_subdev	   *empress_sd;
+	struct vb2_queue           empress_vbq;
+	struct work_struct         empress_workqueue;
+	int                        empress_started;
+	struct v4l2_ctrl_handler   empress_ctrl_handler;
+
 	/* various v4l controls */
 	/* various v4l controls */
 	struct saa7134_tvnorm      *tvnorm;              /* video */
 	struct saa7134_tvnorm      *tvnorm;              /* video */
 	struct saa7134_tvaudio     *tvaudio;
 	struct saa7134_tvaudio     *tvaudio;
@@ -635,23 +644,9 @@ struct saa7134_dev {
 	/* I2C keyboard data */
 	/* I2C keyboard data */
 	struct IR_i2c_init_data    init_data;
 	struct IR_i2c_init_data    init_data;
 
 
-	/* SAA7134_MPEG_* */
-	struct saa7134_ts          ts;
-	struct saa7134_dmaqueue    ts_q;
-	int                        ts_started;
-	struct saa7134_mpeg_ops    *mops;
-
-	/* SAA7134_MPEG_EMPRESS only */
-	struct video_device        *empress_dev;
-	struct v4l2_subdev	   *empress_sd;
-	struct videobuf_queue      empress_tsq;
-	struct work_struct         empress_workqueue;
-	int                        empress_started;
-	struct v4l2_ctrl_handler   empress_ctrl_handler;
-
 #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)
 #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB)
 	/* SAA7134_MPEG_DVB only */
 	/* SAA7134_MPEG_DVB only */
-	struct videobuf_dvb_frontends frontends;
+	struct vb2_dvb_frontends frontends;
 	int (*original_demod_sleep)(struct dvb_frontend *fe);
 	int (*original_demod_sleep)(struct dvb_frontend *fe);
 	int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
 	int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
 	int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
 	int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
@@ -705,14 +700,12 @@ struct saa7134_dev {
 	_rc;								\
 	_rc;								\
 })
 })
 
 
-static inline int res_check(struct saa7134_fh *fh, unsigned int bit)
+static inline bool is_empress(struct file *file)
 {
 {
-	return fh->resources & bit;
-}
+	struct video_device *vdev = video_devdata(file);
+	struct saa7134_dev *dev = video_get_drvdata(vdev);
 
 
-static inline int res_locked(struct saa7134_dev *dev, unsigned int bit)
-{
-	return dev->resources & bit;
+	return vdev->queue == &dev->empress_vbq;
 }
 }
 
 
 /* ----------------------------------------------------------- */
 /* ----------------------------------------------------------- */
@@ -721,6 +714,7 @@ static inline int res_locked(struct saa7134_dev *dev, unsigned int bit)
 extern struct list_head  saa7134_devlist;
 extern struct list_head  saa7134_devlist;
 extern struct mutex saa7134_devlist_lock;
 extern struct mutex saa7134_devlist_lock;
 extern int saa7134_no_overlay;
 extern int saa7134_no_overlay;
+extern bool saa7134_userptr;
 
 
 void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
 void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
 void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value);
 void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value);
@@ -743,7 +737,7 @@ void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
 			   unsigned int state);
 			   unsigned int state);
 void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
 void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
 void saa7134_buffer_timeout(unsigned long data);
 void saa7134_buffer_timeout(unsigned long data);
-void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf);
+void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
 
 
 int saa7134_set_dmabits(struct saa7134_dev *dev);
 int saa7134_set_dmabits(struct saa7134_dev *dev);
 
 
@@ -777,8 +771,13 @@ extern unsigned int video_debug;
 extern struct video_device saa7134_video_template;
 extern struct video_device saa7134_video_template;
 extern struct video_device saa7134_radio_template;
 extern struct video_device saa7134_radio_template;
 
 
+void saa7134_vb2_buffer_queue(struct vb2_buffer *vb);
+int saa7134_vb2_start_streaming(struct vb2_queue *vq, unsigned int count);
+void saa7134_vb2_stop_streaming(struct vb2_queue *vq);
+
 int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id);
 int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id);
 int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id);
 int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id);
+int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std);
 int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i);
 int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i);
 int saa7134_g_input(struct file *file, void *priv, unsigned int *i);
 int saa7134_g_input(struct file *file, void *priv, unsigned int *i);
 int saa7134_s_input(struct file *file, void *priv, unsigned int i);
 int saa7134_s_input(struct file *file, void *priv, unsigned int i);
@@ -792,16 +791,6 @@ int saa7134_g_frequency(struct file *file, void *priv,
 					struct v4l2_frequency *f);
 					struct v4l2_frequency *f);
 int saa7134_s_frequency(struct file *file, void *priv,
 int saa7134_s_frequency(struct file *file, void *priv,
 					const struct v4l2_frequency *f);
 					const struct v4l2_frequency *f);
-int saa7134_reqbufs(struct file *file, void *priv,
-					struct v4l2_requestbuffers *p);
-int saa7134_querybuf(struct file *file, void *priv,
-					struct v4l2_buffer *b);
-int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b);
-int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b);
-int saa7134_streamon(struct file *file, void *priv,
-					enum v4l2_buf_type type);
-int saa7134_streamoff(struct file *file, void *priv,
-					enum v4l2_buf_type type);
 
 
 int saa7134_videoport_init(struct saa7134_dev *dev);
 int saa7134_videoport_init(struct saa7134_dev *dev);
 void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
 void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
@@ -818,7 +807,16 @@ void saa7134_video_fini(struct saa7134_dev *dev);
 
 
 #define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
 #define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
 
 
-extern struct videobuf_queue_ops saa7134_ts_qops;
+int saa7134_ts_buffer_init(struct vb2_buffer *vb2);
+int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2);
+void saa7134_ts_buffer_finish(struct vb2_buffer *vb2);
+int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *nbuffers, unsigned int *nplanes,
+			   unsigned int sizes[], void *alloc_ctxs[]);
+int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count);
+void saa7134_ts_stop_streaming(struct vb2_queue *vq);
+
+extern struct vb2_ops saa7134_ts_qops;
 
 
 int saa7134_ts_init1(struct saa7134_dev *dev);
 int saa7134_ts_init1(struct saa7134_dev *dev);
 int saa7134_ts_fini(struct saa7134_dev *dev);
 int saa7134_ts_fini(struct saa7134_dev *dev);
@@ -835,7 +833,7 @@ int saa7134_ts_stop(struct saa7134_dev *dev);
 /* ----------------------------------------------------------- */
 /* ----------------------------------------------------------- */
 /* saa7134-vbi.c                                               */
 /* saa7134-vbi.c                                               */
 
 
-extern struct videobuf_queue_ops saa7134_vbi_qops;
+extern struct vb2_ops saa7134_vbi_qops;
 extern struct video_device saa7134_vbi_template;
 extern struct video_device saa7134_vbi_template;
 
 
 int saa7134_vbi_init1(struct saa7134_dev *dev);
 int saa7134_vbi_init1(struct saa7134_dev *dev);

+ 7 - 7
drivers/media/pci/saa7146/mxb.c

@@ -357,7 +357,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
 	tea6420_route(mxb, 6);
 	tea6420_route(mxb, 6);
 
 
 	/* select video mode in saa7111a */
 	/* select video mode in saa7111a */
-	saa7111a_call(mxb, core, s_std, std);
+	saa7111a_call(mxb, video, s_std, std);
 
 
 	/* select tuner-output on saa7111a */
 	/* select tuner-output on saa7111a */
 	i = 0;
 	i = 0;
@@ -379,8 +379,8 @@ static int mxb_init_done(struct saa7146_dev* dev)
 	/* These two gpio calls set the GPIO pins that control the tda9820 */
 	/* These two gpio calls set the GPIO pins that control the tda9820 */
 	saa7146_write(dev, GPIO_CTRL, 0x00404050);
 	saa7146_write(dev, GPIO_CTRL, 0x00404050);
 	saa7111a_call(mxb, core, s_gpio, 1);
 	saa7111a_call(mxb, core, s_gpio, 1);
-	saa7111a_call(mxb, core, s_std, std);
-	tuner_call(mxb, core, s_std, std);
+	saa7111a_call(mxb, video, s_std, std);
+	tuner_call(mxb, video, s_std, std);
 
 
 	/* switch to tuner-channel on tea6415c */
 	/* switch to tuner-channel on tea6415c */
 	tea6415c_call(mxb, video, s_routing, 3, 17, 0);
 	tea6415c_call(mxb, video, s_routing, 3, 17, 0);
@@ -771,9 +771,9 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
 		/* These two gpio calls set the GPIO pins that control the tda9820 */
 		/* These two gpio calls set the GPIO pins that control the tda9820 */
 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
 		saa7111a_call(mxb, core, s_gpio, 0);
 		saa7111a_call(mxb, core, s_gpio, 0);
-		saa7111a_call(mxb, core, s_std, std);
+		saa7111a_call(mxb, video, s_std, std);
 		if (mxb->cur_input == 0)
 		if (mxb->cur_input == 0)
-			tuner_call(mxb, core, s_std, std);
+			tuner_call(mxb, video, s_std, std);
 	} else {
 	} else {
 		v4l2_std_id std = V4L2_STD_PAL_BG;
 		v4l2_std_id std = V4L2_STD_PAL_BG;
 
 
@@ -783,9 +783,9 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
 		/* These two gpio calls set the GPIO pins that control the tda9820 */
 		/* These two gpio calls set the GPIO pins that control the tda9820 */
 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
 		saa7146_write(dev, GPIO_CTRL, 0x00404050);
 		saa7111a_call(mxb, core, s_gpio, 1);
 		saa7111a_call(mxb, core, s_gpio, 1);
-		saa7111a_call(mxb, core, s_std, std);
+		saa7111a_call(mxb, video, s_std, std);
 		if (mxb->cur_input == 0)
 		if (mxb->cur_input == 0)
-			tuner_call(mxb, core, s_std, std);
+			tuner_call(mxb, video, s_std, std);
 	}
 	}
 	return 0;
 	return 0;
 }
 }

+ 3 - 4
drivers/media/pci/sta2x11/sta2x11_vip.c

@@ -357,7 +357,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
 }
 }
 
 
 /* abort streaming and wait for last buffer */
 /* abort streaming and wait for last buffer */
-static int stop_streaming(struct vb2_queue *vq)
+static void stop_streaming(struct vb2_queue *vq)
 {
 {
 	struct sta2x11_vip *vip = vb2_get_drv_priv(vq);
 	struct sta2x11_vip *vip = vb2_get_drv_priv(vq);
 	struct vip_buffer *vip_buf, *node;
 	struct vip_buffer *vip_buf, *node;
@@ -374,7 +374,6 @@ static int stop_streaming(struct vb2_queue *vq)
 		list_del(&vip_buf->list);
 		list_del(&vip_buf->list);
 	}
 	}
 	spin_unlock(&vip->lock);
 	spin_unlock(&vip->lock);
-	return 0;
 }
 }
 
 
 static struct vb2_ops vip_video_qops = {
 static struct vb2_ops vip_video_qops = {
@@ -445,7 +444,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
 	int status;
 	int status;
 
 
 	if (V4L2_STD_ALL == std) {
 	if (V4L2_STD_ALL == std) {
-		v4l2_subdev_call(vip->decoder, core, s_std, std);
+		v4l2_subdev_call(vip->decoder, video, s_std, std);
 		ssleep(2);
 		ssleep(2);
 		v4l2_subdev_call(vip->decoder, video, querystd, &newstd);
 		v4l2_subdev_call(vip->decoder, video, querystd, &newstd);
 		v4l2_subdev_call(vip->decoder, video, g_input_status, &status);
 		v4l2_subdev_call(vip->decoder, video, g_input_status, &status);
@@ -468,7 +467,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
 			vip->format = formats_50[0];
 			vip->format = formats_50[0];
 	}
 	}
 
 
-	return v4l2_subdev_call(vip->decoder, core, s_std, std);
+	return v4l2_subdev_call(vip->decoder, video, s_std, std);
 }
 }
 
 
 /**
 /**

+ 4 - 2
drivers/media/pci/ttpci/av7110_av.c

@@ -958,8 +958,10 @@ static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
 		if (av7110->playing) {
 		if (av7110->playing) {
 			if (FREE_COND)
 			if (FREE_COND)
 				mask |= (POLLOUT | POLLWRNORM);
 				mask |= (POLLOUT | POLLWRNORM);
-			} else /* if not playing: may play if asked for */
-				mask |= (POLLOUT | POLLWRNORM);
+		} else {
+			/* if not playing: may play if asked for */
+			mask |= (POLLOUT | POLLWRNORM);
+		}
 	}
 	}
 
 
 	return mask;
 	return mask;

+ 1 - 1
drivers/media/pci/zoran/zoran_device.c

@@ -1572,7 +1572,7 @@ zoran_init_hardware (struct zoran *zr)
 	}
 	}
 
 
 	decoder_call(zr, core, init, 0);
 	decoder_call(zr, core, init, 0);
-	decoder_call(zr, core, s_std, zr->norm);
+	decoder_call(zr, video, s_std, zr->norm);
 	decoder_call(zr, video, s_routing,
 	decoder_call(zr, video, s_routing,
 		zr->card.input[zr->input].muxsel, 0, 0);
 		zr->card.input[zr->input].muxsel, 0, 0);
 
 

+ 1 - 1
drivers/media/pci/zoran/zoran_driver.c

@@ -1469,7 +1469,7 @@ zoran_set_norm (struct zoran *zr,
 	if (on)
 	if (on)
 		zr36057_overlay(zr, 0);
 		zr36057_overlay(zr, 0);
 
 
-	decoder_call(zr, core, s_std, norm);
+	decoder_call(zr, video, s_std, norm);
 	encoder_call(zr, video, s_std_output, norm);
 	encoder_call(zr, video, s_std_output, norm);
 
 
 	if (on)
 	if (on)

+ 6 - 8
drivers/media/platform/blackfin/bfin_capture.c

@@ -427,15 +427,12 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
 	return 0;
 	return 0;
 }
 }
 
 
-static int bcap_stop_streaming(struct vb2_queue *vq)
+static void bcap_stop_streaming(struct vb2_queue *vq)
 {
 {
 	struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
 	struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
 	struct ppi_if *ppi = bcap_dev->ppi;
 	struct ppi_if *ppi = bcap_dev->ppi;
 	int ret;
 	int ret;
 
 
-	if (!vb2_is_streaming(vq))
-		return 0;
-
 	bcap_dev->stop = true;
 	bcap_dev->stop = true;
 	wait_for_completion(&bcap_dev->comp);
 	wait_for_completion(&bcap_dev->comp);
 	ppi->ops->stop(ppi);
 	ppi->ops->stop(ppi);
@@ -452,7 +449,6 @@ static int bcap_stop_streaming(struct vb2_queue *vq)
 		list_del(&bcap_dev->cur_frm->list);
 		list_del(&bcap_dev->cur_frm->list);
 		vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
 		vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
 	}
 	}
-	return 0;
 }
 }
 
 
 static struct vb2_ops bcap_video_qops = {
 static struct vb2_ops bcap_video_qops = {
@@ -635,7 +631,7 @@ static int bcap_s_std(struct file *file, void *priv, v4l2_std_id std)
 	if (vb2_is_busy(&bcap_dev->buffer_queue))
 	if (vb2_is_busy(&bcap_dev->buffer_queue))
 		return -EBUSY;
 		return -EBUSY;
 
 
-	ret = v4l2_subdev_call(bcap_dev->sd, core, s_std, std);
+	ret = v4l2_subdev_call(bcap_dev->sd, video, s_std, std);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -648,7 +644,9 @@ static int bcap_enum_dv_timings(struct file *file, void *priv,
 {
 {
 	struct bcap_device *bcap_dev = video_drvdata(file);
 	struct bcap_device *bcap_dev = video_drvdata(file);
 
 
-	return v4l2_subdev_call(bcap_dev->sd, video,
+	timings->pad = 0;
+
+	return v4l2_subdev_call(bcap_dev->sd, pad,
 			enum_dv_timings, timings);
 			enum_dv_timings, timings);
 }
 }
 
 
@@ -1069,7 +1067,7 @@ static int bcap_probe(struct platform_device *pdev)
 	/* now we can probe the default state */
 	/* now we can probe the default state */
 	if (config->inputs[0].capabilities & V4L2_IN_CAP_STD) {
 	if (config->inputs[0].capabilities & V4L2_IN_CAP_STD) {
 		v4l2_std_id std;
 		v4l2_std_id std;
-		ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std);
+		ret = v4l2_subdev_call(bcap_dev->sd, video, g_std, &std);
 		if (ret) {
 		if (ret) {
 			v4l2_err(&bcap_dev->v4l2_dev,
 			v4l2_err(&bcap_dev->v4l2_dev,
 					"Unable to get std\n");
 					"Unable to get std\n");

+ 2 - 4
drivers/media/platform/coda.c

@@ -2269,7 +2269,7 @@ out:
 	return ret;
 	return ret;
 }
 }
 
 
-static int coda_stop_streaming(struct vb2_queue *q)
+static void coda_stop_streaming(struct vb2_queue *q)
 {
 {
 	struct coda_ctx *ctx = vb2_get_drv_priv(q);
 	struct coda_ctx *ctx = vb2_get_drv_priv(q);
 	struct coda_dev *dev = ctx->dev;
 	struct coda_dev *dev = ctx->dev;
@@ -2295,8 +2295,6 @@ static int coda_stop_streaming(struct vb2_queue *q)
 			ctx->bitstream.vaddr, ctx->bitstream.size);
 			ctx->bitstream.vaddr, ctx->bitstream.size);
 		ctx->runcounter = 0;
 		ctx->runcounter = 0;
 	}
 	}
-
-	return 0;
 }
 }
 
 
 static struct vb2_ops coda_qops = {
 static struct vb2_ops coda_qops = {
@@ -3235,7 +3233,7 @@ static int coda_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	if (devm_request_threaded_irq(&pdev->dev, irq, NULL, coda_irq_handler,
 	if (devm_request_threaded_irq(&pdev->dev, irq, NULL, coda_irq_handler,
-		IRQF_ONESHOT, CODA_NAME, dev) < 0) {
+		IRQF_ONESHOT, dev_name(&pdev->dev), dev) < 0) {
 		dev_err(&pdev->dev, "failed to request irq\n");
 		dev_err(&pdev->dev, "failed to request irq\n");
 		return -ENOENT;
 		return -ENOENT;
 	}
 	}

+ 19 - 36
drivers/media/platform/davinci/vpbe_display.c

@@ -355,8 +355,17 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
 
 
 	/* Set parameters in OSD and VENC */
 	/* Set parameters in OSD and VENC */
 	ret = vpbe_set_osd_display_params(fh->disp_dev, layer);
 	ret = vpbe_set_osd_display_params(fh->disp_dev, layer);
-	if (ret < 0)
+	if (ret < 0) {
+		struct vpbe_disp_buffer *buf, *tmp;
+
+		vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_QUEUED);
+		list_for_each_entry_safe(buf, tmp, &layer->dma_queue, list) {
+			list_del(&buf->list);
+			vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+		}
+
 		return ret;
 		return ret;
+	}
 
 
 	/*
 	/*
 	 * if request format is yuv420 semiplanar, need to
 	 * if request format is yuv420 semiplanar, need to
@@ -368,7 +377,7 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count)
 	return ret;
 	return ret;
 }
 }
 
 
-static int vpbe_stop_streaming(struct vb2_queue *vq)
+static void vpbe_stop_streaming(struct vb2_queue *vq)
 {
 {
 	struct vpbe_fh *fh = vb2_get_drv_priv(vq);
 	struct vpbe_fh *fh = vb2_get_drv_priv(vq);
 	struct vpbe_layer *layer = fh->layer;
 	struct vpbe_layer *layer = fh->layer;
@@ -376,7 +385,7 @@ static int vpbe_stop_streaming(struct vb2_queue *vq)
 	unsigned long flags;
 	unsigned long flags;
 
 
 	if (!vb2_is_streaming(vq))
 	if (!vb2_is_streaming(vq))
-		return 0;
+		return;
 
 
 	/* release all active buffers */
 	/* release all active buffers */
 	spin_lock_irqsave(&disp->dma_queue_lock, flags);
 	spin_lock_irqsave(&disp->dma_queue_lock, flags);
@@ -398,7 +407,6 @@ static int vpbe_stop_streaming(struct vb2_queue *vq)
 		vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR);
 		vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR);
 	}
 	}
 	spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
 	spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
-	return 0;
 }
 }
 
 
 static struct vb2_ops video_qops = {
 static struct vb2_ops video_qops = {
@@ -680,29 +688,6 @@ static int vpbe_try_format(struct vpbe_display *disp_dev,
 	return 0;
 	return 0;
 }
 }
 
 
-static int vpbe_display_g_priority(struct file *file, void *priv,
-				enum v4l2_priority *p)
-{
-	struct vpbe_fh *fh = file->private_data;
-	struct vpbe_layer *layer = fh->layer;
-
-	*p = v4l2_prio_max(&layer->prio);
-
-	return 0;
-}
-
-static int vpbe_display_s_priority(struct file *file, void *priv,
-				enum v4l2_priority p)
-{
-	struct vpbe_fh *fh = file->private_data;
-	struct vpbe_layer *layer = fh->layer;
-	int ret;
-
-	ret = v4l2_prio_change(&layer->prio, &fh->prio, p);
-
-	return ret;
-}
-
 static int vpbe_display_querycap(struct file *file, void  *priv,
 static int vpbe_display_querycap(struct file *file, void  *priv,
 			       struct v4l2_capability *cap)
 			       struct v4l2_capability *cap)
 {
 {
@@ -1492,6 +1477,7 @@ static int vpbe_display_open(struct file *file)
 {
 {
 	struct vpbe_fh *fh = NULL;
 	struct vpbe_fh *fh = NULL;
 	struct vpbe_layer *layer = video_drvdata(file);
 	struct vpbe_layer *layer = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
 	struct vpbe_display *disp_dev = layer->disp_dev;
 	struct vpbe_display *disp_dev = layer->disp_dev;
 	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
 	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
 	struct osd_state *osd_device = disp_dev->osd_device;
 	struct osd_state *osd_device = disp_dev->osd_device;
@@ -1504,6 +1490,7 @@ static int vpbe_display_open(struct file *file)
 			"unable to allocate memory for file handle object\n");
 			"unable to allocate memory for file handle object\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
+	v4l2_fh_init(&fh->fh, vdev);
 	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
 	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
 			"vpbe display open plane = %d\n",
 			"vpbe display open plane = %d\n",
 			layer->device_id);
 			layer->device_id);
@@ -1532,9 +1519,7 @@ static int vpbe_display_open(struct file *file)
 	layer->usrs++;
 	layer->usrs++;
 	/* Set io_allowed member to false */
 	/* Set io_allowed member to false */
 	fh->io_allowed = 0;
 	fh->io_allowed = 0;
-	/* Initialize priority of this instance to default priority */
-	fh->prio = V4L2_PRIORITY_UNSET;
-	v4l2_prio_open(&layer->prio, &fh->prio);
+	v4l2_fh_add(&fh->fh);
 	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
 	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
 			"vpbe display device opened successfully\n");
 			"vpbe display device opened successfully\n");
 	return 0;
 	return 0;
@@ -1589,8 +1574,9 @@ static int vpbe_display_release(struct file *file)
 		osd_device->ops.release_layer(osd_device,
 		osd_device->ops.release_layer(osd_device,
 				layer->layer_info.id);
 				layer->layer_info.id);
 	}
 	}
-	/* Close the priority */
-	v4l2_prio_close(&layer->prio, fh->prio);
+
+	v4l2_fh_del(&fh->fh);
+	v4l2_fh_exit(&fh->fh);
 	file->private_data = NULL;
 	file->private_data = NULL;
 	mutex_unlock(&layer->opslock);
 	mutex_unlock(&layer->opslock);
 
 
@@ -1618,8 +1604,6 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
 	.vidioc_cropcap		 = vpbe_display_cropcap,
 	.vidioc_cropcap		 = vpbe_display_cropcap,
 	.vidioc_g_crop		 = vpbe_display_g_crop,
 	.vidioc_g_crop		 = vpbe_display_g_crop,
 	.vidioc_s_crop		 = vpbe_display_s_crop,
 	.vidioc_s_crop		 = vpbe_display_s_crop,
-	.vidioc_g_priority	 = vpbe_display_g_priority,
-	.vidioc_s_priority	 = vpbe_display_s_priority,
 	.vidioc_s_std		 = vpbe_display_s_std,
 	.vidioc_s_std		 = vpbe_display_s_std,
 	.vidioc_g_std		 = vpbe_display_g_std,
 	.vidioc_g_std		 = vpbe_display_g_std,
 	.vidioc_enum_output	 = vpbe_display_enum_output,
 	.vidioc_enum_output	 = vpbe_display_enum_output,
@@ -1699,8 +1683,6 @@ static int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
 	vpbe_display_layer->layer_info.id =
 	vpbe_display_layer->layer_info.id =
 		((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
 		((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
 
 
-	/* Initialize prio member of layer object */
-	v4l2_prio_init(&vpbe_display_layer->prio);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1727,6 +1709,7 @@ static int register_device(struct vpbe_layer *vpbe_display_layer,
 	vpbe_display_layer->disp_dev = disp_dev;
 	vpbe_display_layer->disp_dev = disp_dev;
 	/* set the driver data in platform device */
 	/* set the driver data in platform device */
 	platform_set_drvdata(pdev, disp_dev);
 	platform_set_drvdata(pdev, disp_dev);
+	set_bit(V4L2_FL_USE_FH_PRIO, &vpbe_display_layer->video_dev.flags);
 	video_set_drvdata(&vpbe_display_layer->video_dev,
 	video_set_drvdata(&vpbe_display_layer->video_dev,
 			  vpbe_display_layer);
 			  vpbe_display_layer);
 
 

+ 7 - 8
drivers/media/platform/davinci/vpfe_capture.c

@@ -498,6 +498,7 @@ unlock:
 static int vpfe_open(struct file *file)
 static int vpfe_open(struct file *file)
 {
 {
 	struct vpfe_device *vpfe_dev = video_drvdata(file);
 	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct video_device *vdev = video_devdata(file);
 	struct vpfe_fh *fh;
 	struct vpfe_fh *fh;
 
 
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
@@ -517,6 +518,7 @@ static int vpfe_open(struct file *file)
 	/* store pointer to fh in private_data member of file */
 	/* store pointer to fh in private_data member of file */
 	file->private_data = fh;
 	file->private_data = fh;
 	fh->vpfe_dev = vpfe_dev;
 	fh->vpfe_dev = vpfe_dev;
+	v4l2_fh_init(&fh->fh, vdev);
 	mutex_lock(&vpfe_dev->lock);
 	mutex_lock(&vpfe_dev->lock);
 	/* If decoder is not initialized. initialize it */
 	/* If decoder is not initialized. initialize it */
 	if (!vpfe_dev->initialized) {
 	if (!vpfe_dev->initialized) {
@@ -529,9 +531,7 @@ static int vpfe_open(struct file *file)
 	vpfe_dev->usrs++;
 	vpfe_dev->usrs++;
 	/* Set io_allowed member to false */
 	/* Set io_allowed member to false */
 	fh->io_allowed = 0;
 	fh->io_allowed = 0;
-	/* Initialize priority of this instance to default priority */
-	fh->prio = V4L2_PRIORITY_UNSET;
-	v4l2_prio_open(&vpfe_dev->prio, &fh->prio);
+	v4l2_fh_add(&fh->fh);
 	mutex_unlock(&vpfe_dev->lock);
 	mutex_unlock(&vpfe_dev->lock);
 	return 0;
 	return 0;
 }
 }
@@ -740,8 +740,8 @@ static int vpfe_release(struct file *file)
 
 
 	/* Decrement device usrs counter */
 	/* Decrement device usrs counter */
 	vpfe_dev->usrs--;
 	vpfe_dev->usrs--;
-	/* Close the priority */
-	v4l2_prio_close(&vpfe_dev->prio, fh->prio);
+	v4l2_fh_del(&fh->fh);
+	v4l2_fh_exit(&fh->fh);
 	/* If this is the last file handle */
 	/* If this is the last file handle */
 	if (!vpfe_dev->usrs) {
 	if (!vpfe_dev->usrs) {
 		vpfe_dev->initialized = 0;
 		vpfe_dev->initialized = 0;
@@ -1217,7 +1217,7 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 	}
 	}
 
 
 	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
 	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-					 core, s_std, std_id);
+					 video, s_std, std_id);
 	if (ret < 0) {
 	if (ret < 0) {
 		v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
 		v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
 		goto unlock_out;
 		goto unlock_out;
@@ -1910,14 +1910,13 @@ static int vpfe_probe(struct platform_device *pdev)
 	/* Initialize field of the device objects */
 	/* Initialize field of the device objects */
 	vpfe_dev->numbuffers = config_params.numbuffers;
 	vpfe_dev->numbuffers = config_params.numbuffers;
 
 
-	/* Initialize prio member of device object */
-	v4l2_prio_init(&vpfe_dev->prio);
 	/* register video device */
 	/* register video device */
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
 		"trying to register vpfe device.\n");
 		"trying to register vpfe device.\n");
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
 		"video_dev=%x\n", (int)&vpfe_dev->video_dev);
 		"video_dev=%x\n", (int)&vpfe_dev->video_dev);
 	vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	set_bit(V4L2_FL_USE_FH_PRIO, &vpfe_dev->video_dev->flags);
 	ret = video_register_device(vpfe_dev->video_dev,
 	ret = video_register_device(vpfe_dev->video_dev,
 				    VFL_TYPE_GRABBER, -1);
 				    VFL_TYPE_GRABBER, -1);
 
 

+ 306 - 813
drivers/media/platform/davinci/vpif_capture.c

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (C) 2009 Texas Instruments Inc
  * Copyright (C) 2009 Texas Instruments Inc
+ * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License as published by
@@ -65,14 +66,26 @@ static struct vpif_config_params config_params = {
 	.channel_bufsize[1] = 720 * 576 * 2,
 	.channel_bufsize[1] = 720 * 576 * 2,
 };
 };
 
 
+#define VPIF_DRIVER_NAME	"vpif_capture"
+
 /* global variables */
 /* global variables */
 static struct vpif_device vpif_obj = { {NULL} };
 static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
 static struct device *vpif_dev;
 static void vpif_calculate_offsets(struct channel_obj *ch);
 static void vpif_calculate_offsets(struct channel_obj *ch);
 static void vpif_config_addr(struct channel_obj *ch, int muxmode);
 static void vpif_config_addr(struct channel_obj *ch, int muxmode);
 
 
+static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] = { {1, 1} };
+
+/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
+static int ycmux_mode;
+
+static inline struct vpif_cap_buffer *to_vpif_buffer(struct vb2_buffer *vb)
+{
+	return container_of(vb, struct vpif_cap_buffer, vb);
+}
+
 /**
 /**
- * buffer_prepare :  callback function for buffer prepare
+ * vpif_buffer_prepare :  callback function for buffer prepare
  * @vb: ptr to vb2_buffer
  * @vb: ptr to vb2_buffer
  *
  *
  * This is the callback function for buffer prepare when vb2_qbuf()
  * This is the callback function for buffer prepare when vb2_qbuf()
@@ -81,10 +94,8 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode);
  */
  */
 static int vpif_buffer_prepare(struct vb2_buffer *vb)
 static int vpif_buffer_prepare(struct vb2_buffer *vb)
 {
 {
-	/* Get the file handle object and channel object */
-	struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
 	struct vb2_queue *q = vb->vb2_queue;
 	struct vb2_queue *q = vb->vb2_queue;
-	struct channel_obj *ch = fh->channel;
+	struct channel_obj *ch = vb2_get_drv_priv(q);
 	struct common_obj *common;
 	struct common_obj *common;
 	unsigned long addr;
 	unsigned long addr;
 
 
@@ -92,26 +103,22 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb)
 
 
 	common = &ch->common[VPIF_VIDEO_INDEX];
 	common = &ch->common[VPIF_VIDEO_INDEX];
 
 
-	if (vb->state != VB2_BUF_STATE_ACTIVE &&
-		vb->state != VB2_BUF_STATE_PREPARED) {
-		vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
-		if (vb2_plane_vaddr(vb, 0) &&
-		vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
-			goto exit;
-		addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+	vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
+	if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
+		return -EINVAL;
 
 
-		if (q->streaming) {
-			if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
-				!IS_ALIGNED((addr + common->ybtm_off), 8) ||
-				!IS_ALIGNED((addr + common->ctop_off), 8) ||
-				!IS_ALIGNED((addr + common->cbtm_off), 8))
-				goto exit;
-		}
+	vb->v4l2_buf.field = common->fmt.fmt.pix.field;
+
+	addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+	if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
+		!IS_ALIGNED((addr + common->ybtm_off), 8) ||
+		!IS_ALIGNED((addr + common->ctop_off), 8) ||
+		!IS_ALIGNED((addr + common->cbtm_off), 8)) {
+		vpif_dbg(1, debug, "offset is not aligned\n");
+		return -EINVAL;
 	}
 	}
+
 	return 0;
 	return 0;
-exit:
-	vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
-	return -EINVAL;
 }
 }
 
 
 /**
 /**
@@ -131,49 +138,26 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
 				unsigned int *nbuffers, unsigned int *nplanes,
 				unsigned int *nbuffers, unsigned int *nplanes,
 				unsigned int sizes[], void *alloc_ctxs[])
 				unsigned int sizes[], void *alloc_ctxs[])
 {
 {
-	/* Get the file handle object and channel object */
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
+	struct channel_obj *ch = vb2_get_drv_priv(vq);
 	struct common_obj *common;
 	struct common_obj *common;
-	unsigned long size;
 
 
 	common = &ch->common[VPIF_VIDEO_INDEX];
 	common = &ch->common[VPIF_VIDEO_INDEX];
 
 
 	vpif_dbg(2, debug, "vpif_buffer_setup\n");
 	vpif_dbg(2, debug, "vpif_buffer_setup\n");
 
 
-	/* If memory type is not mmap, return */
-	if (V4L2_MEMORY_MMAP == common->memory) {
-		/* Calculate the size of the buffer */
-		size = config_params.channel_bufsize[ch->channel_id];
-		/*
-		 * Checking if the buffer size exceeds the available buffer
-		 * ycmux_mode = 0 means 1 channel mode HD and
-		 * ycmux_mode = 1 means 2 channels mode SD
-		 */
-		if (ch->vpifparams.std_info.ycmux_mode == 0) {
-			if (config_params.video_limit[ch->channel_id])
-				while (size * *nbuffers >
-					(config_params.video_limit[0]
-						+ config_params.video_limit[1]))
-					(*nbuffers)--;
-		} else {
-			if (config_params.video_limit[ch->channel_id])
-				while (size * *nbuffers >
-				config_params.video_limit[ch->channel_id])
-					(*nbuffers)--;
-		}
-
-	} else {
-		size = common->fmt.fmt.pix.sizeimage;
-	}
+	if (fmt && fmt->fmt.pix.sizeimage < common->fmt.fmt.pix.sizeimage)
+		return -EINVAL;
 
 
-	if (*nbuffers < config_params.min_numbuffers)
-		*nbuffers = config_params.min_numbuffers;
+	if (vq->num_buffers + *nbuffers < 3)
+		*nbuffers = 3 - vq->num_buffers;
 
 
 	*nplanes = 1;
 	*nplanes = 1;
-	sizes[0] = size;
+	sizes[0] = fmt ? fmt->fmt.pix.sizeimage : common->fmt.fmt.pix.sizeimage;
 	alloc_ctxs[0] = common->alloc_ctx;
 	alloc_ctxs[0] = common->alloc_ctx;
 
 
+	/* Calculate the offset for Y and C data in the buffer */
+	vpif_calculate_offsets(ch);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -183,11 +167,8 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq,
  */
  */
 static void vpif_buffer_queue(struct vb2_buffer *vb)
 static void vpif_buffer_queue(struct vb2_buffer *vb)
 {
 {
-	/* Get the file handle object and channel object */
-	struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
-	struct channel_obj *ch = fh->channel;
-	struct vpif_cap_buffer *buf = container_of(vb,
-				struct vpif_cap_buffer, vb);
+	struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
+	struct vpif_cap_buffer *buf = to_vpif_buffer(vb);
 	struct common_obj *common;
 	struct common_obj *common;
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -202,102 +183,25 @@ static void vpif_buffer_queue(struct vb2_buffer *vb)
 }
 }
 
 
 /**
 /**
- * vpif_buf_cleanup : Callback function to free buffer
+ * vpif_start_streaming : Starts the DMA engine for streaming
  * @vb: ptr to vb2_buffer
  * @vb: ptr to vb2_buffer
- *
- * This function is called from the videobuf2 layer to free memory
- * allocated to  the buffers
+ * @count: number of buffers
  */
  */
-static void vpif_buf_cleanup(struct vb2_buffer *vb)
-{
-	/* Get the file handle object and channel object */
-	struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
-	struct vpif_cap_buffer *buf = container_of(vb,
-					struct vpif_cap_buffer, vb);
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common;
-	unsigned long flags;
-
-	common = &ch->common[VPIF_VIDEO_INDEX];
-
-	spin_lock_irqsave(&common->irqlock, flags);
-	if (vb->state == VB2_BUF_STATE_ACTIVE)
-		list_del_init(&buf->list);
-	spin_unlock_irqrestore(&common->irqlock, flags);
-
-}
-
-static void vpif_wait_prepare(struct vb2_queue *vq)
-{
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common;
-
-	common = &ch->common[VPIF_VIDEO_INDEX];
-	mutex_unlock(&common->lock);
-}
-
-static void vpif_wait_finish(struct vb2_queue *vq)
-{
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common;
-
-	common = &ch->common[VPIF_VIDEO_INDEX];
-	mutex_lock(&common->lock);
-}
-
-static int vpif_buffer_init(struct vb2_buffer *vb)
-{
-	struct vpif_cap_buffer *buf = container_of(vb,
-					struct vpif_cap_buffer, vb);
-
-	INIT_LIST_HEAD(&buf->list);
-
-	return 0;
-}
-
-static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
-	{ {1, 1} };
-
 static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 {
 	struct vpif_capture_config *vpif_config_data =
 	struct vpif_capture_config *vpif_config_data =
 					vpif_dev->platform_data;
 					vpif_dev->platform_data;
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
+	struct channel_obj *ch = vb2_get_drv_priv(vq);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct vpif_params *vpif = &ch->vpifparams;
 	struct vpif_params *vpif = &ch->vpifparams;
-	unsigned long addr = 0;
-	unsigned long flags;
+	struct vpif_cap_buffer *buf, *tmp;
+	unsigned long addr, flags;
 	int ret;
 	int ret;
 
 
 	spin_lock_irqsave(&common->irqlock, flags);
 	spin_lock_irqsave(&common->irqlock, flags);
 
 
-	/* Get the next frame from the buffer queue */
-	common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
-				    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 */
+	/* Initialize field_id */
 	ch->field_id = 0;
 	ch->field_id = 0;
-	common->started = 1;
-	addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
-
-	/* Calculate the offset for Y and C data in the buffer */
-	vpif_calculate_offsets(ch);
-
-	if ((vpif->std_info.frm_fmt &&
-	    ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
-	     (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
-	    (!vpif->std_info.frm_fmt &&
-	     (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
-		vpif_dbg(1, debug, "conflict in field format and std format\n");
-		return -EINVAL;
-	}
 
 
 	/* configure 1 or 2 channel mode */
 	/* configure 1 or 2 channel mode */
 	if (vpif_config_data->setup_input_channel_mode) {
 	if (vpif_config_data->setup_input_channel_mode) {
@@ -305,21 +209,37 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 			setup_input_channel_mode(vpif->std_info.ycmux_mode);
 			setup_input_channel_mode(vpif->std_info.ycmux_mode);
 		if (ret < 0) {
 		if (ret < 0) {
 			vpif_dbg(1, debug, "can't set vpif channel mode\n");
 			vpif_dbg(1, debug, "can't set vpif channel mode\n");
-			return ret;
+			goto err;
 		}
 		}
 	}
 	}
 
 
+	ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
+	if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
+		vpif_dbg(1, debug, "stream on failed in subdev\n");
+		goto err;
+	}
+
 	/* Call vpif_set_params function to set the parameters and addresses */
 	/* Call vpif_set_params function to set the parameters and addresses */
 	ret = vpif_set_video_params(vpif, ch->channel_id);
 	ret = vpif_set_video_params(vpif, ch->channel_id);
-
 	if (ret < 0) {
 	if (ret < 0) {
 		vpif_dbg(1, debug, "can't set video params\n");
 		vpif_dbg(1, debug, "can't set video params\n");
-		return ret;
+		goto err;
 	}
 	}
 
 
-	common->started = ret;
+	ycmux_mode = ret;
 	vpif_config_addr(ch, ret);
 	vpif_config_addr(ch, ret);
 
 
+	/* Get the next frame from the buffer queue */
+	common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
+				    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;
+
+	addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
+
 	common->set_addr(addr + common->ytop_off,
 	common->set_addr(addr + common->ytop_off,
 			 addr + common->ybtm_off,
 			 addr + common->ybtm_off,
 			 addr + common->ctop_off,
 			 addr + common->ctop_off,
@@ -330,31 +250,42 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 	 * VPIF register
 	 * VPIF register
 	 */
 	 */
 	channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
 	channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
-	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
+	if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
 		channel0_intr_assert();
 		channel0_intr_assert();
 		channel0_intr_enable(1);
 		channel0_intr_enable(1);
 		enable_channel0(1);
 		enable_channel0(1);
 	}
 	}
-	if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
-	    (common->started == 2)) {
+	if (VPIF_CHANNEL1_VIDEO == ch->channel_id ||
+		ycmux_mode == 2) {
 		channel1_intr_assert();
 		channel1_intr_assert();
 		channel1_intr_enable(1);
 		channel1_intr_enable(1);
 		enable_channel1(1);
 		enable_channel1(1);
 	}
 	}
 
 
 	return 0;
 	return 0;
+
+err:
+	list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+	}
+
+	return ret;
 }
 }
 
 
-/* abort streaming and wait for last buffer */
-static int vpif_stop_streaming(struct vb2_queue *vq)
+/**
+ * vpif_stop_streaming : Stop the DMA engine
+ * @vq: ptr to vb2_queue
+ *
+ * This callback stops the DMA engine and any remaining buffers
+ * in the DMA queue are released.
+ */
+static void vpif_stop_streaming(struct vb2_queue *vq)
 {
 {
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
+	struct channel_obj *ch = vb2_get_drv_priv(vq);
 	struct common_obj *common;
 	struct common_obj *common;
 	unsigned long flags;
 	unsigned long flags;
-
-	if (!vb2_is_streaming(vq))
-		return 0;
+	int ret;
 
 
 	common = &ch->common[VPIF_VIDEO_INDEX];
 	common = &ch->common[VPIF_VIDEO_INDEX];
 
 
@@ -363,12 +294,17 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
 		enable_channel0(0);
 		enable_channel0(0);
 		channel0_intr_enable(0);
 		channel0_intr_enable(0);
 	}
 	}
-	if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
-		(2 == common->started)) {
+	if (VPIF_CHANNEL1_VIDEO == ch->channel_id ||
+		ycmux_mode == 2) {
 		enable_channel1(0);
 		enable_channel1(0);
 		channel1_intr_enable(0);
 		channel1_intr_enable(0);
 	}
 	}
-	common->started = 0;
+
+	ycmux_mode = 0;
+
+	ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
+	if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
+		vpif_dbg(1, debug, "stream off failed in subdev\n");
 
 
 	/* release all active buffers */
 	/* release all active buffers */
 	spin_lock_irqsave(&common->irqlock, flags);
 	spin_lock_irqsave(&common->irqlock, flags);
@@ -390,19 +326,13 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
 		vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
 		vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
 	}
 	}
 	spin_unlock_irqrestore(&common->irqlock, flags);
 	spin_unlock_irqrestore(&common->irqlock, flags);
-
-	return 0;
 }
 }
 
 
 static struct vb2_ops video_qops = {
 static struct vb2_ops video_qops = {
 	.queue_setup		= vpif_buffer_queue_setup,
 	.queue_setup		= vpif_buffer_queue_setup,
-	.wait_prepare		= vpif_wait_prepare,
-	.wait_finish		= vpif_wait_finish,
-	.buf_init		= vpif_buffer_init,
 	.buf_prepare		= vpif_buffer_prepare,
 	.buf_prepare		= vpif_buffer_prepare,
 	.start_streaming	= vpif_start_streaming,
 	.start_streaming	= vpif_start_streaming,
 	.stop_streaming		= vpif_stop_streaming,
 	.stop_streaming		= vpif_stop_streaming,
-	.buf_cleanup		= vpif_buf_cleanup,
 	.buf_queue		= vpif_buffer_queue,
 	.buf_queue		= vpif_buffer_queue,
 };
 };
 
 
@@ -479,9 +409,6 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
 	for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
 	for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
 		common = &ch->common[i];
 		common = &ch->common[i];
 		/* skip If streaming is not started in this channel */
 		/* skip If streaming is not started in this channel */
-		if (0 == common->started)
-			continue;
-
 		/* Check the field format */
 		/* Check the field format */
 		if (1 == ch->vpifparams.std_info.frm_fmt) {
 		if (1 == ch->vpifparams.std_info.frm_fmt) {
 			/* Progressive mode */
 			/* Progressive mode */
@@ -683,11 +610,6 @@ static void vpif_config_format(struct channel_obj *ch)
 	vpif_dbg(2, debug, "vpif_config_format\n");
 	vpif_dbg(2, debug, "vpif_config_format\n");
 
 
 	common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
 	common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
-	if (config_params.numbuffers[ch->channel_id] == 0)
-		common->memory = V4L2_MEMORY_USERPTR;
-	else
-		common->memory = V4L2_MEMORY_MMAP;
-
 	common->fmt.fmt.pix.sizeimage
 	common->fmt.fmt.pix.sizeimage
 	    = config_params.channel_bufsize[ch->channel_id];
 	    = config_params.channel_bufsize[ch->channel_id];
 
 
@@ -836,415 +758,6 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
 		common->set_addr = ch0_set_videobuf_addr;
 		common->set_addr = ch0_set_videobuf_addr;
 }
 }
 
 
-/**
- * vpif_mmap : It is used to map kernel space buffers into user spaces
- * @filep: file pointer
- * @vma: ptr to vm_area_struct
- */
-static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
-{
-	/* Get the channel object and file handle object */
-	struct vpif_fh *fh = filep->private_data;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
-	int ret;
-
-	vpif_dbg(2, debug, "vpif_mmap\n");
-
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-	ret = vb2_mmap(&common->buffer_queue, vma);
-	mutex_unlock(&common->lock);
-	return ret;
-}
-
-/**
- * vpif_poll: It is used for select/poll system call
- * @filep: file pointer
- * @wait: poll table to wait
- */
-static unsigned int vpif_poll(struct file *filep, poll_table * wait)
-{
-	struct vpif_fh *fh = filep->private_data;
-	struct channel_obj *channel = fh->channel;
-	struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
-	unsigned int res = 0;
-
-	vpif_dbg(2, debug, "vpif_poll\n");
-
-	if (common->started) {
-		mutex_lock(&common->lock);
-		res = vb2_poll(&common->buffer_queue, filep, wait);
-		mutex_unlock(&common->lock);
-	}
-	return res;
-}
-
-/**
- * vpif_open : vpif open handler
- * @filep: file ptr
- *
- * It creates object of file handle structure and stores it in private_data
- * member of filepointer
- */
-static int vpif_open(struct file *filep)
-{
-	struct video_device *vdev = video_devdata(filep);
-	struct common_obj *common;
-	struct video_obj *vid_ch;
-	struct channel_obj *ch;
-	struct vpif_fh *fh;
-
-	vpif_dbg(2, debug, "vpif_open\n");
-
-	ch = video_get_drvdata(vdev);
-
-	vid_ch = &ch->video;
-	common = &ch->common[VPIF_VIDEO_INDEX];
-
-	/* Allocate memory for the file handle object */
-	fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
-	if (NULL == fh) {
-		vpif_err("unable to allocate memory for file handle object\n");
-		return -ENOMEM;
-	}
-
-	if (mutex_lock_interruptible(&common->lock)) {
-		kfree(fh);
-		return -ERESTARTSYS;
-	}
-	/* store pointer to fh in private_data member of filep */
-	filep->private_data = fh;
-	fh->channel = ch;
-	fh->initialized = 0;
-	/* If decoder is not initialized. initialize it */
-	if (!ch->initialized) {
-		fh->initialized = 1;
-		ch->initialized = 1;
-		memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
-	}
-	/* Increment channel usrs counter */
-	ch->usrs++;
-	/* Set io_allowed member to false */
-	fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
-	/* Initialize priority of this instance to default priority */
-	fh->prio = V4L2_PRIORITY_UNSET;
-	v4l2_prio_open(&ch->prio, &fh->prio);
-	mutex_unlock(&common->lock);
-	return 0;
-}
-
-/**
- * vpif_release : function to clean up file close
- * @filep: file pointer
- *
- * This function deletes buffer queue, frees the buffers and the vpif file
- * handle
- */
-static int vpif_release(struct file *filep)
-{
-	struct vpif_fh *fh = filep->private_data;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common;
-
-	vpif_dbg(2, debug, "vpif_release\n");
-
-	common = &ch->common[VPIF_VIDEO_INDEX];
-
-	mutex_lock(&common->lock);
-	/* if this instance is doing IO */
-	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
-		/* Reset io_usrs member of channel object */
-		common->io_usrs = 0;
-		/* Free buffers allocated */
-		vb2_queue_release(&common->buffer_queue);
-		vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
-	}
-
-	/* Decrement channel usrs counter */
-	ch->usrs--;
-
-	/* Close the priority */
-	v4l2_prio_close(&ch->prio, fh->prio);
-
-	if (fh->initialized)
-		ch->initialized = 0;
-
-	mutex_unlock(&common->lock);
-	filep->private_data = NULL;
-	kfree(fh);
-	return 0;
-}
-
-/**
- * vpif_reqbufs() - request buffer handler
- * @file: file ptr
- * @priv: file handle
- * @reqbuf: request buffer structure ptr
- */
-static int vpif_reqbufs(struct file *file, void *priv,
-			struct v4l2_requestbuffers *reqbuf)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common;
-	u8 index = 0;
-	struct vb2_queue *q;
-	int ret;
-
-	vpif_dbg(2, debug, "vpif_reqbufs\n");
-
-	/**
-	 * This file handle has not initialized the channel,
-	 * It is not allowed to do settings
-	 */
-	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
-	    || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
-		if (!fh->initialized) {
-			vpif_dbg(1, debug, "Channel Busy\n");
-			return -EBUSY;
-		}
-	}
-
-	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type || !vpif_dev)
-		return -EINVAL;
-
-	index = VPIF_VIDEO_INDEX;
-
-	common = &ch->common[index];
-
-	if (0 != common->io_usrs)
-		return -EBUSY;
-
-	/* Initialize videobuf2 queue as per the buffer type */
-	common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
-	if (IS_ERR(common->alloc_ctx)) {
-		vpif_err("Failed to get the context\n");
-		return PTR_ERR(common->alloc_ctx);
-	}
-	q = &common->buffer_queue;
-	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	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 vpif_cap_buffer);
-	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-	q->min_buffers_needed = 1;
-
-	ret = vb2_queue_init(q);
-	if (ret) {
-		vpif_err("vpif_capture: vb2_queue_init() failed\n");
-		vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
-		return ret;
-	}
-	/* Set io allowed member of file handle to TRUE */
-	fh->io_allowed[index] = 1;
-	/* Increment io usrs member of channel object to 1 */
-	common->io_usrs = 1;
-	/* Store type of memory requested in channel object */
-	common->memory = reqbuf->memory;
-	INIT_LIST_HEAD(&common->dma_queue);
-
-	/* Allocate buffers */
-	return vb2_reqbufs(&common->buffer_queue, reqbuf);
-}
-
-/**
- * vpif_querybuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_querybuf(struct file *file, void *priv,
-				struct v4l2_buffer *buf)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-	vpif_dbg(2, debug, "vpif_querybuf\n");
-
-	if (common->fmt.type != buf->type)
-		return -EINVAL;
-
-	if (common->memory != V4L2_MEMORY_MMAP) {
-		vpif_dbg(1, debug, "Invalid memory\n");
-		return -EINVAL;
-	}
-
-	return vb2_querybuf(&common->buffer_queue, buf);
-}
-
-/**
- * vpif_qbuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	struct v4l2_buffer tbuf = *buf;
-
-	vpif_dbg(2, debug, "vpif_qbuf\n");
-
-	if (common->fmt.type != tbuf.type) {
-		vpif_err("invalid buffer type\n");
-		return -EINVAL;
-	}
-
-	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
-		vpif_err("fh io not allowed\n");
-		return -EACCES;
-	}
-
-	return vb2_qbuf(&common->buffer_queue, buf);
-}
-
-/**
- * vpif_dqbuf() - query buffer handler
- * @file: file ptr
- * @priv: file handle
- * @buf: v4l2 buffer structure ptr
- */
-static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-	vpif_dbg(2, debug, "vpif_dqbuf\n");
-
-	return vb2_dqbuf(&common->buffer_queue, buf,
-			 (file->f_flags & O_NONBLOCK));
-}
-
-/**
- * vpif_streamon() - streamon handler
- * @file: file ptr
- * @priv: file handle
- * @buftype: v4l2 buffer type
- */
-static int vpif_streamon(struct file *file, void *priv,
-				enum v4l2_buf_type buftype)
-{
-
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
-	struct vpif_params *vpif;
-	int ret = 0;
-
-	vpif_dbg(2, debug, "vpif_streamon\n");
-
-	vpif = &ch->vpifparams;
-
-	if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		vpif_dbg(1, debug, "buffer type not supported\n");
-		return -EINVAL;
-	}
-
-	/* If file handle is not allowed IO, return error */
-	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
-		vpif_dbg(1, debug, "io not allowed\n");
-		return -EACCES;
-	}
-
-	/* If Streaming is already started, return error */
-	if (common->started) {
-		vpif_dbg(1, debug, "channel->started\n");
-		return -EBUSY;
-	}
-
-	if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
-	    oth_ch->common[VPIF_VIDEO_INDEX].started &&
-	    vpif->std_info.ycmux_mode == 0) ||
-	   ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
-	    (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
-		vpif_dbg(1, debug, "other channel is being used\n");
-		return -EBUSY;
-	}
-
-	ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
-	if (ret)
-		return ret;
-
-	/* Enable streamon on the sub device */
-	ret = v4l2_subdev_call(ch->sd, video, s_stream, 1);
-
-	if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
-		vpif_dbg(1, debug, "stream on failed in subdev\n");
-		return ret;
-	}
-
-	/* Call vb2_streamon to start streaming in videobuf2 */
-	ret = vb2_streamon(&common->buffer_queue, buftype);
-	if (ret) {
-		vpif_dbg(1, debug, "vb2_streamon\n");
-		return ret;
-	}
-
-	return ret;
-}
-
-/**
- * vpif_streamoff() - streamoff handler
- * @file: file ptr
- * @priv: file handle
- * @buftype: v4l2 buffer type
- */
-static int vpif_streamoff(struct file *file, void *priv,
-				enum v4l2_buf_type buftype)
-{
-
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	int ret;
-
-	vpif_dbg(2, debug, "vpif_streamoff\n");
-
-	if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		vpif_dbg(1, debug, "buffer type not supported\n");
-		return -EINVAL;
-	}
-
-	/* If io is allowed for this file handle, return error */
-	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
-		vpif_dbg(1, debug, "io not allowed\n");
-		return -EACCES;
-	}
-
-	/* If streaming is not started, return error */
-	if (!common->started) {
-		vpif_dbg(1, debug, "channel->started\n");
-		return -EINVAL;
-	}
-
-	/* disable channel */
-	if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
-		enable_channel0(0);
-		channel0_intr_enable(0);
-	} else {
-		enable_channel1(0);
-		channel1_intr_enable(0);
-	}
-
-	common->started = 0;
-
-	ret = v4l2_subdev_call(ch->sd, video, s_stream, 0);
-
-	if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
-		vpif_dbg(1, debug, "stream off failed in subdev\n");
-
-	return vb2_streamoff(&common->buffer_queue, buftype);
-}
-
 /**
 /**
  * vpif_input_to_subdev() - Maps input to sub device
  * vpif_input_to_subdev() - Maps input to sub device
  * @vpif_cfg - global config ptr
  * @vpif_cfg - global config ptr
@@ -1348,8 +861,8 @@ static int vpif_set_input(
  */
  */
 static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
 static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	int ret = 0;
 	int ret = 0;
 
 
 	vpif_dbg(2, debug, "vpif_querystd\n");
 	vpif_dbg(2, debug, "vpif_querystd\n");
@@ -1375,11 +888,22 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
  */
  */
 static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
 static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
+	struct vpif_capture_chan_config *chan_cfg;
+	struct v4l2_input input;
 
 
 	vpif_dbg(2, debug, "vpif_g_std\n");
 	vpif_dbg(2, debug, "vpif_g_std\n");
 
 
+	if (config->chan_config[ch->channel_id].inputs == NULL)
+		return -ENODATA;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+	input = chan_cfg->inputs[ch->input_idx].input;
+	if (input.capabilities != V4L2_IN_CAP_STD)
+		return -ENODATA;
+
 	*std = ch->video.stdid;
 	*std = ch->video.stdid;
 	return 0;
 	return 0;
 }
 }
@@ -1392,31 +916,26 @@ static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
  */
  */
 static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	int ret = 0;
+	struct vpif_capture_chan_config *chan_cfg;
+	struct v4l2_input input;
+	int ret;
 
 
 	vpif_dbg(2, debug, "vpif_s_std\n");
 	vpif_dbg(2, debug, "vpif_s_std\n");
 
 
-	if (common->started) {
-		vpif_err("streaming in progress\n");
-		return -EBUSY;
-	}
-
-	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
-	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
-		if (!fh->initialized) {
-			vpif_dbg(1, debug, "Channel Busy\n");
-			return -EBUSY;
-		}
-	}
+	if (config->chan_config[ch->channel_id].inputs == NULL)
+		return -ENODATA;
 
 
-	ret = v4l2_prio_check(&ch->prio, fh->prio);
-	if (0 != ret)
-		return ret;
+	chan_cfg = &config->chan_config[ch->channel_id];
+	input = chan_cfg->inputs[ch->input_idx].input;
+	if (input.capabilities != V4L2_IN_CAP_STD)
+		return -ENODATA;
 
 
-	fh->initialized = 1;
+	if (vb2_is_busy(&common->buffer_queue))
+		return -EBUSY;
 
 
 	/* Call encoder subdevice function to set the standard */
 	/* Call encoder subdevice function to set the standard */
 	ch->video.stdid = std_id;
 	ch->video.stdid = std_id;
@@ -1432,7 +951,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 	vpif_config_format(ch);
 	vpif_config_format(ch);
 
 
 	/* set standard in the sub device */
 	/* set standard in the sub device */
-	ret = v4l2_subdev_call(ch->sd, core, s_std, std_id);
+	ret = v4l2_subdev_call(ch->sd, video, s_std, std_id);
 	if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
 	if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
 		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
 		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
 		return ret;
 		return ret;
@@ -1451,9 +970,9 @@ static int vpif_enum_input(struct file *file, void *priv,
 {
 {
 
 
 	struct vpif_capture_config *config = vpif_dev->platform_data;
 	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct vpif_capture_chan_config *chan_cfg;
 	struct vpif_capture_chan_config *chan_cfg;
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
 
 
 	chan_cfg = &config->chan_config[ch->channel_id];
 	chan_cfg = &config->chan_config[ch->channel_id];
 
 
@@ -1475,8 +994,8 @@ static int vpif_enum_input(struct file *file, void *priv,
  */
  */
 static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
 static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 
 
 	*index = ch->input_idx;
 	*index = ch->input_idx;
 	return 0;
 	return 0;
@@ -1491,35 +1010,19 @@ static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
 static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 {
 {
 	struct vpif_capture_config *config = vpif_dev->platform_data;
 	struct vpif_capture_config *config = vpif_dev->platform_data;
-	struct vpif_capture_chan_config *chan_cfg;
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	int ret;
+	struct vpif_capture_chan_config *chan_cfg;
 
 
 	chan_cfg = &config->chan_config[ch->channel_id];
 	chan_cfg = &config->chan_config[ch->channel_id];
 
 
 	if (index >= chan_cfg->input_count)
 	if (index >= chan_cfg->input_count)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (common->started) {
-		vpif_err("Streaming in progress\n");
+	if (vb2_is_busy(&common->buffer_queue))
 		return -EBUSY;
 		return -EBUSY;
-	}
-
-	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
-	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
-		if (!fh->initialized) {
-			vpif_dbg(1, debug, "Channel Busy\n");
-			return -EBUSY;
-		}
-	}
-
-	ret = v4l2_prio_check(&ch->prio, fh->prio);
-	if (0 != ret)
-		return ret;
 
 
-	fh->initialized = 1;
 	return vpif_set_input(config, ch, index);
 	return vpif_set_input(config, ch, index);
 }
 }
 
 
@@ -1532,8 +1035,8 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index)
 static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
 					struct v4l2_fmtdesc *fmt)
 					struct v4l2_fmtdesc *fmt)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 
 
 	if (fmt->index != 0) {
 	if (fmt->index != 0) {
 		vpif_dbg(1, debug, "Invalid format index\n");
 		vpif_dbg(1, debug, "Invalid format index\n");
@@ -1562,8 +1065,8 @@ static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
 static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *fmt)
 				struct v4l2_format *fmt)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
 	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
 
 
 	return vpif_check_format(ch, pixfmt, 1);
 	return vpif_check_format(ch, pixfmt, 1);
@@ -1579,8 +1082,8 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
 static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
 static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *fmt)
 				struct v4l2_format *fmt)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
 
 	/* Check the validity of the buffer type */
 	/* Check the validity of the buffer type */
@@ -1601,33 +1104,16 @@ static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
 static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
 static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *fmt)
 				struct v4l2_format *fmt)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct v4l2_pix_format *pixfmt;
 	struct v4l2_pix_format *pixfmt;
 	int ret = 0;
 	int ret = 0;
 
 
 	vpif_dbg(2, debug, "%s\n", __func__);
 	vpif_dbg(2, debug, "%s\n", __func__);
 
 
-	/* If streaming is started, return error */
-	if (common->started) {
-		vpif_dbg(1, debug, "Streaming is started\n");
+	if (vb2_is_busy(&common->buffer_queue))
 		return -EBUSY;
 		return -EBUSY;
-	}
-
-	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
-	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
-		if (!fh->initialized) {
-			vpif_dbg(1, debug, "Channel Busy\n");
-			return -EBUSY;
-		}
-	}
-
-	ret = v4l2_prio_check(&ch->prio, fh->prio);
-	if (0 != ret)
-		return ret;
-
-	fh->initialized = 1;
 
 
 	pixfmt = &fmt->fmt.pix;
 	pixfmt = &fmt->fmt.pix;
 	/* Check for valid field format */
 	/* Check for valid field format */
@@ -1653,7 +1139,7 @@ static int vpif_querycap(struct file *file, void  *priv,
 
 
 	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-	snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev));
+	strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 		 dev_name(vpif_dev));
 		 dev_name(vpif_dev));
 	strlcpy(cap->card, config->card_name, sizeof(cap->card));
 	strlcpy(cap->card, config->card_name, sizeof(cap->card));
@@ -1661,61 +1147,6 @@ static int vpif_querycap(struct file *file, void  *priv,
 	return 0;
 	return 0;
 }
 }
 
 
-/**
- * vpif_g_priority() - get priority handler
- * @file: file ptr
- * @priv: file handle
- * @prio: ptr to v4l2_priority structure
- */
-static int vpif_g_priority(struct file *file, void *priv,
-			   enum v4l2_priority *prio)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	*prio = v4l2_prio_max(&ch->prio);
-
-	return 0;
-}
-
-/**
- * vpif_s_priority() - set priority handler
- * @file: file ptr
- * @priv: file handle
- * @prio: ptr to v4l2_priority structure
- */
-static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_prio_change(&ch->prio, &fh->prio, p);
-}
-
-/**
- * vpif_cropcap() - cropcap handler
- * @file: file ptr
- * @priv: file handle
- * @crop: ptr to v4l2_cropcap structure
- */
-static int vpif_cropcap(struct file *file, void *priv,
-			struct v4l2_cropcap *crop)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
-		return -EINVAL;
-
-	crop->bounds.left = 0;
-	crop->bounds.top = 0;
-	crop->bounds.height = common->height;
-	crop->bounds.width = common->width;
-	crop->defrect = crop->bounds;
-	return 0;
-}
-
 /**
 /**
  * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
  * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
  * @file: file ptr
  * @file: file ptr
@@ -1726,13 +1157,27 @@ static int
 vpif_enum_dv_timings(struct file *file, void *priv,
 vpif_enum_dv_timings(struct file *file, void *priv,
 		     struct v4l2_enum_dv_timings *timings)
 		     struct v4l2_enum_dv_timings *timings)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
+	struct vpif_capture_chan_config *chan_cfg;
+	struct v4l2_input input;
 	int ret;
 	int ret;
 
 
-	ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
+	if (config->chan_config[ch->channel_id].inputs == NULL)
+		return -ENODATA;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+	input = chan_cfg->inputs[ch->input_idx].input;
+	if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
+		return -ENODATA;
+
+	timings->pad = 0;
+
+	ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings);
 	if (ret == -ENOIOCTLCMD || ret == -ENODEV)
 	if (ret == -ENOIOCTLCMD || ret == -ENODEV)
 		return -EINVAL;
 		return -EINVAL;
+
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1746,13 +1191,25 @@ static int
 vpif_query_dv_timings(struct file *file, void *priv,
 vpif_query_dv_timings(struct file *file, void *priv,
 		      struct v4l2_dv_timings *timings)
 		      struct v4l2_dv_timings *timings)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
+	struct vpif_capture_chan_config *chan_cfg;
+	struct v4l2_input input;
 	int ret;
 	int ret;
 
 
+	if (config->chan_config[ch->channel_id].inputs == NULL)
+		return -ENODATA;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+	input = chan_cfg->inputs[ch->input_idx].input;
+	if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
+		return -ENODATA;
+
 	ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
 	ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings);
 	if (ret == -ENOIOCTLCMD || ret == -ENODEV)
 	if (ret == -ENOIOCTLCMD || ret == -ENODEV)
 		return -ENODATA;
 		return -ENODATA;
+
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1765,19 +1222,34 @@ vpif_query_dv_timings(struct file *file, void *priv,
 static int vpif_s_dv_timings(struct file *file, void *priv,
 static int vpif_s_dv_timings(struct file *file, void *priv,
 		struct v4l2_dv_timings *timings)
 		struct v4l2_dv_timings *timings)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct vpif_params *vpifparams = &ch->vpifparams;
 	struct vpif_params *vpifparams = &ch->vpifparams;
 	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
 	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct video_obj *vid_ch = &ch->video;
 	struct video_obj *vid_ch = &ch->video;
 	struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
 	struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
+	struct vpif_capture_chan_config *chan_cfg;
+	struct v4l2_input input;
 	int ret;
 	int ret;
 
 
+	if (config->chan_config[ch->channel_id].inputs == NULL)
+		return -ENODATA;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+	input = chan_cfg->inputs[ch->input_idx].input;
+	if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
+		return -ENODATA;
+
 	if (timings->type != V4L2_DV_BT_656_1120) {
 	if (timings->type != V4L2_DV_BT_656_1120) {
 		vpif_dbg(2, debug, "Timing type not defined\n");
 		vpif_dbg(2, debug, "Timing type not defined\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
+	if (vb2_is_busy(&common->buffer_queue))
+		return -EBUSY;
+
 	/* Configure subdevice timings, if any */
 	/* Configure subdevice timings, if any */
 	ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
 	ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings);
 	if (ret == -ENOIOCTLCMD || ret == -ENODEV)
 	if (ret == -ENOIOCTLCMD || ret == -ENODEV)
@@ -1853,9 +1325,20 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
 static int vpif_g_dv_timings(struct file *file, void *priv,
 static int vpif_g_dv_timings(struct file *file, void *priv,
 		struct v4l2_dv_timings *timings)
 		struct v4l2_dv_timings *timings)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct video_obj *vid_ch = &ch->video;
 	struct video_obj *vid_ch = &ch->video;
+	struct vpif_capture_chan_config *chan_cfg;
+	struct v4l2_input input;
+
+	if (config->chan_config[ch->channel_id].inputs == NULL)
+		return -ENODATA;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+	input = chan_cfg->inputs[ch->input_idx].input;
+	if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS)
+		return -ENODATA;
 
 
 	*timings = vid_ch->dv_timings;
 	*timings = vid_ch->dv_timings;
 
 
@@ -1879,49 +1362,45 @@ static int vpif_log_status(struct file *filep, void *priv)
 
 
 /* vpif capture ioctl operations */
 /* vpif capture ioctl operations */
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
-	.vidioc_querycap        	= vpif_querycap,
-	.vidioc_g_priority		= vpif_g_priority,
-	.vidioc_s_priority		= vpif_s_priority,
+	.vidioc_querycap		= vpif_querycap,
 	.vidioc_enum_fmt_vid_cap	= vpif_enum_fmt_vid_cap,
 	.vidioc_enum_fmt_vid_cap	= vpif_enum_fmt_vid_cap,
-	.vidioc_g_fmt_vid_cap  		= vpif_g_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap		= vpif_g_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap		= vpif_s_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap		= vpif_s_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap		= vpif_try_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap		= vpif_try_fmt_vid_cap,
+
 	.vidioc_enum_input		= vpif_enum_input,
 	.vidioc_enum_input		= vpif_enum_input,
 	.vidioc_s_input			= vpif_s_input,
 	.vidioc_s_input			= vpif_s_input,
 	.vidioc_g_input			= vpif_g_input,
 	.vidioc_g_input			= vpif_g_input,
-	.vidioc_reqbufs         	= vpif_reqbufs,
-	.vidioc_querybuf        	= vpif_querybuf,
+
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
+	.vidioc_expbuf			= vb2_ioctl_expbuf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
+
 	.vidioc_querystd		= vpif_querystd,
 	.vidioc_querystd		= vpif_querystd,
-	.vidioc_s_std           	= vpif_s_std,
+	.vidioc_s_std			= vpif_s_std,
 	.vidioc_g_std			= vpif_g_std,
 	.vidioc_g_std			= vpif_g_std,
-	.vidioc_qbuf            	= vpif_qbuf,
-	.vidioc_dqbuf           	= vpif_dqbuf,
-	.vidioc_streamon        	= vpif_streamon,
-	.vidioc_streamoff       	= vpif_streamoff,
-	.vidioc_cropcap         	= vpif_cropcap,
-	.vidioc_enum_dv_timings         = vpif_enum_dv_timings,
-	.vidioc_query_dv_timings        = vpif_query_dv_timings,
-	.vidioc_s_dv_timings            = vpif_s_dv_timings,
-	.vidioc_g_dv_timings            = vpif_g_dv_timings,
+
+	.vidioc_enum_dv_timings		= vpif_enum_dv_timings,
+	.vidioc_query_dv_timings	= vpif_query_dv_timings,
+	.vidioc_s_dv_timings		= vpif_s_dv_timings,
+	.vidioc_g_dv_timings		= vpif_g_dv_timings,
+
 	.vidioc_log_status		= vpif_log_status,
 	.vidioc_log_status		= vpif_log_status,
 };
 };
 
 
 /* vpif file operations */
 /* vpif file operations */
 static struct v4l2_file_operations vpif_fops = {
 static struct v4l2_file_operations vpif_fops = {
 	.owner = THIS_MODULE,
 	.owner = THIS_MODULE,
-	.open = vpif_open,
-	.release = vpif_release,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
 	.unlocked_ioctl = video_ioctl2,
 	.unlocked_ioctl = video_ioctl2,
-	.mmap = vpif_mmap,
-	.poll = vpif_poll
-};
-
-/* vpif video template */
-static struct video_device vpif_video_template = {
-	.name		= "vpif",
-	.fops		= &vpif_fops,
-	.minor		= -1,
-	.ioctl_ops	= &vpif_ioctl_ops,
+	.mmap = vb2_fop_mmap,
+	.poll = vb2_fop_poll
 };
 };
 
 
 /**
 /**
@@ -1999,7 +1478,9 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
 static int vpif_probe_complete(void)
 static int vpif_probe_complete(void)
 {
 {
 	struct common_obj *common;
 	struct common_obj *common;
+	struct video_device *vdev;
 	struct channel_obj *ch;
 	struct channel_obj *ch;
+	struct vb2_queue *q;
 	int i, j, err, k;
 	int i, j, err, k;
 
 
 	for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
 	for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
@@ -2008,17 +1489,52 @@ static int vpif_probe_complete(void)
 		common = &(ch->common[VPIF_VIDEO_INDEX]);
 		common = &(ch->common[VPIF_VIDEO_INDEX]);
 		spin_lock_init(&common->irqlock);
 		spin_lock_init(&common->irqlock);
 		mutex_init(&common->lock);
 		mutex_init(&common->lock);
-		ch->video_dev->lock = &common->lock;
-		/* Initialize prio member of channel object */
-		v4l2_prio_init(&ch->prio);
-		video_set_drvdata(ch->video_dev, ch);
 
 
 		/* select input 0 */
 		/* select input 0 */
 		err = vpif_set_input(vpif_obj.config, ch, 0);
 		err = vpif_set_input(vpif_obj.config, ch, 0);
 		if (err)
 		if (err)
 			goto probe_out;
 			goto probe_out;
 
 
-		err = video_register_device(ch->video_dev,
+		/* Initialize vb2 queue */
+		q = &common->buffer_queue;
+		q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+		q->drv_priv = ch;
+		q->ops = &video_qops;
+		q->mem_ops = &vb2_dma_contig_memops;
+		q->buf_struct_size = sizeof(struct vpif_cap_buffer);
+		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+		q->min_buffers_needed = 1;
+		q->lock = &common->lock;
+
+		err = vb2_queue_init(q);
+		if (err) {
+			vpif_err("vpif_capture: vb2_queue_init() failed\n");
+			goto probe_out;
+		}
+
+		common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
+		if (IS_ERR(common->alloc_ctx)) {
+			vpif_err("Failed to get the context\n");
+			err = PTR_ERR(common->alloc_ctx);
+			goto probe_out;
+		}
+
+		INIT_LIST_HEAD(&common->dma_queue);
+
+		/* Initialize the video_device structure */
+		vdev = ch->video_dev;
+		strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
+		vdev->release = video_device_release;
+		vdev->fops = &vpif_fops;
+		vdev->ioctl_ops = &vpif_ioctl_ops;
+		vdev->v4l2_dev = &vpif_obj.v4l2_dev;
+		vdev->vfl_dir = VFL_DIR_RX;
+		vdev->queue = q;
+		vdev->lock = &common->lock;
+		set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
+		video_set_drvdata(ch->video_dev, ch);
+		err = video_register_device(vdev,
 					    VFL_TYPE_GRABBER, (j ? 1 : 0));
 					    VFL_TYPE_GRABBER, (j ? 1 : 0));
 		if (err)
 		if (err)
 			goto probe_out;
 			goto probe_out;
@@ -2031,6 +1547,8 @@ probe_out:
 	for (k = 0; k < j; k++) {
 	for (k = 0; k < j; k++) {
 		/* Get the pointer to the channel object */
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[k];
 		ch = vpif_obj.dev[k];
+		common = &ch->common[k];
+		vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
 		/* Unregister video device */
 		/* Unregister video device */
 		video_unregister_device(ch->video_dev);
 		video_unregister_device(ch->video_dev);
 	}
 	}
@@ -2067,7 +1585,6 @@ static __init int vpif_probe(struct platform_device *pdev)
 	struct video_device *vfd;
 	struct video_device *vfd;
 	struct resource *res;
 	struct resource *res;
 	int subdev_count;
 	int subdev_count;
-	size_t size;
 
 
 	vpif_dev = &pdev->dev;
 	vpif_dev = &pdev->dev;
 
 
@@ -2085,7 +1602,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 
 
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
 		err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
 		err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
-					IRQF_SHARED, "VPIF_Capture",
+					IRQF_SHARED, VPIF_DRIVER_NAME,
 					(void *)(&vpif_obj.dev[res_idx]->
 					(void *)(&vpif_obj.dev[res_idx]->
 					channel_id));
 					channel_id));
 		if (err) {
 		if (err) {
@@ -2109,34 +1626,10 @@ static __init int vpif_probe(struct platform_device *pdev)
 			goto vpif_unregister;
 			goto vpif_unregister;
 		}
 		}
 
 
-		/* Initialize field of video device */
-		*vfd = vpif_video_template;
-		vfd->v4l2_dev = &vpif_obj.v4l2_dev;
-		vfd->release = video_device_release;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "VPIF_Capture_DRIVER_V%s",
-			 VPIF_CAPTURE_VERSION);
 		/* Set video_dev to the video device */
 		/* Set video_dev to the video device */
 		ch->video_dev = vfd;
 		ch->video_dev = vfd;
 	}
 	}
 
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res) {
-		size = resource_size(res);
-		/* The resources are divided into two equal memory and when we
-		 * have HD output we can add them together
-		 */
-		for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
-			ch = vpif_obj.dev[j];
-			ch->channel_id = j;
-			/* only enabled if second resource exists */
-			config_params.video_limit[ch->channel_id] = 0;
-			if (size)
-				config_params.video_limit[ch->channel_id] =
-									size/2;
-		}
-	}
-
 	vpif_obj.config = pdev->dev.platform_data;
 	vpif_obj.config = pdev->dev.platform_data;
 
 
 	subdev_count = vpif_obj.config->subdev_count;
 	subdev_count = vpif_obj.config->subdev_count;
@@ -2209,6 +1702,7 @@ vpif_unregister:
  */
  */
 static int vpif_remove(struct platform_device *device)
 static int vpif_remove(struct platform_device *device)
 {
 {
+	struct common_obj *common;
 	struct channel_obj *ch;
 	struct channel_obj *ch;
 	int i;
 	int i;
 
 
@@ -2219,6 +1713,8 @@ static int vpif_remove(struct platform_device *device)
 	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
 	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
 		/* Get the pointer to the channel object */
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[i];
 		ch = vpif_obj.dev[i];
+		common = &ch->common[i];
+		vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
 		/* Unregister video device */
 		/* Unregister video device */
 		video_unregister_device(ch->video_dev);
 		video_unregister_device(ch->video_dev);
 		kfree(vpif_obj.dev[i]);
 		kfree(vpif_obj.dev[i]);
@@ -2226,7 +1722,7 @@ static int vpif_remove(struct platform_device *device)
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /**
 /**
  * vpif_suspend: vpif device suspend
  * vpif_suspend: vpif device suspend
  */
  */
@@ -2241,18 +1737,20 @@ static int vpif_suspend(struct device *dev)
 		/* Get the pointer to the channel object */
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[i];
 		ch = vpif_obj.dev[i];
 		common = &ch->common[VPIF_VIDEO_INDEX];
 		common = &ch->common[VPIF_VIDEO_INDEX];
+
+		if (!vb2_is_streaming(&common->buffer_queue))
+			continue;
+
 		mutex_lock(&common->lock);
 		mutex_lock(&common->lock);
-		if (ch->usrs && common->io_usrs) {
-			/* Disable channel */
-			if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
-				enable_channel0(0);
-				channel0_intr_enable(0);
-			}
-			if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
-			    common->started == 2) {
-				enable_channel1(0);
-				channel1_intr_enable(0);
-			}
+		/* Disable channel */
+		if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
+			enable_channel0(0);
+			channel0_intr_enable(0);
+		}
+		if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
+			ycmux_mode == 2) {
+			enable_channel1(0);
+			channel1_intr_enable(0);
 		}
 		}
 		mutex_unlock(&common->lock);
 		mutex_unlock(&common->lock);
 	}
 	}
@@ -2273,40 +1771,35 @@ static int vpif_resume(struct device *dev)
 		/* Get the pointer to the channel object */
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[i];
 		ch = vpif_obj.dev[i];
 		common = &ch->common[VPIF_VIDEO_INDEX];
 		common = &ch->common[VPIF_VIDEO_INDEX];
+
+		if (!vb2_is_streaming(&common->buffer_queue))
+			continue;
+
 		mutex_lock(&common->lock);
 		mutex_lock(&common->lock);
-		if (ch->usrs && common->io_usrs) {
-			/* Disable channel */
-			if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
-				enable_channel0(1);
-				channel0_intr_enable(1);
-			}
-			if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
-			    common->started == 2) {
-				enable_channel1(1);
-				channel1_intr_enable(1);
-			}
+		/* Enable channel */
+		if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
+			enable_channel0(1);
+			channel0_intr_enable(1);
+		}
+		if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
+			ycmux_mode == 2) {
+			enable_channel1(1);
+			channel1_intr_enable(1);
 		}
 		}
 		mutex_unlock(&common->lock);
 		mutex_unlock(&common->lock);
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
-
-static const struct dev_pm_ops vpif_dev_pm_ops = {
-	.suspend = vpif_suspend,
-	.resume = vpif_resume,
-};
-
-#define vpif_pm_ops (&vpif_dev_pm_ops)
-#else
-#define vpif_pm_ops NULL
 #endif
 #endif
 
 
+static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);
+
 static __refdata struct platform_driver vpif_driver = {
 static __refdata struct platform_driver vpif_driver = {
 	.driver	= {
 	.driver	= {
-		.name	= "vpif_capture",
+		.name	= VPIF_DRIVER_NAME,
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
-		.pm	= vpif_pm_ops,
+		.pm	= &vpif_pm_ops,
 	},
 	},
 	.probe = vpif_probe,
 	.probe = vpif_probe,
 	.remove = vpif_remove,
 	.remove = vpif_remove,

+ 0 - 28
drivers/media/platform/davinci/vpif_capture.h

@@ -19,8 +19,6 @@
 #ifndef VPIF_CAPTURE_H
 #ifndef VPIF_CAPTURE_H
 #define VPIF_CAPTURE_H
 #define VPIF_CAPTURE_H
 
 
-#ifdef __KERNEL__
-
 /* Header files */
 /* Header files */
 #include <media/videobuf2-dma-contig.h>
 #include <media/videobuf2-dma-contig.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-device.h>
@@ -63,11 +61,6 @@ struct common_obj {
 	struct vpif_cap_buffer *cur_frm;
 	struct vpif_cap_buffer *cur_frm;
 	/* Pointer pointing to current v4l2_buffer */
 	/* Pointer pointing to current v4l2_buffer */
 	struct vpif_cap_buffer *next_frm;
 	struct vpif_cap_buffer *next_frm;
-	/*
-	 * This field keeps track of type of buffer exchange mechanism
-	 * user has selected
-	 */
-	enum v4l2_memory memory;
 	/* Used to store pixel format */
 	/* Used to store pixel format */
 	struct v4l2_format fmt;
 	struct v4l2_format fmt;
 	/* Buffer queue used in video-buf */
 	/* Buffer queue used in video-buf */
@@ -80,10 +73,6 @@ struct common_obj {
 	spinlock_t irqlock;
 	spinlock_t irqlock;
 	/* lock used to access this structure */
 	/* lock used to access this structure */
 	struct mutex lock;
 	struct mutex lock;
-	/* number of users performing IO */
-	u32 io_usrs;
-	/* Indicates whether streaming started */
-	u8 started;
 	/* Function pointer to set the addresses */
 	/* Function pointer to set the addresses */
 	void (*set_addr) (unsigned long, unsigned long, unsigned long,
 	void (*set_addr) (unsigned long, unsigned long, unsigned long,
 			  unsigned long);
 			  unsigned long);
@@ -104,10 +93,6 @@ struct common_obj {
 struct channel_obj {
 struct channel_obj {
 	/* Identifies video device for this channel */
 	/* Identifies video device for this channel */
 	struct video_device *video_dev;
 	struct video_device *video_dev;
-	/* Used to keep track of state of the priority */
-	struct v4l2_prio_state prio;
-	/* number of open instances of the channel */
-	int usrs;
 	/* Indicates id of the field which is being displayed */
 	/* Indicates id of the field which is being displayed */
 	u32 field_id;
 	u32 field_id;
 	/* flag to indicate whether decoder is initialized */
 	/* flag to indicate whether decoder is initialized */
@@ -126,18 +111,6 @@ struct channel_obj {
 	struct video_obj video;
 	struct video_obj video;
 };
 };
 
 
-/* File handle structure */
-struct vpif_fh {
-	/* pointer to channel object for opened device */
-	struct channel_obj *channel;
-	/* Indicates whether this file handle is doing IO */
-	u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
-	/* Used to keep track priority of this instance */
-	enum v4l2_priority prio;
-	/* Used to indicate channel is initialize or not */
-	u8 initialized;
-};
-
 struct vpif_device {
 struct vpif_device {
 	struct v4l2_device v4l2_dev;
 	struct v4l2_device v4l2_dev;
 	struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
 	struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
@@ -157,5 +130,4 @@ struct vpif_config_params {
 	u8 max_device_type;
 	u8 max_device_type;
 };
 };
 
 
-#endif				/* End of __KERNEL__ */
 #endif				/* VPIF_CAPTURE_H */
 #endif				/* VPIF_CAPTURE_H */

+ 358 - 848
drivers/media/platform/davinci/vpif_display.c

@@ -3,6 +3,7 @@
  * Display driver for TI DaVinci VPIF
  * Display driver for TI DaVinci VPIF
  *
  *
  * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
  * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com>
  *
  *
  * This program is free software; you can redistribute it and/or
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * modify it under the terms of the GNU General Public License as
@@ -35,129 +36,110 @@ MODULE_VERSION(VPIF_DISPLAY_VERSION);
 		v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
 		v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
 
 
 static int debug = 1;
 static int debug = 1;
-static u32 ch2_numbuffers = 3;
-static u32 ch3_numbuffers = 3;
-static u32 ch2_bufsize = 1920 * 1080 * 2;
-static u32 ch3_bufsize = 720 * 576 * 2;
 
 
 module_param(debug, int, 0644);
 module_param(debug, int, 0644);
-module_param(ch2_numbuffers, uint, S_IRUGO);
-module_param(ch3_numbuffers, uint, S_IRUGO);
-module_param(ch2_bufsize, uint, S_IRUGO);
-module_param(ch3_bufsize, uint, S_IRUGO);
 
 
 MODULE_PARM_DESC(debug, "Debug level 0-1");
 MODULE_PARM_DESC(debug, "Debug level 0-1");
-MODULE_PARM_DESC(ch2_numbuffers, "Channel2 buffer count (default:3)");
-MODULE_PARM_DESC(ch3_numbuffers, "Channel3 buffer count (default:3)");
-MODULE_PARM_DESC(ch2_bufsize, "Channel2 buffer size (default:1920 x 1080 x 2)");
-MODULE_PARM_DESC(ch3_bufsize, "Channel3 buffer size (default:720 x 576 x 2)");
-
-static struct vpif_config_params config_params = {
-	.min_numbuffers		= 3,
-	.numbuffers[0]		= 3,
-	.numbuffers[1]		= 3,
-	.min_bufsize[0]		= 720 * 480 * 2,
-	.min_bufsize[1]		= 720 * 480 * 2,
-	.channel_bufsize[0]	= 1920 * 1080 * 2,
-	.channel_bufsize[1]	= 720 * 576 * 2,
-};
+
+#define VPIF_DRIVER_NAME	"vpif_display"
+
+/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */
+static int ycmux_mode;
+
+static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
 
 
 static struct vpif_device vpif_obj = { {NULL} };
 static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
 static struct device *vpif_dev;
 static void vpif_calculate_offsets(struct channel_obj *ch);
 static void vpif_calculate_offsets(struct channel_obj *ch);
 static void vpif_config_addr(struct channel_obj *ch, int muxmode);
 static void vpif_config_addr(struct channel_obj *ch, int muxmode);
 
 
-/*
- * buffer_prepare: 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 inline struct vpif_disp_buffer *to_vpif_buffer(struct vb2_buffer *vb)
+{
+	return container_of(vb, struct vpif_disp_buffer, vb);
+}
+
+/**
+ * vpif_buffer_prepare :  callback function for buffer prepare
+ * @vb: ptr to vb2_buffer
+ *
+ * This is the callback function for buffer prepare when vb2_qbuf()
+ * function is called. The buffer is prepared and user space virtual address
+ * or user address is converted into  physical address
  */
  */
 static int vpif_buffer_prepare(struct vb2_buffer *vb)
 static int vpif_buffer_prepare(struct vb2_buffer *vb)
 {
 {
-	struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
-	struct vb2_queue *q = vb->vb2_queue;
+	struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
 	struct common_obj *common;
 	struct common_obj *common;
-	unsigned long addr;
-
-	common = &fh->channel->common[VPIF_VIDEO_INDEX];
-	if (vb->state != VB2_BUF_STATE_ACTIVE &&
-		vb->state != VB2_BUF_STATE_PREPARED) {
-		vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
-		if (vb2_plane_vaddr(vb, 0) &&
-		vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
-			goto buf_align_exit;
-
-		addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-		if (q->streaming &&
-			(V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
-			if (!ISALIGNED(addr + common->ytop_off) ||
+
+	common = &ch->common[VPIF_VIDEO_INDEX];
+
+	vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
+	if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
+		return -EINVAL;
+
+	vb->v4l2_buf.field = common->fmt.fmt.pix.field;
+
+	if (vb->vb2_queue->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
+		unsigned long addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+
+		if (!ISALIGNED(addr + common->ytop_off) ||
 			!ISALIGNED(addr + common->ybtm_off) ||
 			!ISALIGNED(addr + common->ybtm_off) ||
 			!ISALIGNED(addr + common->ctop_off) ||
 			!ISALIGNED(addr + common->ctop_off) ||
-			!ISALIGNED(addr + common->cbtm_off))
-				goto buf_align_exit;
+			!ISALIGNED(addr + common->cbtm_off)) {
+			vpif_err("buffer offset not aligned to 8 bytes\n");
+			return -EINVAL;
 		}
 		}
 	}
 	}
-	return 0;
 
 
-buf_align_exit:
-	vpif_err("buffer offset not aligned to 8 bytes\n");
-	return -EINVAL;
+	return 0;
 }
 }
 
 
-/*
- * vpif_buffer_queue_setup: This function allocates memory for the buffers
+/**
+ * vpif_buffer_queue_setup : Callback function for buffer setup.
+ * @vq: vb2_queue ptr
+ * @fmt: v4l2 format
+ * @nbuffers: ptr to number of buffers requested by application
+ * @nplanes:: contains number of distinct video planes needed to hold a frame
+ * @sizes[]: contains the size (in bytes) of each plane.
+ * @alloc_ctxs: ptr to allocation context
+ *
+ * This callback function is called when reqbuf() is called to adjust
+ * the buffer count and buffer size
  */
  */
 static int vpif_buffer_queue_setup(struct vb2_queue *vq,
 static int vpif_buffer_queue_setup(struct vb2_queue *vq,
 				const struct v4l2_format *fmt,
 				const struct v4l2_format *fmt,
 				unsigned int *nbuffers, unsigned int *nplanes,
 				unsigned int *nbuffers, unsigned int *nplanes,
 				unsigned int sizes[], void *alloc_ctxs[])
 				unsigned int sizes[], void *alloc_ctxs[])
 {
 {
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
+	struct channel_obj *ch = vb2_get_drv_priv(vq);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	unsigned long size;
-
-	if (V4L2_MEMORY_MMAP == common->memory) {
-		size = config_params.channel_bufsize[ch->channel_id];
-		/*
-		* Checking if the buffer size exceeds the available buffer
-		* ycmux_mode = 0 means 1 channel mode HD and
-		* ycmux_mode = 1 means 2 channels mode SD
-		*/
-		if (ch->vpifparams.std_info.ycmux_mode == 0) {
-			if (config_params.video_limit[ch->channel_id])
-				while (size * *nbuffers >
-					(config_params.video_limit[0]
-						+ config_params.video_limit[1]))
-					(*nbuffers)--;
-		} else {
-			if (config_params.video_limit[ch->channel_id])
-				while (size * *nbuffers >
-				config_params.video_limit[ch->channel_id])
-					(*nbuffers)--;
-		}
-	} else {
-		size = common->fmt.fmt.pix.sizeimage;
-	}
 
 
-	if (*nbuffers < config_params.min_numbuffers)
-			*nbuffers = config_params.min_numbuffers;
+	if (fmt && fmt->fmt.pix.sizeimage < common->fmt.fmt.pix.sizeimage)
+		return -EINVAL;
+
+	if (vq->num_buffers + *nbuffers < 3)
+		*nbuffers = 3 - vq->num_buffers;
 
 
 	*nplanes = 1;
 	*nplanes = 1;
-	sizes[0] = size;
+	sizes[0] = fmt ? fmt->fmt.pix.sizeimage : common->fmt.fmt.pix.sizeimage;
 	alloc_ctxs[0] = common->alloc_ctx;
 	alloc_ctxs[0] = common->alloc_ctx;
+
+	/* Calculate the offset for Y and C data  in the buffer */
+	vpif_calculate_offsets(ch);
+
 	return 0;
 	return 0;
 }
 }
 
 
-/*
- * vpif_buffer_queue: This function adds the buffer to DMA queue
+/**
+ * vpif_buffer_queue : Callback function to add buffer to DMA queue
+ * @vb: ptr to vb2_buffer
+ *
+ * This callback fucntion queues the buffer to DMA engine
  */
  */
 static void vpif_buffer_queue(struct vb2_buffer *vb)
 static void vpif_buffer_queue(struct vb2_buffer *vb)
 {
 {
-	struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
-	struct vpif_disp_buffer *buf = container_of(vb,
-				struct vpif_disp_buffer, vb);
-	struct channel_obj *ch = fh->channel;
+	struct vpif_disp_buffer *buf = to_vpif_buffer(vb);
+	struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue);
 	struct common_obj *common;
 	struct common_obj *common;
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -169,98 +151,26 @@ static void vpif_buffer_queue(struct vb2_buffer *vb)
 	spin_unlock_irqrestore(&common->irqlock, flags);
 	spin_unlock_irqrestore(&common->irqlock, flags);
 }
 }
 
 
-/*
- * vpif_buf_cleanup: This function is called from the videobuf2 layer to
- * free memory allocated to the buffers
+/**
+ * vpif_start_streaming : Starts the DMA engine for streaming
+ * @vb: ptr to vb2_buffer
+ * @count: number of buffers
  */
  */
-static void vpif_buf_cleanup(struct vb2_buffer *vb)
-{
-	struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
-	struct vpif_disp_buffer *buf = container_of(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];
-
-	spin_lock_irqsave(&common->irqlock, flags);
-	if (vb->state == VB2_BUF_STATE_ACTIVE)
-		list_del_init(&buf->list);
-	spin_unlock_irqrestore(&common->irqlock, flags);
-}
-
-static void vpif_wait_prepare(struct vb2_queue *vq)
-{
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common;
-
-	common = &ch->common[VPIF_VIDEO_INDEX];
-	mutex_unlock(&common->lock);
-}
-
-static void vpif_wait_finish(struct vb2_queue *vq)
-{
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common;
-
-	common = &ch->common[VPIF_VIDEO_INDEX];
-	mutex_lock(&common->lock);
-}
-
-static int vpif_buffer_init(struct vb2_buffer *vb)
-{
-	struct vpif_disp_buffer *buf = container_of(vb,
-					struct vpif_disp_buffer, vb);
-
-	INIT_LIST_HEAD(&buf->list);
-
-	return 0;
-}
-
-static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
-
 static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 {
 	struct vpif_display_config *vpif_config_data =
 	struct vpif_display_config *vpif_config_data =
 					vpif_dev->platform_data;
 					vpif_dev->platform_data;
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
+	struct channel_obj *ch = vb2_get_drv_priv(vq);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct vpif_params *vpif = &ch->vpifparams;
 	struct vpif_params *vpif = &ch->vpifparams;
-	unsigned long addr = 0;
-	unsigned long flags;
+	struct vpif_disp_buffer *buf, *tmp;
+	unsigned long addr, flags;
 	int ret;
 	int ret;
 
 
 	spin_lock_irqsave(&common->irqlock, flags);
 	spin_lock_irqsave(&common->irqlock, flags);
 
 
-	/* Get the next frame from the buffer queue */
-	common->next_frm = common->cur_frm =
-			    list_entry(common->dma_queue.next,
-				       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;
-
-	/* Initialize field_id and started member */
+	/* Initialize field_id */
 	ch->field_id = 0;
 	ch->field_id = 0;
-	common->started = 1;
-	addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
-	/* Calculate the offset for Y and C data  in the buffer */
-	vpif_calculate_offsets(ch);
-
-	if ((ch->vpifparams.std_info.frm_fmt &&
-		((common->fmt.fmt.pix.field != V4L2_FIELD_NONE)
-		&& (common->fmt.fmt.pix.field != V4L2_FIELD_ANY)))
-		|| (!ch->vpifparams.std_info.frm_fmt
-		&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
-		vpif_err("conflict in field format and std format\n");
-		return -EINVAL;
-	}
 
 
 	/* clock settings */
 	/* clock settings */
 	if (vpif_config_data->set_clock) {
 	if (vpif_config_data->set_clock) {
@@ -268,24 +178,37 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 		ycmux_mode, ch->vpifparams.std_info.hd_sd);
 		ycmux_mode, ch->vpifparams.std_info.hd_sd);
 		if (ret < 0) {
 		if (ret < 0) {
 			vpif_err("can't set clock\n");
 			vpif_err("can't set clock\n");
-			return ret;
+			goto err;
 		}
 		}
 	}
 	}
 
 
 	/* set the parameters and addresses */
 	/* set the parameters and addresses */
 	ret = vpif_set_video_params(vpif, ch->channel_id + 2);
 	ret = vpif_set_video_params(vpif, ch->channel_id + 2);
 	if (ret < 0)
 	if (ret < 0)
-		return ret;
+		goto err;
 
 
-	common->started = ret;
+	ycmux_mode = ret;
 	vpif_config_addr(ch, ret);
 	vpif_config_addr(ch, ret);
+	/* Get the next frame from the buffer queue */
+	common->next_frm = common->cur_frm =
+			    list_entry(common->dma_queue.next,
+				       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;
+
+	addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
 	common->set_addr((addr + common->ytop_off),
 	common->set_addr((addr + common->ytop_off),
 			    (addr + common->ybtm_off),
 			    (addr + common->ybtm_off),
 			    (addr + common->ctop_off),
 			    (addr + common->ctop_off),
 			    (addr + common->cbtm_off));
 			    (addr + common->cbtm_off));
 
 
-	/* Set interrupt for both the fields in VPIF
-	    Register enable channel in VPIF register */
+	/*
+	 * Set interrupt for both the fields in VPIF
+	 * Register enable channel in VPIF register
+	 */
 	channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
 	channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
 	if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
 	if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
 		channel2_intr_assert();
 		channel2_intr_assert();
@@ -295,8 +218,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 			channel2_clipping_enable(1);
 			channel2_clipping_enable(1);
 	}
 	}
 
 
-	if ((VPIF_CHANNEL3_VIDEO == ch->channel_id)
-		|| (common->started == 2)) {
+	if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) {
 		channel3_intr_assert();
 		channel3_intr_assert();
 		channel3_intr_enable(1);
 		channel3_intr_enable(1);
 		enable_channel3(1);
 		enable_channel3(1);
@@ -305,19 +227,29 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
 	}
 	}
 
 
 	return 0;
 	return 0;
+
+err:
+	list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+	}
+
+	return ret;
 }
 }
 
 
-/* abort streaming and wait for last buffer */
-static int vpif_stop_streaming(struct vb2_queue *vq)
+/**
+ * vpif_stop_streaming : Stop the DMA engine
+ * @vq: ptr to vb2_queue
+ *
+ * This callback stops the DMA engine and any remaining buffers
+ * in the DMA queue are released.
+ */
+static void vpif_stop_streaming(struct vb2_queue *vq)
 {
 {
-	struct vpif_fh *fh = vb2_get_drv_priv(vq);
-	struct channel_obj *ch = fh->channel;
+	struct channel_obj *ch = vb2_get_drv_priv(vq);
 	struct common_obj *common;
 	struct common_obj *common;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	if (!vb2_is_streaming(vq))
-		return 0;
-
 	common = &ch->common[VPIF_VIDEO_INDEX];
 	common = &ch->common[VPIF_VIDEO_INDEX];
 
 
 	/* Disable channel */
 	/* Disable channel */
@@ -325,12 +257,10 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
 		enable_channel2(0);
 		enable_channel2(0);
 		channel2_intr_enable(0);
 		channel2_intr_enable(0);
 	}
 	}
-	if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
-		(2 == common->started)) {
+	if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) {
 		enable_channel3(0);
 		enable_channel3(0);
 		channel3_intr_enable(0);
 		channel3_intr_enable(0);
 	}
 	}
-	common->started = 0;
 
 
 	/* release all active buffers */
 	/* release all active buffers */
 	spin_lock_irqsave(&common->irqlock, flags);
 	spin_lock_irqsave(&common->irqlock, flags);
@@ -352,19 +282,15 @@ static int vpif_stop_streaming(struct vb2_queue *vq)
 		vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
 		vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
 	}
 	}
 	spin_unlock_irqrestore(&common->irqlock, flags);
 	spin_unlock_irqrestore(&common->irqlock, flags);
-
-	return 0;
 }
 }
 
 
 static struct vb2_ops video_qops = {
 static struct vb2_ops video_qops = {
 	.queue_setup		= vpif_buffer_queue_setup,
 	.queue_setup		= vpif_buffer_queue_setup,
-	.wait_prepare		= vpif_wait_prepare,
-	.wait_finish		= vpif_wait_finish,
-	.buf_init		= vpif_buffer_init,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
 	.buf_prepare		= vpif_buffer_prepare,
 	.buf_prepare		= vpif_buffer_prepare,
 	.start_streaming	= vpif_start_streaming,
 	.start_streaming	= vpif_start_streaming,
 	.stop_streaming		= vpif_stop_streaming,
 	.stop_streaming		= vpif_stop_streaming,
-	.buf_cleanup		= vpif_buf_cleanup,
 	.buf_queue		= vpif_buffer_queue,
 	.buf_queue		= vpif_buffer_queue,
 };
 };
 
 
@@ -446,8 +372,6 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
 	for (i = 0; i < VPIF_NUMOBJECTS; i++) {
 	for (i = 0; i < VPIF_NUMOBJECTS; i++) {
 		common = &ch->common[i];
 		common = &ch->common[i];
 		/* If streaming is started in this channel */
 		/* If streaming is started in this channel */
-		if (0 == common->started)
-			continue;
 
 
 		if (1 == ch->vpifparams.std_info.frm_fmt) {
 		if (1 == ch->vpifparams.std_info.frm_fmt) {
 			spin_lock(&common->irqlock);
 			spin_lock(&common->irqlock);
@@ -543,6 +467,7 @@ static int vpif_update_resolution(struct channel_obj *ch)
 			return -EINVAL;
 			return -EINVAL;
 	}
 	}
 
 
+	common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
 	common->fmt.fmt.pix.width = std_info->width;
 	common->fmt.fmt.pix.width = std_info->width;
 	common->fmt.fmt.pix.height = std_info->height;
 	common->fmt.fmt.pix.height = std_info->height;
 	vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
 	vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
@@ -551,6 +476,17 @@ static int vpif_update_resolution(struct channel_obj *ch)
 	/* Set height and width paramateres */
 	/* Set height and width paramateres */
 	common->height = std_info->height;
 	common->height = std_info->height;
 	common->width = std_info->width;
 	common->width = std_info->width;
+	common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
+
+	if (vid_ch->stdid)
+		common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+	else
+		common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+	if (ch->vpifparams.std_info.frm_fmt)
+		common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
+	else
+		common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -621,70 +557,6 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
 	ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
 	ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
 }
 }
 
 
-static void vpif_config_format(struct channel_obj *ch)
-{
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-	common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
-	if (config_params.numbuffers[ch->channel_id] == 0)
-		common->memory = V4L2_MEMORY_USERPTR;
-	else
-		common->memory = V4L2_MEMORY_MMAP;
-
-	common->fmt.fmt.pix.sizeimage =
-			config_params.channel_bufsize[ch->channel_id];
-	common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
-	common->fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-}
-
-static int vpif_check_format(struct channel_obj *ch,
-			     struct v4l2_pix_format *pixfmt)
-{
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	enum v4l2_field field = pixfmt->field;
-	u32 sizeimage, hpitch, vpitch;
-
-	if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
-		goto invalid_fmt_exit;
-
-	if (!(VPIF_VALID_FIELD(field)))
-		goto invalid_fmt_exit;
-
-	if (pixfmt->bytesperline <= 0)
-		goto invalid_pitch_exit;
-
-	sizeimage = pixfmt->sizeimage;
-
-	if (vpif_update_resolution(ch))
-		return -EINVAL;
-
-	hpitch = pixfmt->bytesperline;
-	vpitch = sizeimage / (hpitch * 2);
-
-	/* Check for valid value of pitch */
-	if ((hpitch < ch->vpifparams.std_info.width) ||
-	    (vpitch < ch->vpifparams.std_info.height))
-		goto invalid_pitch_exit;
-
-	/* Check for 8 byte alignment */
-	if (!ISALIGNED(hpitch)) {
-		vpif_err("invalid pitch alignment\n");
-		return -EINVAL;
-	}
-	pixfmt->width = common->fmt.fmt.pix.width;
-	pixfmt->height = common->fmt.fmt.pix.height;
-
-	return 0;
-
-invalid_fmt_exit:
-	vpif_err("invalid field format\n");
-	return -EINVAL;
-
-invalid_pitch_exit:
-	vpif_err("invalid pitch\n");
-	return -EINVAL;
-}
-
 static void vpif_config_addr(struct channel_obj *ch, int muxmode)
 static void vpif_config_addr(struct channel_obj *ch, int muxmode)
 {
 {
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
@@ -699,127 +571,6 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
 	}
 	}
 }
 }
 
 
-/*
- * vpif_mmap: It is used to map kernel space buffers into user spaces
- */
-static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
-{
-	struct vpif_fh *fh = filep->private_data;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
-	int ret;
-
-	vpif_dbg(2, debug, "vpif_mmap\n");
-
-	if (mutex_lock_interruptible(&common->lock))
-		return -ERESTARTSYS;
-	ret = vb2_mmap(&common->buffer_queue, vma);
-	mutex_unlock(&common->lock);
-	return ret;
-}
-
-/*
- * vpif_poll: It is used for select/poll system call
- */
-static unsigned int vpif_poll(struct file *filep, poll_table *wait)
-{
-	struct vpif_fh *fh = filep->private_data;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	unsigned int res = 0;
-
-	if (common->started) {
-		mutex_lock(&common->lock);
-		res = vb2_poll(&common->buffer_queue, filep, wait);
-		mutex_unlock(&common->lock);
-	}
-
-	return res;
-}
-
-/*
- * vpif_open: It creates object of file handle structure and stores it in
- * private_data member of filepointer
- */
-static int vpif_open(struct file *filep)
-{
-	struct video_device *vdev = video_devdata(filep);
-	struct channel_obj *ch = video_get_drvdata(vdev);
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	struct vpif_fh *fh;
-
-	/* Allocate memory for the file handle object */
-	fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
-	if (fh == NULL) {
-		vpif_err("unable to allocate memory for file handle object\n");
-		return -ENOMEM;
-	}
-
-	if (mutex_lock_interruptible(&common->lock)) {
-		kfree(fh);
-		return -ERESTARTSYS;
-	}
-	/* store pointer to fh in private_data member of filep */
-	filep->private_data = fh;
-	fh->channel = ch;
-	fh->initialized = 0;
-	if (!ch->initialized) {
-		fh->initialized = 1;
-		ch->initialized = 1;
-		memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
-	}
-
-	/* Increment channel usrs counter */
-	atomic_inc(&ch->usrs);
-	/* Set io_allowed[VPIF_VIDEO_INDEX] member to false */
-	fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
-	/* Initialize priority of this instance to default priority */
-	fh->prio = V4L2_PRIORITY_UNSET;
-	v4l2_prio_open(&ch->prio, &fh->prio);
-	mutex_unlock(&common->lock);
-
-	return 0;
-}
-
-/*
- * vpif_release: This function deletes buffer queue, frees the buffers and
- * the vpif file handle
- */
-static int vpif_release(struct file *filep)
-{
-	struct vpif_fh *fh = filep->private_data;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-	mutex_lock(&common->lock);
-	/* if this instance is doing IO */
-	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
-		/* Reset io_usrs member of channel object */
-		common->io_usrs = 0;
-		/* Free buffers allocated */
-		vb2_queue_release(&common->buffer_queue);
-		vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
-
-		common->numbuffers =
-		    config_params.numbuffers[ch->channel_id];
-	}
-
-	/* Decrement channel usrs counter */
-	atomic_dec(&ch->usrs);
-	/* If this file handle has initialize encoder device, reset it */
-	if (fh->initialized)
-		ch->initialized = 0;
-
-	/* Close the priority */
-	v4l2_prio_close(&ch->prio, fh->prio);
-	filep->private_data = NULL;
-	fh->initialized = 0;
-	mutex_unlock(&common->lock);
-	kfree(fh);
-
-	return 0;
-}
-
 /* functions implementing ioctls */
 /* functions implementing ioctls */
 /**
 /**
  * vpif_querycap() - QUERYCAP handler
  * vpif_querycap() - QUERYCAP handler
@@ -834,7 +585,7 @@ static int vpif_querycap(struct file *file, void  *priv,
 
 
 	cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
 	cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-	snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev));
+	strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 		 dev_name(vpif_dev));
 		 dev_name(vpif_dev));
 	strlcpy(cap->card, config->card_name, sizeof(cap->card));
 	strlcpy(cap->card, config->card_name, sizeof(cap->card));
@@ -845,24 +596,22 @@ static int vpif_querycap(struct file *file, void  *priv,
 static int vpif_enum_fmt_vid_out(struct file *file, void  *priv,
 static int vpif_enum_fmt_vid_out(struct file *file, void  *priv,
 					struct v4l2_fmtdesc *fmt)
 					struct v4l2_fmtdesc *fmt)
 {
 {
-	if (fmt->index != 0) {
-		vpif_err("Invalid format index\n");
+	if (fmt->index != 0)
 		return -EINVAL;
 		return -EINVAL;
-	}
 
 
 	/* Fill in the information about format */
 	/* Fill in the information about format */
 	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
 	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
 	strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
 	strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
 	fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
 	fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
-
+	fmt->flags = 0;
 	return 0;
 	return 0;
 }
 }
 
 
 static int vpif_g_fmt_vid_out(struct file *file, void *priv,
 static int vpif_g_fmt_vid_out(struct file *file, void *priv,
 				struct v4l2_format *fmt)
 				struct v4l2_format *fmt)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
 
 	/* Check the validity of the buffer type */
 	/* Check the validity of the buffer type */
@@ -875,193 +624,84 @@ static int vpif_g_fmt_vid_out(struct file *file, void *priv,
 	return 0;
 	return 0;
 }
 }
 
 
-static int vpif_s_fmt_vid_out(struct file *file, void *priv,
+static int vpif_try_fmt_vid_out(struct file *file, void *priv,
 				struct v4l2_format *fmt)
 				struct v4l2_format *fmt)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct v4l2_pix_format *pixfmt;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	int ret = 0;
-
-	if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
-	    || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
-		if (!fh->initialized) {
-			vpif_dbg(1, debug, "Channel Busy\n");
-			return -EBUSY;
-		}
+	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
 
 
-		/* Check for the priority */
-		ret = v4l2_prio_check(&ch->prio, fh->prio);
-		if (0 != ret)
-			return ret;
-		fh->initialized = 1;
-	}
+	/*
+	 * to supress v4l-compliance warnings silently correct
+	 * the pixelformat
+	 */
+	if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
+		pixfmt->pixelformat = common->fmt.fmt.pix.pixelformat;
 
 
-	if (common->started) {
-		vpif_dbg(1, debug, "Streaming in progress\n");
-		return -EBUSY;
-	}
+	if (vpif_update_resolution(ch))
+		return -EINVAL;
 
 
-	pixfmt = &fmt->fmt.pix;
-	/* Check for valid field format */
-	ret = vpif_check_format(ch, pixfmt);
-	if (ret)
-		return ret;
+	pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
+	pixfmt->field = common->fmt.fmt.pix.field;
+	pixfmt->bytesperline = common->fmt.fmt.pix.width;
+	pixfmt->width = common->fmt.fmt.pix.width;
+	pixfmt->height = common->fmt.fmt.pix.height;
+	pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
+	pixfmt->priv = 0;
 
 
-	/* store the pix format in the channel object */
-	common->fmt.fmt.pix = *pixfmt;
-	/* store the format in the channel object */
-	common->fmt = *fmt;
 	return 0;
 	return 0;
 }
 }
 
 
-static int vpif_try_fmt_vid_out(struct file *file, void *priv,
+static int vpif_s_fmt_vid_out(struct file *file, void *priv,
 				struct v4l2_format *fmt)
 				struct v4l2_format *fmt)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
 	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-	int ret = 0;
-
-	ret = vpif_check_format(ch, pixfmt);
-	if (ret) {
-		*pixfmt = common->fmt.fmt.pix;
-		pixfmt->sizeimage = pixfmt->width * pixfmt->height * 2;
-	}
-
-	return ret;
-}
-
-static int vpif_reqbufs(struct file *file, void *priv,
-			struct v4l2_requestbuffers *reqbuf)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common;
-	enum v4l2_field field;
-	struct vb2_queue *q;
-	u8 index = 0;
 	int ret;
 	int ret;
 
 
-	/* This file handle has not initialized the channel,
-	   It is not allowed to do settings */
-	if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
-	    || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
-		if (!fh->initialized) {
-			vpif_err("Channel Busy\n");
-			return -EBUSY;
-		}
-	}
-
-	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != reqbuf->type)
-		return -EINVAL;
-
-	index = VPIF_VIDEO_INDEX;
-
-	common = &ch->common[index];
-
-	if (common->fmt.type != reqbuf->type || !vpif_dev)
-		return -EINVAL;
-	if (0 != common->io_usrs)
+	if (vb2_is_busy(&common->buffer_queue))
 		return -EBUSY;
 		return -EBUSY;
 
 
-	if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
-			field = V4L2_FIELD_INTERLACED;
-		else
-			field = common->fmt.fmt.pix.field;
-	} else {
-		field = V4L2_VBI_INTERLACED;
-	}
-	/* Initialize videobuf2 queue as per the buffer type */
-	common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
-	if (IS_ERR(common->alloc_ctx)) {
-		vpif_err("Failed to get the context\n");
-		return PTR_ERR(common->alloc_ctx);
-	}
-	q = &common->buffer_queue;
-	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 vpif_disp_buffer);
-	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-	q->min_buffers_needed = 1;
-
-	ret = vb2_queue_init(q);
-	if (ret) {
-		vpif_err("vpif_display: vb2_queue_init() failed\n");
-		vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
+	ret = vpif_try_fmt_vid_out(file, priv, fmt);
+	if (ret)
 		return ret;
 		return ret;
-	}
-	/* Set io allowed member of file handle to TRUE */
-	fh->io_allowed[index] = 1;
-	/* Increment io usrs member of channel object to 1 */
-	common->io_usrs = 1;
-	/* Store type of memory requested in channel object */
-	common->memory = reqbuf->memory;
-	INIT_LIST_HEAD(&common->dma_queue);
-	/* Allocate buffers */
-	return vb2_reqbufs(&common->buffer_queue, reqbuf);
-}
-
-static int vpif_querybuf(struct file *file, void *priv,
-				struct v4l2_buffer *tbuf)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
 
-	if (common->fmt.type != tbuf->type)
-		return -EINVAL;
+	/* store the pix format in the channel object */
+	common->fmt.fmt.pix = *pixfmt;
 
 
-	return vb2_querybuf(&common->buffer_queue, tbuf);
+	/* store the format in the channel object */
+	common->fmt = *fmt;
+	return 0;
 }
 }
 
 
-static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 {
 {
-	struct vpif_fh *fh = NULL;
-	struct channel_obj *ch = NULL;
-	struct common_obj *common = NULL;
-
-	if (!buf || !priv)
-		return -EINVAL;
-
-	fh = priv;
-	ch = fh->channel;
-	if (!ch)
-		return -EINVAL;
+	struct vpif_display_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct vpif_display_chan_config *chan_cfg;
+	struct v4l2_output output;
+	int ret;
 
 
-	common = &(ch->common[VPIF_VIDEO_INDEX]);
-	if (common->fmt.type != buf->type)
-		return -EINVAL;
+	if (config->chan_config[ch->channel_id].outputs == NULL)
+		return -ENODATA;
 
 
-	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
-		vpif_err("fh->io_allowed\n");
-		return -EACCES;
-	}
+	chan_cfg = &config->chan_config[ch->channel_id];
+	output = chan_cfg->outputs[ch->output_idx].output;
+	if (output.capabilities != V4L2_OUT_CAP_STD)
+		return -ENODATA;
 
 
-	return vb2_qbuf(&common->buffer_queue, buf);
-}
+	if (vb2_is_busy(&common->buffer_queue))
+		return -EBUSY;
 
 
-static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	int ret = 0;
 
 
 	if (!(std_id & VPIF_V4L2_STD))
 	if (!(std_id & VPIF_V4L2_STD))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (common->started) {
-		vpif_err("streaming in progress\n");
-		return -EBUSY;
-	}
-
 	/* Call encoder subdevice function to set the standard */
 	/* Call encoder subdevice function to set the standard */
 	ch->video.stdid = std_id;
 	ch->video.stdid = std_id;
 	memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
 	memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
@@ -1069,16 +709,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 	if (vpif_update_resolution(ch))
 	if (vpif_update_resolution(ch))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if ((ch->vpifparams.std_info.width *
-		ch->vpifparams.std_info.height * 2) >
-		config_params.channel_bufsize[ch->channel_id]) {
-		vpif_err("invalid std for this size\n");
-		return -EINVAL;
-	}
-
 	common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
 	common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
-	/* Configure the default format information */
-	vpif_config_format(ch);
 
 
 	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
 	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
 						s_std_output, std_id);
 						s_std_output, std_id);
@@ -1087,7 +718,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 		return ret;
 		return ret;
 	}
 	}
 
 
-	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
+	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
 							s_std, std_id);
 							s_std, std_id);
 	if (ret < 0)
 	if (ret < 0)
 		vpif_err("Failed to set standard for sub devices\n");
 		vpif_err("Failed to set standard for sub devices\n");
@@ -1096,132 +727,21 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
 
 
 static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
 static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	*std = ch->video.stdid;
-	return 0;
-}
-
-static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
-	return vb2_dqbuf(&common->buffer_queue, p,
-					(file->f_flags & O_NONBLOCK));
-}
-
-static int vpif_streamon(struct file *file, void *priv,
-				enum v4l2_buf_type buftype)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
-	int ret = 0;
-
-	if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		vpif_err("buffer type not supported\n");
-		return -EINVAL;
-	}
-
-	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
-		vpif_err("fh->io_allowed\n");
-		return -EACCES;
-	}
-
-	/* If Streaming is already started, return error */
-	if (common->started) {
-		vpif_err("channel->started\n");
-		return -EBUSY;
-	}
-
-	if ((ch->channel_id == VPIF_CHANNEL2_VIDEO
-		&& oth_ch->common[VPIF_VIDEO_INDEX].started &&
-		ch->vpifparams.std_info.ycmux_mode == 0)
-		|| ((ch->channel_id == VPIF_CHANNEL3_VIDEO)
-		&& (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
-		vpif_err("other channel is using\n");
-		return -EBUSY;
-	}
-
-	ret = vpif_check_format(ch, &common->fmt.fmt.pix);
-	if (ret < 0)
-		return ret;
-
-	/* Call vb2_streamon to start streaming in videobuf2 */
-	ret = vb2_streamon(&common->buffer_queue, buftype);
-	if (ret < 0) {
-		vpif_err("vb2_streamon\n");
-		return ret;
-	}
-
-	return ret;
-}
-
-static int vpif_streamoff(struct file *file, void *priv,
-				enum v4l2_buf_type buftype)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	struct vpif_display_config *vpif_config_data =
-					vpif_dev->platform_data;
-
-	if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		vpif_err("buffer type not supported\n");
-		return -EINVAL;
-	}
-
-	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
-		vpif_err("fh->io_allowed\n");
-		return -EACCES;
-	}
-
-	if (!common->started) {
-		vpif_err("channel->started\n");
-		return -EINVAL;
-	}
-
-	if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		/* disable channel */
-		if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
-			if (vpif_config_data->
-				chan_config[VPIF_CHANNEL2_VIDEO].clip_en)
-				channel2_clipping_enable(0);
-			enable_channel2(0);
-			channel2_intr_enable(0);
-		}
-		if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
-					(2 == common->started)) {
-			if (vpif_config_data->
-				chan_config[VPIF_CHANNEL3_VIDEO].clip_en)
-				channel3_clipping_enable(0);
-			enable_channel3(0);
-			channel3_intr_enable(0);
-		}
-	}
-
-	common->started = 0;
-	return vb2_streamoff(&common->buffer_queue, buftype);
-}
+	struct vpif_display_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
+	struct vpif_display_chan_config *chan_cfg;
+	struct v4l2_output output;
 
 
-static int vpif_cropcap(struct file *file, void *priv,
-			struct v4l2_cropcap *crop)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != crop->type)
-		return -EINVAL;
+	if (config->chan_config[ch->channel_id].outputs == NULL)
+		return -ENODATA;
 
 
-	crop->bounds.left = crop->bounds.top = 0;
-	crop->defrect.left = crop->defrect.top = 0;
-	crop->defrect.height = crop->bounds.height = common->height;
-	crop->defrect.width = crop->bounds.width = common->width;
+	chan_cfg = &config->chan_config[ch->channel_id];
+	output = chan_cfg->outputs[ch->output_idx].output;
+	if (output.capabilities != V4L2_OUT_CAP_STD)
+		return -ENODATA;
 
 
+	*std = ch->video.stdid;
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1230,9 +750,9 @@ static int vpif_enum_output(struct file *file, void *fh,
 {
 {
 
 
 	struct vpif_display_config *config = vpif_dev->platform_data;
 	struct vpif_display_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct vpif_display_chan_config *chan_cfg;
 	struct vpif_display_chan_config *chan_cfg;
-	struct vpif_fh *vpif_handler = fh;
-	struct channel_obj *ch = vpif_handler->channel;
 
 
 	chan_cfg = &config->chan_config[ch->channel_id];
 	chan_cfg = &config->chan_config[ch->channel_id];
 	if (output->index >= chan_cfg->output_count) {
 	if (output->index >= chan_cfg->output_count) {
@@ -1326,52 +846,32 @@ static int vpif_set_output(struct vpif_display_config *vpif_cfg,
 static int vpif_s_output(struct file *file, void *priv, unsigned int i)
 static int vpif_s_output(struct file *file, void *priv, unsigned int i)
 {
 {
 	struct vpif_display_config *config = vpif_dev->platform_data;
 	struct vpif_display_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct vpif_display_chan_config *chan_cfg;
 	struct vpif_display_chan_config *chan_cfg;
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 
 
+	if (vb2_is_busy(&common->buffer_queue))
+		return -EBUSY;
+
 	chan_cfg = &config->chan_config[ch->channel_id];
 	chan_cfg = &config->chan_config[ch->channel_id];
 
 
 	if (i >= chan_cfg->output_count)
 	if (i >= chan_cfg->output_count)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (common->started) {
-		vpif_err("Streaming in progress\n");
-		return -EBUSY;
-	}
-
 	return vpif_set_output(config, ch, i);
 	return vpif_set_output(config, ch, i);
 }
 }
 
 
 static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
 static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 
 
 	*i = ch->output_idx;
 	*i = ch->output_idx;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int vpif_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	*p = v4l2_prio_max(&ch->prio);
-
-	return 0;
-}
-
-static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_prio_change(&ch->prio, &fh->prio, p);
-}
-
 /**
 /**
  * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
  * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler
  * @file: file ptr
  * @file: file ptr
@@ -1382,11 +882,24 @@ static int
 vpif_enum_dv_timings(struct file *file, void *priv,
 vpif_enum_dv_timings(struct file *file, void *priv,
 		     struct v4l2_enum_dv_timings *timings)
 		     struct v4l2_enum_dv_timings *timings)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_display_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
+	struct vpif_display_chan_config *chan_cfg;
+	struct v4l2_output output;
 	int ret;
 	int ret;
 
 
-	ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings);
+	if (config->chan_config[ch->channel_id].outputs == NULL)
+		return -ENODATA;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+	output = chan_cfg->outputs[ch->output_idx].output;
+	if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
+		return -ENODATA;
+
+	timings->pad = 0;
+
+	ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings);
 	if (ret == -ENOIOCTLCMD || ret == -ENODEV)
 	if (ret == -ENOIOCTLCMD || ret == -ENODEV)
 		return -EINVAL;
 		return -EINVAL;
 	return ret;
 	return ret;
@@ -1401,14 +914,29 @@ vpif_enum_dv_timings(struct file *file, void *priv,
 static int vpif_s_dv_timings(struct file *file, void *priv,
 static int vpif_s_dv_timings(struct file *file, void *priv,
 		struct v4l2_dv_timings *timings)
 		struct v4l2_dv_timings *timings)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_display_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
 	struct vpif_params *vpifparams = &ch->vpifparams;
 	struct vpif_params *vpifparams = &ch->vpifparams;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
 	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
 	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
 	struct video_obj *vid_ch = &ch->video;
 	struct video_obj *vid_ch = &ch->video;
 	struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
 	struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt;
+	struct vpif_display_chan_config *chan_cfg;
+	struct v4l2_output output;
 	int ret;
 	int ret;
 
 
+	if (config->chan_config[ch->channel_id].outputs == NULL)
+		return -ENODATA;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+	output = chan_cfg->outputs[ch->output_idx].output;
+	if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
+		return -ENODATA;
+
+	if (vb2_is_busy(&common->buffer_queue))
+		return -EBUSY;
+
 	if (timings->type != V4L2_DV_BT_656_1120) {
 	if (timings->type != V4L2_DV_BT_656_1120) {
 		vpif_dbg(2, debug, "Timing type not defined\n");
 		vpif_dbg(2, debug, "Timing type not defined\n");
 		return -EINVAL;
 		return -EINVAL;
@@ -1490,13 +1018,27 @@ static int vpif_s_dv_timings(struct file *file, void *priv,
 static int vpif_g_dv_timings(struct file *file, void *priv,
 static int vpif_g_dv_timings(struct file *file, void *priv,
 		struct v4l2_dv_timings *timings)
 		struct v4l2_dv_timings *timings)
 {
 {
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
+	struct vpif_display_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(file);
+	struct channel_obj *ch = video_get_drvdata(vdev);
+	struct vpif_display_chan_config *chan_cfg;
 	struct video_obj *vid_ch = &ch->video;
 	struct video_obj *vid_ch = &ch->video;
+	struct v4l2_output output;
+
+	if (config->chan_config[ch->channel_id].outputs == NULL)
+		goto error;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+	output = chan_cfg->outputs[ch->output_idx].output;
+
+	if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS)
+		goto error;
 
 
 	*timings = vid_ch->dv_timings;
 	*timings = vid_ch->dv_timings;
 
 
 	return 0;
 	return 0;
+error:
+	return -ENODATA;
 }
 }
 
 
 /*
 /*
@@ -1516,83 +1058,49 @@ static int vpif_log_status(struct file *filep, void *priv)
 
 
 /* vpif display ioctl operations */
 /* vpif display ioctl operations */
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
 static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
-	.vidioc_querycap        	= vpif_querycap,
-	.vidioc_g_priority		= vpif_g_priority,
-	.vidioc_s_priority		= vpif_s_priority,
+	.vidioc_querycap		= vpif_querycap,
 	.vidioc_enum_fmt_vid_out	= vpif_enum_fmt_vid_out,
 	.vidioc_enum_fmt_vid_out	= vpif_enum_fmt_vid_out,
-	.vidioc_g_fmt_vid_out  		= vpif_g_fmt_vid_out,
-	.vidioc_s_fmt_vid_out   	= vpif_s_fmt_vid_out,
-	.vidioc_try_fmt_vid_out 	= vpif_try_fmt_vid_out,
-	.vidioc_reqbufs         	= vpif_reqbufs,
-	.vidioc_querybuf        	= vpif_querybuf,
-	.vidioc_qbuf            	= vpif_qbuf,
-	.vidioc_dqbuf           	= vpif_dqbuf,
-	.vidioc_streamon        	= vpif_streamon,
-	.vidioc_streamoff       	= vpif_streamoff,
-	.vidioc_s_std           	= vpif_s_std,
+	.vidioc_g_fmt_vid_out		= vpif_g_fmt_vid_out,
+	.vidioc_s_fmt_vid_out		= vpif_s_fmt_vid_out,
+	.vidioc_try_fmt_vid_out		= vpif_try_fmt_vid_out,
+
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
+	.vidioc_expbuf			= vb2_ioctl_expbuf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
+
+	.vidioc_s_std			= vpif_s_std,
 	.vidioc_g_std			= vpif_g_std,
 	.vidioc_g_std			= vpif_g_std,
+
 	.vidioc_enum_output		= vpif_enum_output,
 	.vidioc_enum_output		= vpif_enum_output,
 	.vidioc_s_output		= vpif_s_output,
 	.vidioc_s_output		= vpif_s_output,
 	.vidioc_g_output		= vpif_g_output,
 	.vidioc_g_output		= vpif_g_output,
-	.vidioc_cropcap         	= vpif_cropcap,
-	.vidioc_enum_dv_timings         = vpif_enum_dv_timings,
-	.vidioc_s_dv_timings            = vpif_s_dv_timings,
-	.vidioc_g_dv_timings            = vpif_g_dv_timings,
+
+	.vidioc_enum_dv_timings		= vpif_enum_dv_timings,
+	.vidioc_s_dv_timings		= vpif_s_dv_timings,
+	.vidioc_g_dv_timings		= vpif_g_dv_timings,
+
 	.vidioc_log_status		= vpif_log_status,
 	.vidioc_log_status		= vpif_log_status,
 };
 };
 
 
 static const struct v4l2_file_operations vpif_fops = {
 static const struct v4l2_file_operations vpif_fops = {
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
-	.open		= vpif_open,
-	.release	= vpif_release,
+	.open		= v4l2_fh_open,
+	.release	= vb2_fop_release,
 	.unlocked_ioctl	= video_ioctl2,
 	.unlocked_ioctl	= video_ioctl2,
-	.mmap		= vpif_mmap,
-	.poll		= vpif_poll
-};
-
-static struct video_device vpif_video_template = {
-	.name		= "vpif",
-	.fops		= &vpif_fops,
-	.ioctl_ops	= &vpif_ioctl_ops,
+	.mmap		= vb2_fop_mmap,
+	.poll		= vb2_fop_poll
 };
 };
 
 
 /*Configure the channels, buffer sizei, request irq */
 /*Configure the channels, buffer sizei, request irq */
 static int initialize_vpif(void)
 static int initialize_vpif(void)
 {
 {
 	int free_channel_objects_index;
 	int free_channel_objects_index;
-	int free_buffer_channel_index;
-	int free_buffer_index;
-	int err = 0, i, j;
-
-	/* Default number of buffers should be 3 */
-	if ((ch2_numbuffers > 0) &&
-	    (ch2_numbuffers < config_params.min_numbuffers))
-		ch2_numbuffers = config_params.min_numbuffers;
-	if ((ch3_numbuffers > 0) &&
-	    (ch3_numbuffers < config_params.min_numbuffers))
-		ch3_numbuffers = config_params.min_numbuffers;
-
-	/* Set buffer size to min buffers size if invalid buffer size is
-	 * given */
-	if (ch2_bufsize < config_params.min_bufsize[VPIF_CHANNEL2_VIDEO])
-		ch2_bufsize =
-		    config_params.min_bufsize[VPIF_CHANNEL2_VIDEO];
-	if (ch3_bufsize < config_params.min_bufsize[VPIF_CHANNEL3_VIDEO])
-		ch3_bufsize =
-		    config_params.min_bufsize[VPIF_CHANNEL3_VIDEO];
-
-	config_params.numbuffers[VPIF_CHANNEL2_VIDEO] = ch2_numbuffers;
-
-	if (ch2_numbuffers) {
-		config_params.channel_bufsize[VPIF_CHANNEL2_VIDEO] =
-							ch2_bufsize;
-	}
-	config_params.numbuffers[VPIF_CHANNEL3_VIDEO] = ch3_numbuffers;
-
-	if (ch3_numbuffers) {
-		config_params.channel_bufsize[VPIF_CHANNEL3_VIDEO] =
-							ch3_bufsize;
-	}
+	int err, i, j;
 
 
 	/* Allocate memory for six channel objects */
 	/* Allocate memory for six channel objects */
 	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
 	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
@@ -1606,10 +1114,6 @@ static int initialize_vpif(void)
 		}
 		}
 	}
 	}
 
 
-	free_channel_objects_index = VPIF_DISPLAY_MAX_DEVICES;
-	free_buffer_channel_index = VPIF_DISPLAY_NUM_CHANNELS;
-	free_buffer_index = config_params.numbuffers[i - 1];
-
 	return 0;
 	return 0;
 
 
 vpif_init_free_channel_objects:
 vpif_init_free_channel_objects:
@@ -1638,21 +1142,18 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
 static int vpif_probe_complete(void)
 static int vpif_probe_complete(void)
 {
 {
 	struct common_obj *common;
 	struct common_obj *common;
+	struct video_device *vdev;
 	struct channel_obj *ch;
 	struct channel_obj *ch;
+	struct vb2_queue *q;
 	int j, err, k;
 	int j, err, k;
 
 
 	for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
 	for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
 		ch = vpif_obj.dev[j];
 		ch = vpif_obj.dev[j];
 		/* Initialize field of the channel objects */
 		/* Initialize field of the channel objects */
-		atomic_set(&ch->usrs, 0);
 		for (k = 0; k < VPIF_NUMOBJECTS; k++) {
 		for (k = 0; k < VPIF_NUMOBJECTS; k++) {
-			ch->common[k].numbuffers = 0;
 			common = &ch->common[k];
 			common = &ch->common[k];
-			common->io_usrs = 0;
-			common->started = 0;
 			spin_lock_init(&common->irqlock);
 			spin_lock_init(&common->irqlock);
 			mutex_init(&common->lock);
 			mutex_init(&common->lock);
-			common->numbuffers = 0;
 			common->set_addr = NULL;
 			common->set_addr = NULL;
 			common->ytop_off = 0;
 			common->ytop_off = 0;
 			common->ybtm_off = 0;
 			common->ybtm_off = 0;
@@ -1661,38 +1162,71 @@ static int vpif_probe_complete(void)
 			common->cur_frm = NULL;
 			common->cur_frm = NULL;
 			common->next_frm = NULL;
 			common->next_frm = NULL;
 			memset(&common->fmt, 0, sizeof(common->fmt));
 			memset(&common->fmt, 0, sizeof(common->fmt));
-			common->numbuffers = config_params.numbuffers[k];
 		}
 		}
 		ch->initialized = 0;
 		ch->initialized = 0;
 		if (vpif_obj.config->subdev_count)
 		if (vpif_obj.config->subdev_count)
 			ch->sd = vpif_obj.sd[0];
 			ch->sd = vpif_obj.sd[0];
 		ch->channel_id = j;
 		ch->channel_id = j;
-		if (j < 2)
-			ch->common[VPIF_VIDEO_INDEX].numbuffers =
-			    config_params.numbuffers[ch->channel_id];
-		else
-			ch->common[VPIF_VIDEO_INDEX].numbuffers = 0;
 
 
 		memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
 		memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
 
 
-		/* Initialize prio member of channel object */
-		v4l2_prio_init(&ch->prio);
 		ch->common[VPIF_VIDEO_INDEX].fmt.type =
 		ch->common[VPIF_VIDEO_INDEX].fmt.type =
 						V4L2_BUF_TYPE_VIDEO_OUTPUT;
 						V4L2_BUF_TYPE_VIDEO_OUTPUT;
-		ch->video_dev->lock = &common->lock;
-		video_set_drvdata(ch->video_dev, ch);
 
 
 		/* select output 0 */
 		/* select output 0 */
 		err = vpif_set_output(vpif_obj.config, ch, 0);
 		err = vpif_set_output(vpif_obj.config, ch, 0);
 		if (err)
 		if (err)
 			goto probe_out;
 			goto probe_out;
 
 
+		/* set initial format */
+		ch->video.stdid = V4L2_STD_525_60;
+		memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
+		vpif_update_resolution(ch);
+
+		/* Initialize vb2 queue */
+		q = &common->buffer_queue;
+		q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+		q->drv_priv = ch;
+		q->ops = &video_qops;
+		q->mem_ops = &vb2_dma_contig_memops;
+		q->buf_struct_size = sizeof(struct vpif_disp_buffer);
+		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+		q->min_buffers_needed = 1;
+		q->lock = &common->lock;
+		err = vb2_queue_init(q);
+		if (err) {
+			vpif_err("vpif_display: vb2_queue_init() failed\n");
+			goto probe_out;
+		}
+
+		common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
+		if (IS_ERR(common->alloc_ctx)) {
+			vpif_err("Failed to get the context\n");
+			err = PTR_ERR(common->alloc_ctx);
+			goto probe_out;
+		}
+
+		INIT_LIST_HEAD(&common->dma_queue);
+
 		/* register video device */
 		/* register video device */
 		vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
 		vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
 			 (int)ch, (int)&ch->video_dev);
 			 (int)ch, (int)&ch->video_dev);
 
 
-		err = video_register_device(ch->video_dev,
-					  VFL_TYPE_GRABBER, (j ? 3 : 2));
+		/* Initialize the video_device structure */
+		vdev = ch->video_dev;
+		strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
+		vdev->release = video_device_release;
+		vdev->fops = &vpif_fops;
+		vdev->ioctl_ops = &vpif_ioctl_ops;
+		vdev->v4l2_dev = &vpif_obj.v4l2_dev;
+		vdev->vfl_dir = VFL_DIR_TX;
+		vdev->queue = q;
+		vdev->lock = &common->lock;
+		set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
+		video_set_drvdata(ch->video_dev, ch);
+		err = video_register_device(vdev, VFL_TYPE_GRABBER,
+					    (j ? 3 : 2));
 		if (err < 0)
 		if (err < 0)
 			goto probe_out;
 			goto probe_out;
 	}
 	}
@@ -1702,6 +1236,8 @@ static int vpif_probe_complete(void)
 probe_out:
 probe_out:
 	for (k = 0; k < j; k++) {
 	for (k = 0; k < j; k++) {
 		ch = vpif_obj.dev[k];
 		ch = vpif_obj.dev[k];
+		common = &ch->common[k];
+		vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
 		video_unregister_device(ch->video_dev);
 		video_unregister_device(ch->video_dev);
 		video_device_release(ch->video_dev);
 		video_device_release(ch->video_dev);
 		ch->video_dev = NULL;
 		ch->video_dev = NULL;
@@ -1728,7 +1264,6 @@ static __init int vpif_probe(struct platform_device *pdev)
 	struct video_device *vfd;
 	struct video_device *vfd;
 	struct resource *res;
 	struct resource *res;
 	int subdev_count;
 	int subdev_count;
-	size_t size;
 
 
 	vpif_dev = &pdev->dev;
 	vpif_dev = &pdev->dev;
 	err = initialize_vpif();
 	err = initialize_vpif();
@@ -1746,7 +1281,7 @@ static __init int vpif_probe(struct platform_device *pdev)
 
 
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
 		err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
 		err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
-					IRQF_SHARED, "VPIF_Display",
+					IRQF_SHARED, VPIF_DRIVER_NAME,
 					(void *)(&vpif_obj.dev[res_idx]->
 					(void *)(&vpif_obj.dev[res_idx]->
 					channel_id));
 					channel_id));
 		if (err) {
 		if (err) {
@@ -1772,36 +1307,10 @@ static __init int vpif_probe(struct platform_device *pdev)
 			goto vpif_unregister;
 			goto vpif_unregister;
 		}
 		}
 
 
-		/* Initialize field of video device */
-		*vfd = vpif_video_template;
-		vfd->v4l2_dev = &vpif_obj.v4l2_dev;
-		vfd->release = video_device_release;
-		vfd->vfl_dir = VFL_DIR_TX;
-		snprintf(vfd->name, sizeof(vfd->name),
-			 "VPIF_Display_DRIVER_V%s",
-			 VPIF_DISPLAY_VERSION);
-
 		/* Set video_dev to the video device */
 		/* Set video_dev to the video device */
 		ch->video_dev = vfd;
 		ch->video_dev = vfd;
 	}
 	}
 
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res) {
-		size = resource_size(res);
-		/* The resources are divided into two equal memory and when
-		 * we have HD output we can add them together
-		 */
-		for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
-			ch = vpif_obj.dev[j];
-			ch->channel_id = j;
-
-			/* only enabled if second resource exists */
-			config_params.video_limit[ch->channel_id] = 0;
-			if (size)
-				config_params.video_limit[ch->channel_id] =
-									size/2;
-		}
-	}
 	vpif_obj.config = pdev->dev.platform_data;
 	vpif_obj.config = pdev->dev.platform_data;
 	subdev_count = vpif_obj.config->subdev_count;
 	subdev_count = vpif_obj.config->subdev_count;
 	subdevdata = vpif_obj.config->subdevinfo;
 	subdevdata = vpif_obj.config->subdevinfo;
@@ -1867,6 +1376,7 @@ vpif_unregister:
  */
  */
 static int vpif_remove(struct platform_device *device)
 static int vpif_remove(struct platform_device *device)
 {
 {
+	struct common_obj *common;
 	struct channel_obj *ch;
 	struct channel_obj *ch;
 	int i;
 	int i;
 
 
@@ -1877,6 +1387,8 @@ static int vpif_remove(struct platform_device *device)
 	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
 	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
 		/* Get the pointer to the channel object */
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[i];
 		ch = vpif_obj.dev[i];
+		common = &ch->common[i];
+		vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
 		/* Unregister video device */
 		/* Unregister video device */
 		video_unregister_device(ch->video_dev);
 		video_unregister_device(ch->video_dev);
 
 
@@ -1887,7 +1399,7 @@ static int vpif_remove(struct platform_device *device)
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int vpif_suspend(struct device *dev)
 static int vpif_suspend(struct device *dev)
 {
 {
 	struct common_obj *common;
 	struct common_obj *common;
@@ -1898,18 +1410,20 @@ static int vpif_suspend(struct device *dev)
 		/* Get the pointer to the channel object */
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[i];
 		ch = vpif_obj.dev[i];
 		common = &ch->common[VPIF_VIDEO_INDEX];
 		common = &ch->common[VPIF_VIDEO_INDEX];
+
+		if (!vb2_is_streaming(&common->buffer_queue))
+			continue;
+
 		mutex_lock(&common->lock);
 		mutex_lock(&common->lock);
-		if (atomic_read(&ch->usrs) && common->io_usrs) {
-			/* Disable channel */
-			if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
-				enable_channel2(0);
-				channel2_intr_enable(0);
-			}
-			if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
-					common->started == 2) {
-				enable_channel3(0);
-				channel3_intr_enable(0);
-			}
+		/* Disable channel */
+		if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
+			enable_channel2(0);
+			channel2_intr_enable(0);
+		}
+		if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
+			ycmux_mode == 2) {
+			enable_channel3(0);
+			channel3_intr_enable(0);
 		}
 		}
 		mutex_unlock(&common->lock);
 		mutex_unlock(&common->lock);
 	}
 	}
@@ -1928,18 +1442,20 @@ static int vpif_resume(struct device *dev)
 		/* Get the pointer to the channel object */
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[i];
 		ch = vpif_obj.dev[i];
 		common = &ch->common[VPIF_VIDEO_INDEX];
 		common = &ch->common[VPIF_VIDEO_INDEX];
+
+		if (!vb2_is_streaming(&common->buffer_queue))
+			continue;
+
 		mutex_lock(&common->lock);
 		mutex_lock(&common->lock);
-		if (atomic_read(&ch->usrs) && common->io_usrs) {
-			/* Enable channel */
-			if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
-				enable_channel2(1);
-				channel2_intr_enable(1);
-			}
-			if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
-					common->started == 2) {
-				enable_channel3(1);
-				channel3_intr_enable(1);
-			}
+		/* Enable channel */
+		if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
+			enable_channel2(1);
+			channel2_intr_enable(1);
+		}
+		if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
+				ycmux_mode == 2) {
+			enable_channel3(1);
+			channel3_intr_enable(1);
 		}
 		}
 		mutex_unlock(&common->lock);
 		mutex_unlock(&common->lock);
 	}
 	}
@@ -1947,21 +1463,15 @@ static int vpif_resume(struct device *dev)
 	return 0;
 	return 0;
 }
 }
 
 
-static const struct dev_pm_ops vpif_pm = {
-	.suspend        = vpif_suspend,
-	.resume         = vpif_resume,
-};
-
-#define vpif_pm_ops (&vpif_pm)
-#else
-#define vpif_pm_ops NULL
 #endif
 #endif
 
 
+static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume);
+
 static __refdata struct platform_driver vpif_driver = {
 static __refdata struct platform_driver vpif_driver = {
 	.driver	= {
 	.driver	= {
-			.name	= "vpif_display",
+			.name	= VPIF_DRIVER_NAME,
 			.owner	= THIS_MODULE,
 			.owner	= THIS_MODULE,
-			.pm	= vpif_pm_ops,
+			.pm	= &vpif_pm_ops,
 	},
 	},
 	.probe	= vpif_probe,
 	.probe	= vpif_probe,
 	.remove	= vpif_remove,
 	.remove	= vpif_remove,

+ 4 - 40
drivers/media/platform/davinci/vpif_display.h

@@ -13,8 +13,8 @@
  * GNU General Public License for more details.
  * GNU General Public License for more details.
  */
  */
 
 
-#ifndef DAVINCIHD_DISPLAY_H
-#define DAVINCIHD_DISPLAY_H
+#ifndef VPIF_DISPLAY_H
+#define VPIF_DISPLAY_H
 
 
 /* Header files */
 /* Header files */
 #include <media/videobuf2-dma-contig.h>
 #include <media/videobuf2-dma-contig.h>
@@ -67,17 +67,10 @@ struct vpif_disp_buffer {
 };
 };
 
 
 struct common_obj {
 struct common_obj {
-	/* Buffer specific parameters */
-	u8 *fbuffers[VIDEO_MAX_FRAME];		/* List of buffer pointers for
-						 * storing frames */
-	u32 numbuffers;				/* number of buffers */
 	struct vpif_disp_buffer *cur_frm;	/* Pointer pointing to current
 	struct vpif_disp_buffer *cur_frm;	/* Pointer pointing to current
 						 * vb2_buffer */
 						 * vb2_buffer */
 	struct vpif_disp_buffer *next_frm;	/* Pointer pointing to next
 	struct vpif_disp_buffer *next_frm;	/* Pointer pointing to next
 						 * vb2_buffer */
 						 * vb2_buffer */
-	enum v4l2_memory memory;		/* This field keeps track of
-						 * type of buffer exchange
-						 * method user has selected */
 	struct v4l2_format fmt;			/* Used to store the format */
 	struct v4l2_format fmt;			/* Used to store the format */
 	struct vb2_queue buffer_queue;		/* Buffer queue used in
 	struct vb2_queue buffer_queue;		/* Buffer queue used in
 						 * video-buf */
 						 * video-buf */
@@ -90,10 +83,6 @@ struct common_obj {
 	/* channel specific parameters */
 	/* channel specific parameters */
 	struct mutex lock;			/* lock used to access this
 	struct mutex lock;			/* lock used to access this
 						 * structure */
 						 * structure */
-	u32 io_usrs;				/* number of users performing
-						 * IO */
-	u8 started;				/* Indicates whether streaming
-						 * started */
 	u32 ytop_off;				/* offset of Y top from the
 	u32 ytop_off;				/* offset of Y top from the
 						 * starting of the buffer */
 						 * starting of the buffer */
 	u32 ybtm_off;				/* offset of Y bottom from the
 	u32 ybtm_off;				/* offset of Y bottom from the
@@ -103,7 +92,7 @@ struct common_obj {
 	u32 cbtm_off;				/* offset of C bottom from the
 	u32 cbtm_off;				/* offset of C bottom from the
 						 * starting of the buffer */
 						 * starting of the buffer */
 	/* Function pointer to set the addresses */
 	/* Function pointer to set the addresses */
-	void (*set_addr) (unsigned long, unsigned long,
+	void (*set_addr)(unsigned long, unsigned long,
 				unsigned long, unsigned long);
 				unsigned long, unsigned long);
 	u32 height;
 	u32 height;
 	u32 width;
 	u32 width;
@@ -113,10 +102,6 @@ struct channel_obj {
 	/* V4l2 specific parameters */
 	/* V4l2 specific parameters */
 	struct video_device *video_dev;	/* Identifies video device for
 	struct video_device *video_dev;	/* Identifies video device for
 					 * this channel */
 					 * this channel */
-	struct v4l2_prio_state prio;	/* Used to keep track of state of
-					 * the priority */
-	atomic_t usrs;			/* number of open instances of
-					 * the channel */
 	u32 field_id;			/* Indicates id of the field
 	u32 field_id;			/* Indicates id of the field
 					 * which is being displayed */
 					 * which is being displayed */
 	u8 initialized;			/* flag to indicate whether
 	u8 initialized;			/* flag to indicate whether
@@ -130,19 +115,6 @@ struct channel_obj {
 	struct video_obj video;
 	struct video_obj video;
 };
 };
 
 
-/* File handle structure */
-struct vpif_fh {
-	struct channel_obj *channel;	/* pointer to channel object for
-					 * opened device */
-	u8 io_allowed[VPIF_NUMOBJECTS];	/* Indicates whether this file handle
-					 * is doing IO */
-	enum v4l2_priority prio;	/* Used to keep track priority of
-					 * this instance */
-	u8 initialized;			/* Used to keep track of whether this
-					 * file handle has initialized
-					 * channel or not */
-};
-
 /* vpif device structure */
 /* vpif device structure */
 struct vpif_device {
 struct vpif_device {
 	struct v4l2_device v4l2_dev;
 	struct v4l2_device v4l2_dev;
@@ -152,12 +124,4 @@ struct vpif_device {
 	struct vpif_display_config *config;
 	struct vpif_display_config *config;
 };
 };
 
 
-struct vpif_config_params {
-	u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
-	u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
-	u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS];
-	u32 video_limit[VPIF_DISPLAY_NUM_CHANNELS];
-	u8 min_numbuffers;
-};
-
-#endif				/* DAVINCIHD_DISPLAY_H */
+#endif				/* VPIF_DISPLAY_H */

+ 1 - 3
drivers/media/platform/exynos-gsc/gsc-m2m.c

@@ -66,15 +66,13 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
 	return ret > 0 ? 0 : ret;
 	return ret > 0 ? 0 : ret;
 }
 }
 
 
-static int gsc_m2m_stop_streaming(struct vb2_queue *q)
+static void gsc_m2m_stop_streaming(struct vb2_queue *q)
 {
 {
 	struct gsc_ctx *ctx = q->drv_priv;
 	struct gsc_ctx *ctx = q->drv_priv;
 
 
 	__gsc_m2m_job_abort(ctx);
 	__gsc_m2m_job_abort(ctx);
 
 
 	pm_runtime_put(&ctx->gsc_dev->pdev->dev);
 	pm_runtime_put(&ctx->gsc_dev->pdev->dev);
-
-	return 0;
 }
 }
 
 
 void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)
 void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state)

Vissa filer visades inte eftersom för många filer har ändrats