Bladeren bron

Merge tag 'media/v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:

 - a new frontend driver for new ATSC devices: lgdt3306a

 - a new sensor driver: ov2659

 - a new platform driver: xilinx

 - the m88ts2022 tuner driver was merged at ts2020 driver

 - the media controller gained experimental support for DVB and hybrid
   devices

 - lots of random cleanups, fixes and improvements on media drivers

* tag 'media/v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (404 commits)
  [media] uvcvideo: add support for VIDIOC_QUERY_EXT_CTRL
  [media] uvcvideo: fix cropcap v4l2-compliance failure
  [media] media: omap3isp: remove unused clkdev
  [media] coda: Add tracing support
  [media] coda: drop dma_sync_single_for_device in coda_bitstream_queue
  [media] coda: fix fill bitstream errors in nonstreaming case
  [media] coda: call SEQ_END when the first queue is stopped
  [media] coda: fail to start streaming if userspace set invalid formats
  [media] coda: remove duplicate error messages for buffer allocations
  [media] coda: move parameter buffer in together with context buffer allocation
  [media] coda: allocate bitstream buffer from REQBUFS, size depends on the format
  [media] coda: allocate per-context buffers from REQBUFS
  [media] coda: use strlcpy instead of snprintf
  [media] coda: bitstream payload is unsigned
  [media] coda: fix double call to debugfs_remove
  [media] coda: check kasprintf return value in coda_open
  [media] coda: bitrate can only be set in kbps steps
  [media] v4l2-mem2mem: no need to initialize b in v4l2_m2m_next_buf and v4l2_m2m_buf_remove
  [media] s5p-mfc: set allow_zero_bytesused flag for vb2_queue_init
  [media] coda: set allow_zero_bytesused flag for vb2_queue_init
  ...
Linus Torvalds 10 jaren geleden
bovenliggende
commit
0c8027d50c
100 gewijzigde bestanden met toevoegingen van 4338 en 1059 verwijderingen
  1. 1 1
      Documentation/DocBook/media/v4l/compat.xml
  2. 27 65
      Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
  3. 40 39
      Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
  4. 8 8
      Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml
  5. 1 1
      Documentation/DocBook/media/v4l/pixfmt-srggb10p.xml
  6. 2 2
      Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
  7. 52 58
      Documentation/DocBook/media/v4l/pixfmt.xml
  8. 434 337
      Documentation/DocBook/media/v4l/subdev-formats.xml
  9. 9 0
      Documentation/DocBook/media/v4l/v4l2.xml
  10. 6 3
      Documentation/DocBook/media/v4l/vidioc-cropcap.xml
  11. 114 7
      Documentation/DocBook/media/v4l/vidioc-dqevent.xml
  12. 5 0
      Documentation/DocBook/media/v4l/vidioc-g-crop.xml
  13. 14 4
      Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml
  14. 2 2
      Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml
  15. 2 2
      Documentation/DocBook/media/v4l/vidioc-g-selection.xml
  16. 4 4
      Documentation/DocBook/media/v4l/vidioc-querycap.xml
  17. 11 1
      Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
  18. 9 4
      Documentation/DocBook/media/v4l/vidioc-subdev-enum-frame-interval.xml
  19. 9 4
      Documentation/DocBook/media/v4l/vidioc-subdev-enum-frame-size.xml
  20. 8 3
      Documentation/DocBook/media/v4l/vidioc-subdev-enum-mbus-code.xml
  21. 3 108
      Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
  22. 1 1
      Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt
  23. 39 0
      Documentation/devicetree/bindings/media/i2c/mt9v032.txt
  24. 46 0
      Documentation/devicetree/bindings/media/i2c/ov2640.txt
  25. 38 0
      Documentation/devicetree/bindings/media/i2c/ov2659.txt
  26. 6 0
      Documentation/devicetree/bindings/media/video-interfaces.txt
  27. 35 0
      Documentation/devicetree/bindings/media/xilinx/video.txt
  28. 33 0
      Documentation/devicetree/bindings/media/xilinx/xlnx,v-tc.txt
  29. 71 0
      Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
  30. 55 0
      Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt
  31. 1 0
      Documentation/devicetree/bindings/vendor-prefixes.txt
  32. 3 1
      Documentation/video4linux/v4l2-controls.txt
  33. 3 3
      Documentation/video4linux/v4l2-framework.txt
  34. 5 0
      Documentation/video4linux/vivid.txt
  35. 22 11
      MAINTAINERS
  36. 21 36
      arch/arm/mach-omap2/board-cm-t35.c
  37. 3 73
      arch/arm/mach-omap2/devices.c
  38. 3 33
      arch/arm/mach-omap2/omap34xx.h
  39. 15 3
      drivers/input/ff-memless.c
  40. 2 0
      drivers/input/touchscreen/Kconfig
  41. 422 12
      drivers/input/touchscreen/sur40.c
  42. 9 1
      drivers/media/Kconfig
  43. 4 15
      drivers/media/common/saa7146/saa7146_fops.c
  44. 2 2
      drivers/media/common/saa7146/saa7146_vbi.c
  45. 2 6
      drivers/media/common/siano/sms-cards.c
  46. 2 1
      drivers/media/common/siano/sms-cards.h
  47. 81 83
      drivers/media/common/siano/smscoreapi.c
  48. 10 22
      drivers/media/common/siano/smscoreapi.h
  49. 2 4
      drivers/media/common/siano/smsdvb-debugfs.c
  50. 43 31
      drivers/media/common/siano/smsdvb-main.c
  51. 9 9
      drivers/media/common/siano/smsir.c
  52. 8 3
      drivers/media/dvb-core/dmxdev.c
  53. 3 0
      drivers/media/dvb-core/dvb-usb-ids.h
  54. 16 14
      drivers/media/dvb-core/dvb_ca_en50221.c
  55. 123 1
      drivers/media/dvb-core/dvb_frontend.c
  56. 4 2
      drivers/media/dvb-core/dvb_net.c
  57. 143 1
      drivers/media/dvb-core/dvbdev.c
  58. 27 0
      drivers/media/dvb-core/dvbdev.h
  59. 8 0
      drivers/media/dvb-frontends/Kconfig
  60. 1 0
      drivers/media/dvb-frontends/Makefile
  61. 1 1
      drivers/media/dvb-frontends/a8293.h
  62. 1 1
      drivers/media/dvb-frontends/af9013.h
  63. 1 1
      drivers/media/dvb-frontends/atbm8830.h
  64. 1 1
      drivers/media/dvb-frontends/au8522.h
  65. 1 1
      drivers/media/dvb-frontends/bcm3510.h
  66. 1 1
      drivers/media/dvb-frontends/cx22700.h
  67. 1 1
      drivers/media/dvb-frontends/cx22702.h
  68. 1 1
      drivers/media/dvb-frontends/cx24110.h
  69. 1 1
      drivers/media/dvb-frontends/cx24113.h
  70. 1 1
      drivers/media/dvb-frontends/cx24116.h
  71. 1 1
      drivers/media/dvb-frontends/cx24117.h
  72. 1 1
      drivers/media/dvb-frontends/cx24123.h
  73. 1 1
      drivers/media/dvb-frontends/cxd2820r.h
  74. 1 1
      drivers/media/dvb-frontends/dib0070.h
  75. 1 1
      drivers/media/dvb-frontends/dib0090.h
  76. 1 1
      drivers/media/dvb-frontends/dib3000.h
  77. 1 1
      drivers/media/dvb-frontends/dib3000mc.h
  78. 1 1
      drivers/media/dvb-frontends/dib7000m.h
  79. 1 1
      drivers/media/dvb-frontends/dib7000p.h
  80. 1 1
      drivers/media/dvb-frontends/dib8000.h
  81. 1 1
      drivers/media/dvb-frontends/dib9000.h
  82. 1 1
      drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
  83. 1 1
      drivers/media/dvb-frontends/drxd.h
  84. 1 1
      drivers/media/dvb-frontends/drxk.h
  85. 1 1
      drivers/media/dvb-frontends/ds3000.h
  86. 1 1
      drivers/media/dvb-frontends/dvb-pll.h
  87. 1 1
      drivers/media/dvb-frontends/dvb_dummy_fe.h
  88. 1 1
      drivers/media/dvb-frontends/ec100.h
  89. 1 1
      drivers/media/dvb-frontends/hd29l2.h
  90. 1 1
      drivers/media/dvb-frontends/isl6405.h
  91. 1 1
      drivers/media/dvb-frontends/isl6421.h
  92. 1 1
      drivers/media/dvb-frontends/isl6423.h
  93. 1 1
      drivers/media/dvb-frontends/itd1000.h
  94. 1 1
      drivers/media/dvb-frontends/ix2505v.h
  95. 1 1
      drivers/media/dvb-frontends/l64781.h
  96. 1 1
      drivers/media/dvb-frontends/lg2160.h
  97. 1 1
      drivers/media/dvb-frontends/lgdt3305.h
  98. 2144 0
      drivers/media/dvb-frontends/lgdt3306a.c
  99. 74 0
      drivers/media/dvb-frontends/lgdt3306a.h
  100. 1 1
      drivers/media/dvb-frontends/lgdt330x.h

+ 1 - 1
Documentation/DocBook/media/v4l/compat.xml

@@ -2491,7 +2491,7 @@ that used it. It was originally scheduled for removal in 2.6.35.
         </listitem>
         </listitem>
         <listitem>
         <listitem>
 	  <para>Added <constant>V4L2_EVENT_CTRL_CH_RANGE</constant> control event
 	  <para>Added <constant>V4L2_EVENT_CTRL_CH_RANGE</constant> control event
-	  changes flag. See <xref linkend="changes-flags"/>.</para>
+	  changes flag. See <xref linkend="ctrl-changes-flags"/>.</para>
         </listitem>
         </listitem>
       </orderedlist>
       </orderedlist>
     </section>
     </section>

+ 27 - 65
Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml

@@ -143,86 +143,28 @@
 	  <row>
 	  <row>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry>struct</entry>
 	    <entry>struct</entry>
-	    <entry><structfield>v4l</structfield></entry>
+	    <entry><structfield>dev</structfield></entry>
 	    <entry></entry>
 	    <entry></entry>
-	    <entry>Valid for V4L sub-devices and nodes only.</entry>
+	    <entry>Valid for (sub-)devices that create a single device node.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
 	    <entry><structfield>major</structfield></entry>
 	    <entry><structfield>major</structfield></entry>
-	    <entry>V4L device node major number. For V4L sub-devices with no
-	    device node, set by the driver to 0.</entry>
+	    <entry>Device node major number.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
 	    <entry><structfield>minor</structfield></entry>
 	    <entry><structfield>minor</structfield></entry>
-	    <entry>V4L device node minor number. For V4L sub-devices with no
-	    device node, set by the driver to 0.</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry>struct</entry>
-	    <entry><structfield>fb</structfield></entry>
-	    <entry></entry>
-	    <entry>Valid for frame buffer nodes only.</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry>__u32</entry>
-	    <entry><structfield>major</structfield></entry>
-	    <entry>Frame buffer device node major number.</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry>__u32</entry>
-	    <entry><structfield>minor</structfield></entry>
-	    <entry>Frame buffer device node minor number.</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry>struct</entry>
-	    <entry><structfield>alsa</structfield></entry>
-	    <entry></entry>
-	    <entry>Valid for ALSA devices only.</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry>__u32</entry>
-	    <entry><structfield>card</structfield></entry>
-	    <entry>ALSA card number</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry>__u32</entry>
-	    <entry><structfield>device</structfield></entry>
-	    <entry>ALSA device number</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry>__u32</entry>
-	    <entry><structfield>subdevice</structfield></entry>
-	    <entry>ALSA sub-device number</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry>int</entry>
-	    <entry><structfield>dvb</structfield></entry>
-	    <entry></entry>
-	    <entry>DVB card number</entry>
+	    <entry>Device node minor number.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry>__u8</entry>
 	    <entry>__u8</entry>
-	    <entry><structfield>raw</structfield>[180]</entry>
+	    <entry><structfield>raw</structfield>[184]</entry>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry></entry>
 	    <entry></entry>
 	  </row>
 	  </row>
@@ -253,8 +195,24 @@
 	    <entry>ALSA card</entry>
 	    <entry>ALSA card</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE_DVB</constant></entry>
-	    <entry>DVB card</entry>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_FE</constant></entry>
+	    <entry>DVB frontend devnode</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_DEMUX</constant></entry>
+	    <entry>DVB demux devnode</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_DVR</constant></entry>
+	    <entry>DVB DVR devnode</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_CA</constant></entry>
+	    <entry>DVB CAM devnode</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_NET</constant></entry>
+	    <entry>DVB network devnode</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
@@ -282,6 +240,10 @@
 	    it in some digital video standard, with appropriate embedded timing
 	    it in some digital video standard, with appropriate embedded timing
 	    signals.</entry>
 	    signals.</entry>
 	  </row>
 	  </row>
+	  <row>
+	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_TUNER</constant></entry>
+	    <entry>TV and/or radio tuner</entry>
+	  </row>
 	</tbody>
 	</tbody>
       </tgroup>
       </tgroup>
     </table>
     </table>

+ 40 - 39
Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml

@@ -303,45 +303,6 @@ for a pixel lie next to each other in memory.</para>
 	    <entry>b<subscript>1</subscript></entry>
 	    <entry>b<subscript>1</subscript></entry>
 	    <entry>b<subscript>0</subscript></entry>
 	    <entry>b<subscript>0</subscript></entry>
 	  </row>
 	  </row>
-	  <row id="V4L2-PIX-FMT-BGR666">
-	    <entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
-	    <entry>'BGRH'</entry>
-	    <entry></entry>
-	    <entry>b<subscript>5</subscript></entry>
-	    <entry>b<subscript>4</subscript></entry>
-	    <entry>b<subscript>3</subscript></entry>
-	    <entry>b<subscript>2</subscript></entry>
-	    <entry>b<subscript>1</subscript></entry>
-	    <entry>b<subscript>0</subscript></entry>
-	    <entry>g<subscript>5</subscript></entry>
-	    <entry>g<subscript>4</subscript></entry>
-	    <entry></entry>
-	    <entry>g<subscript>3</subscript></entry>
-	    <entry>g<subscript>2</subscript></entry>
-	    <entry>g<subscript>1</subscript></entry>
-	    <entry>g<subscript>0</subscript></entry>
-	    <entry>r<subscript>5</subscript></entry>
-	    <entry>r<subscript>4</subscript></entry>
-	    <entry>r<subscript>3</subscript></entry>
-	    <entry>r<subscript>2</subscript></entry>
-	    <entry></entry>
-	    <entry>r<subscript>1</subscript></entry>
-	    <entry>r<subscript>0</subscript></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	    <entry></entry>
-	  </row>
 	  <row id="V4L2-PIX-FMT-BGR24">
 	  <row id="V4L2-PIX-FMT-BGR24">
 	    <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
 	    <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
 	    <entry>'BGR3'</entry>
 	    <entry>'BGR3'</entry>
@@ -404,6 +365,46 @@ for a pixel lie next to each other in memory.</para>
 	    <entry>b<subscript>1</subscript></entry>
 	    <entry>b<subscript>1</subscript></entry>
 	    <entry>b<subscript>0</subscript></entry>
 	    <entry>b<subscript>0</subscript></entry>
 	  </row>
 	  </row>
+	  <row id="V4L2-PIX-FMT-BGR666">
+	    <entry><constant>V4L2_PIX_FMT_BGR666</constant></entry>
+	    <entry>'BGRH'</entry>
+	    <entry></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry></entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	    <entry>-</entry>
+	  </row>
 	  <row id="V4L2-PIX-FMT-ABGR32">
 	  <row id="V4L2-PIX-FMT-ABGR32">
 	    <entry><constant>V4L2_PIX_FMT_ABGR32</constant></entry>
 	    <entry><constant>V4L2_PIX_FMT_ABGR32</constant></entry>
 	    <entry>'AR24'</entry>
 	    <entry>'AR24'</entry>

+ 8 - 8
Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml

@@ -38,10 +38,10 @@ columns and rows.</para>
 		    </row>
 		    </row>
 		    <row>
 		    <row>
 		      <entry>start&nbsp;+&nbsp;4:</entry>
 		      <entry>start&nbsp;+&nbsp;4:</entry>
-		      <entry>R<subscript>10</subscript></entry>
-		      <entry>B<subscript>11</subscript></entry>
-		      <entry>R<subscript>12</subscript></entry>
-		      <entry>B<subscript>13</subscript></entry>
+		      <entry>B<subscript>10</subscript></entry>
+		      <entry>G<subscript>11</subscript></entry>
+		      <entry>B<subscript>12</subscript></entry>
+		      <entry>G<subscript>13</subscript></entry>
 		    </row>
 		    </row>
 		    <row>
 		    <row>
 		      <entry>start&nbsp;+&nbsp;8:</entry>
 		      <entry>start&nbsp;+&nbsp;8:</entry>
@@ -52,10 +52,10 @@ columns and rows.</para>
 		    </row>
 		    </row>
 		    <row>
 		    <row>
 		      <entry>start&nbsp;+&nbsp;12:</entry>
 		      <entry>start&nbsp;+&nbsp;12:</entry>
-		      <entry>R<subscript>30</subscript></entry>
-		      <entry>B<subscript>31</subscript></entry>
-		      <entry>R<subscript>32</subscript></entry>
-		      <entry>B<subscript>33</subscript></entry>
+		      <entry>B<subscript>30</subscript></entry>
+		      <entry>G<subscript>31</subscript></entry>
+		      <entry>B<subscript>32</subscript></entry>
+		      <entry>G<subscript>33</subscript></entry>
 		    </row>
 		    </row>
 		  </tbody>
 		  </tbody>
 		</tgroup>
 		</tgroup>

+ 1 - 1
Documentation/DocBook/media/v4l/pixfmt-srggb10p.xml

@@ -38,7 +38,7 @@
 	<title>Byte Order.</title>
 	<title>Byte Order.</title>
 	<para>Each cell is one byte.
 	<para>Each cell is one byte.
 	  <informaltable frame="topbot" colsep="1" rowsep="1">
 	  <informaltable frame="topbot" colsep="1" rowsep="1">
-	    <tgroup cols="5" align="center" border="1">
+	    <tgroup cols="5" align="center">
 	      <colspec align="left" colwidth="2*" />
 	      <colspec align="left" colwidth="2*" />
 	      <tbody valign="top">
 	      <tbody valign="top">
 		<row>
 		<row>

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

@@ -29,12 +29,12 @@ and Cr planes have half as many pad bytes after their rows. In other
 words, two Cx rows (including padding) is exactly as long as one Y row
 words, two Cx rows (including padding) is exactly as long as one Y row
 (including padding).</para>
 (including padding).</para>
 
 
-	<para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be
+	<para><constant>V4L2_PIX_FMT_YUV420M</constant> is intended to be
 used only in drivers and applications that support the multi-planar API,
 used only in drivers and applications that support the multi-planar API,
 described in <xref linkend="planar-apis"/>. </para>
 described in <xref linkend="planar-apis"/>. </para>
 
 
 	<example>
 	<example>
-	  <title><constant>V4L2_PIX_FMT_YVU420M</constant> 4 &times; 4
+	  <title><constant>V4L2_PIX_FMT_YUV420M</constant> 4 &times; 4
 pixel image</title>
 pixel image</title>
 
 
 	  <formalpara>
 	  <formalpara>

+ 52 - 58
Documentation/DocBook/media/v4l/pixfmt.xml

@@ -80,9 +80,9 @@ padding bytes after the last line of an image cross a system page
 boundary. Input devices may write padding bytes, the value is
 boundary. Input devices may write padding bytes, the value is
 undefined. Output devices ignore the contents of padding
 undefined. Output devices ignore the contents of padding
 bytes.</para><para>When the image format is planar the
 bytes.</para><para>When the image format is planar the
-<structfield>bytesperline</structfield> value applies to the largest
+<structfield>bytesperline</structfield> value applies to the first
 plane and is divided by the same factor as the
 plane and is divided by the same factor as the
-<structfield>width</structfield> field for any smaller planes. For
+<structfield>width</structfield> field for the other planes. For
 example the Cb and Cr planes of a YUV 4:2:0 image have half as many
 example the Cb and Cr planes of a YUV 4:2:0 image have half as many
 padding bytes following each line as the Y plane. To avoid ambiguities
 padding bytes following each line as the Y plane. To avoid ambiguities
 drivers must return a <structfield>bytesperline</structfield> value
 drivers must return a <structfield>bytesperline</structfield> value
@@ -182,14 +182,14 @@ see <xref linkend="colorspaces" />.</entry>
           </entry>
           </entry>
         </row>
         </row>
         <row>
         <row>
-          <entry>__u16</entry>
+          <entry>__u32</entry>
           <entry><structfield>bytesperline</structfield></entry>
           <entry><structfield>bytesperline</structfield></entry>
           <entry>Distance in bytes between the leftmost pixels in two adjacent
           <entry>Distance in bytes between the leftmost pixels in two adjacent
             lines. See &v4l2-pix-format;.</entry>
             lines. See &v4l2-pix-format;.</entry>
         </row>
         </row>
         <row>
         <row>
           <entry>__u16</entry>
           <entry>__u16</entry>
-          <entry><structfield>reserved[7]</structfield></entry>
+          <entry><structfield>reserved[6]</structfield></entry>
           <entry>Reserved for future extensions. Should be zeroed by the
           <entry>Reserved for future extensions. Should be zeroed by the
            application.</entry>
            application.</entry>
         </row>
         </row>
@@ -483,8 +483,8 @@ is the Y'CbCr encoding identifier (&v4l2-ycbcr-encoding;) to specify non-standar
 Y'CbCr encodings and the third is the quantization identifier (&v4l2-quantization;)
 Y'CbCr encodings and the third is the quantization identifier (&v4l2-quantization;)
 to specify non-standard quantization methods. Most of the time only the colorspace
 to specify non-standard quantization methods. Most of the time only the colorspace
 field of &v4l2-pix-format; or &v4l2-pix-format-mplane; needs to be filled in. Note
 field of &v4l2-pix-format; or &v4l2-pix-format-mplane; needs to be filled in. Note
-that the default R'G'B' quantization is always full range for all colorspaces,
-so this won't be mentioned explicitly for each colorspace description.</para>
+that the default R'G'B' quantization is full range for all colorspaces except for
+BT.2020 which uses limited range R'G'B' quantization.</para>
 
 
     <table pgwide="1" frame="none" id="v4l2-colorspace">
     <table pgwide="1" frame="none" id="v4l2-colorspace">
       <title>V4L2 Colorspaces</title>
       <title>V4L2 Colorspaces</title>
@@ -598,7 +598,8 @@ so this won't be mentioned explicitly for each colorspace description.</para>
 	  <row>
 	  <row>
 	    <entry><constant>V4L2_QUANTIZATION_DEFAULT</constant></entry>
 	    <entry><constant>V4L2_QUANTIZATION_DEFAULT</constant></entry>
 	    <entry>Use the default quantization encoding as defined by the colorspace.
 	    <entry>Use the default quantization encoding as defined by the colorspace.
-This is always full range for R'G'B' and usually limited range for Y'CbCr.</entry>
+This is always full range for R'G'B' (except for the BT.2020 colorspace) and usually
+limited range for Y'CbCr.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry><constant>V4L2_QUANTIZATION_FULL_RANGE</constant></entry>
 	    <entry><constant>V4L2_QUANTIZATION_FULL_RANGE</constant></entry>
@@ -620,8 +621,8 @@ is mapped to [16&hellip;235]. Cb and Cr are mapped from [-0.5&hellip;0.5] to [16
 
 
   <section>
   <section>
     <title>Detailed Colorspace Descriptions</title>
     <title>Detailed Colorspace Descriptions</title>
-    <section>
-      <title id="col-smpte-170m">Colorspace SMPTE 170M (<constant>V4L2_COLORSPACE_SMPTE170M</constant>)</title>
+    <section id="col-smpte-170m">
+      <title>Colorspace SMPTE 170M (<constant>V4L2_COLORSPACE_SMPTE170M</constant>)</title>
       <para>The <xref linkend="smpte170m" /> standard defines the colorspace used by NTSC and PAL and by SDTV
       <para>The <xref linkend="smpte170m" /> standard defines the colorspace used by NTSC and PAL and by SDTV
 in general. The default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_601</constant>.
 in general. The default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_601</constant>.
 The default Y'CbCr quantization is limited range. The chromaticities of the primary colors and
 The default Y'CbCr quantization is limited range. The chromaticities of the primary colors and
@@ -666,8 +667,7 @@ as the SMPTE C set, so this colorspace is sometimes called SMPTE C as well.</par
       <variablelist>
       <variablelist>
 	<varlistentry>
 	<varlistentry>
           <term>The transfer function defined for SMPTE 170M is the same as the
           <term>The transfer function defined for SMPTE 170M is the same as the
-one defined in Rec. 709. Normally L is in the range [0&hellip;1], but for the extended
-gamut xvYCC encoding values outside that range are allowed.</term>
+one defined in Rec. 709.</term>
 	  <listitem>
 	  <listitem>
             <para>L' = -1.099(-L)<superscript>0.45</superscript>&nbsp;+&nbsp;0.099&nbsp;for&nbsp;L&nbsp;&le;&nbsp;-0.018</para>
             <para>L' = -1.099(-L)<superscript>0.45</superscript>&nbsp;+&nbsp;0.099&nbsp;for&nbsp;L&nbsp;&le;&nbsp;-0.018</para>
             <para>L' = 4.5L&nbsp;for&nbsp;-0.018&nbsp;&lt;&nbsp;L&nbsp;&lt;&nbsp;0.018</para>
             <para>L' = 4.5L&nbsp;for&nbsp;-0.018&nbsp;&lt;&nbsp;L&nbsp;&lt;&nbsp;0.018</para>
@@ -702,29 +702,10 @@ defined in the <xref linkend="itu601" /> standard and this colorspace is sometim
 though BT.601 does not mention any color primaries.</para>
 though BT.601 does not mention any color primaries.</para>
       <para>The default quantization is limited range, but full range is possible although
       <para>The default quantization is limited range, but full range is possible although
 rarely seen.</para>
 rarely seen.</para>
-      <para>The <constant>V4L2_YCBCR_ENC_601</constant> encoding as described above is the
-default for this colorspace, but it can be overridden with <constant>V4L2_YCBCR_ENC_709</constant>,
-in which case the Rec. 709 Y'CbCr encoding is used.</para>
-      <variablelist>
-	<varlistentry>
-      	  <term>The xvYCC 601 encoding (<constant>V4L2_YCBCR_ENC_XV601</constant>, <xref linkend="xvycc" />) is similar
-to the BT.601 encoding, but it allows for R', G' and B' values that are outside the range
-[0&hellip;1]. The resulting Y', Cb and Cr values are scaled and offset:</term>
-	  <listitem>
-            <para>Y'&nbsp;=&nbsp;(219&nbsp;/&nbsp;255)&nbsp;*&nbsp;(0.299R'&nbsp;+&nbsp;0.587G'&nbsp;+&nbsp;0.114B')&nbsp;+&nbsp;(16&nbsp;/&nbsp;255)</para>
-            <para>Cb&nbsp;=&nbsp;(224&nbsp;/&nbsp;255)&nbsp;*&nbsp;(-0.169R'&nbsp;-&nbsp;0.331G'&nbsp;+&nbsp;0.5B')</para>
-            <para>Cr&nbsp;=&nbsp;(224&nbsp;/&nbsp;255)&nbsp;*&nbsp;(0.5R'&nbsp;-&nbsp;0.419G'&nbsp;-&nbsp;0.081B')</para>
-	  </listitem>
-	</varlistentry>
-      </variablelist>
-      <para>Y' is clamped to the range [0&hellip;1] and Cb and Cr are clamped
-to the range [-0.5&hellip;0.5]. The non-standard xvYCC 709 encoding can also be used by selecting
-<constant>V4L2_YCBCR_ENC_XV709</constant>. The xvYCC encodings always use full range
-quantization.</para>
     </section>
     </section>
 
 
-    <section>
-      <title id="col-rec709">Colorspace Rec. 709 (<constant>V4L2_COLORSPACE_REC709</constant>)</title>
+    <section id="col-rec709">
+      <title>Colorspace Rec. 709 (<constant>V4L2_COLORSPACE_REC709</constant>)</title>
       <para>The <xref linkend="itu709" /> standard defines the colorspace used by HDTV in general. The default
       <para>The <xref linkend="itu709" /> standard defines the colorspace used by HDTV in general. The default
 Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_709</constant>. The default Y'CbCr quantization is
 Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_709</constant>. The default Y'CbCr quantization is
 limited range. The chromaticities of the primary colors and the white reference are:</para>
 limited range. The chromaticities of the primary colors and the white reference are:</para>
@@ -803,26 +784,39 @@ rarely seen.</para>
       <para>The <constant>V4L2_YCBCR_ENC_709</constant> encoding described above is the default
       <para>The <constant>V4L2_YCBCR_ENC_709</constant> encoding described above is the default
 for this colorspace, but it can be overridden with <constant>V4L2_YCBCR_ENC_601</constant>, in which
 for this colorspace, but it can be overridden with <constant>V4L2_YCBCR_ENC_601</constant>, in which
 case the BT.601 Y'CbCr encoding is used.</para>
 case the BT.601 Y'CbCr encoding is used.</para>
+      <para>Two additional extended gamut Y'CbCr encodings are also possible with this colorspace:</para>
       <variablelist>
       <variablelist>
 	<varlistentry>
 	<varlistentry>
       	  <term>The xvYCC 709 encoding (<constant>V4L2_YCBCR_ENC_XV709</constant>, <xref linkend="xvycc" />)
       	  <term>The xvYCC 709 encoding (<constant>V4L2_YCBCR_ENC_XV709</constant>, <xref linkend="xvycc" />)
 is similar to the Rec. 709 encoding, but it allows for R', G' and B' values that are outside the range
 is similar to the Rec. 709 encoding, but it allows for R', G' and B' values that are outside the range
 [0&hellip;1]. The resulting Y', Cb and Cr values are scaled and offset:</term>
 [0&hellip;1]. The resulting Y', Cb and Cr values are scaled and offset:</term>
 	  <listitem>
 	  <listitem>
-            <para>Y'&nbsp;=&nbsp;(219&nbsp;/&nbsp;255)&nbsp;*&nbsp;(0.2126R'&nbsp;+&nbsp;0.7152G'&nbsp;+&nbsp;0.0722B')&nbsp;+&nbsp;(16&nbsp;/&nbsp;255)</para>
-            <para>Cb&nbsp;=&nbsp;(224&nbsp;/&nbsp;255)&nbsp;*&nbsp;(-0.1146R'&nbsp;-&nbsp;0.3854G'&nbsp;+&nbsp;0.5B')</para>
-            <para>Cr&nbsp;=&nbsp;(224&nbsp;/&nbsp;255)&nbsp;*&nbsp;(0.5R'&nbsp;-&nbsp;0.4542G'&nbsp;-&nbsp;0.0458B')</para>
+            <para>Y'&nbsp;=&nbsp;(219&nbsp;/&nbsp;256)&nbsp;*&nbsp;(0.2126R'&nbsp;+&nbsp;0.7152G'&nbsp;+&nbsp;0.0722B')&nbsp;+&nbsp;(16&nbsp;/&nbsp;256)</para>
+            <para>Cb&nbsp;=&nbsp;(224&nbsp;/&nbsp;256)&nbsp;*&nbsp;(-0.1146R'&nbsp;-&nbsp;0.3854G'&nbsp;+&nbsp;0.5B')</para>
+            <para>Cr&nbsp;=&nbsp;(224&nbsp;/&nbsp;256)&nbsp;*&nbsp;(0.5R'&nbsp;-&nbsp;0.4542G'&nbsp;-&nbsp;0.0458B')</para>
+	  </listitem>
+	</varlistentry>
+      </variablelist>
+      <variablelist>
+	<varlistentry>
+         <term>The xvYCC 601 encoding (<constant>V4L2_YCBCR_ENC_XV601</constant>, <xref linkend="xvycc" />) is similar
+to the BT.601 encoding, but it allows for R', G' and B' values that are outside the range
+[0&hellip;1]. The resulting Y', Cb and Cr values are scaled and offset:</term>
+	  <listitem>
+            <para>Y'&nbsp;=&nbsp;(219&nbsp;/&nbsp;256)&nbsp;*&nbsp;(0.299R'&nbsp;+&nbsp;0.587G'&nbsp;+&nbsp;0.114B')&nbsp;+&nbsp;(16&nbsp;/&nbsp;256)</para>
+            <para>Cb&nbsp;=&nbsp;(224&nbsp;/&nbsp;256)&nbsp;*&nbsp;(-0.169R'&nbsp;-&nbsp;0.331G'&nbsp;+&nbsp;0.5B')</para>
+            <para>Cr&nbsp;=&nbsp;(224&nbsp;/&nbsp;256)&nbsp;*&nbsp;(0.5R'&nbsp;-&nbsp;0.419G'&nbsp;-&nbsp;0.081B')</para>
 	  </listitem>
 	  </listitem>
 	</varlistentry>
 	</varlistentry>
       </variablelist>
       </variablelist>
       <para>Y' is clamped to the range [0&hellip;1] and Cb and Cr are clamped
       <para>Y' is clamped to the range [0&hellip;1] and Cb and Cr are clamped
-to the range [-0.5&hellip;0.5]. The non-standard xvYCC 601 encoding can also be used by
-selecting <constant>V4L2_YCBCR_ENC_XV601</constant>. The xvYCC encodings always use full
-range quantization.</para>
+to the range [-0.5&hellip;0.5]. The non-standard xvYCC 709 or xvYCC 601 encodings can be used by
+selecting <constant>V4L2_YCBCR_ENC_XV709</constant> or <constant>V4L2_YCBCR_ENC_XV601</constant>.
+The xvYCC encodings always use full range quantization.</para>
     </section>
     </section>
 
 
-    <section>
-      <title id="col-srgb">Colorspace sRGB (<constant>V4L2_COLORSPACE_SRGB</constant>)</title>
+    <section id="col-srgb">
+      <title>Colorspace sRGB (<constant>V4L2_COLORSPACE_SRGB</constant>)</title>
       <para>The <xref linkend="srgb" /> standard defines the colorspace used by most webcams and computer graphics. The
       <para>The <xref linkend="srgb" /> standard defines the colorspace used by most webcams and computer graphics. The
 default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_SYCC</constant>. The default Y'CbCr quantization
 default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_SYCC</constant>. The default Y'CbCr quantization
 is full range. The chromaticities of the primary colors and the white reference are:</para>
 is full range. The chromaticities of the primary colors and the white reference are:</para>
@@ -898,8 +892,8 @@ encoding, it is not. The <constant>V4L2_YCBCR_ENC_XV601</constant> scales and of
 values before quantization, but this encoding does not do that.</para>
 values before quantization, but this encoding does not do that.</para>
     </section>
     </section>
 
 
-    <section>
-      <title id="col-adobergb">Colorspace Adobe RGB (<constant>V4L2_COLORSPACE_ADOBERGB</constant>)</title>
+    <section id="col-adobergb">
+      <title>Colorspace Adobe RGB (<constant>V4L2_COLORSPACE_ADOBERGB</constant>)</title>
       <para>The <xref linkend="adobergb" /> standard defines the colorspace used by computer graphics
       <para>The <xref linkend="adobergb" /> standard defines the colorspace used by computer graphics
 that use the AdobeRGB colorspace. This is also known as the <xref linkend="oprgb" /> standard.
 that use the AdobeRGB colorspace. This is also known as the <xref linkend="oprgb" /> standard.
 The default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_601</constant>. The default Y'CbCr
 The default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_601</constant>. The default Y'CbCr
@@ -970,12 +964,12 @@ clamped to the range [-0.5&hellip;0.5]. This transform is identical to one defin
 SMPTE 170M/BT.601. The Y'CbCr quantization is limited range.</para>
 SMPTE 170M/BT.601. The Y'CbCr quantization is limited range.</para>
     </section>
     </section>
 
 
-    <section>
-      <title id="col-bt2020">Colorspace BT.2020 (<constant>V4L2_COLORSPACE_BT2020</constant>)</title>
+    <section id="col-bt2020">
+      <title>Colorspace BT.2020 (<constant>V4L2_COLORSPACE_BT2020</constant>)</title>
       <para>The <xref linkend="itu2020" /> standard defines the colorspace used by Ultra-high definition
       <para>The <xref linkend="itu2020" /> standard defines the colorspace used by Ultra-high definition
 television (UHDTV). The default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_BT2020</constant>.
 television (UHDTV). The default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_BT2020</constant>.
-The default Y'CbCr quantization is limited range. The chromaticities of the primary colors and
-the white reference are:</para>
+The default R'G'B' quantization is limited range (!), and so is the default Y'CbCr quantization.
+The chromaticities of the primary colors and the white reference are:</para>
       <table frame="none">
       <table frame="none">
         <title>BT.2020 Chromaticities</title>
         <title>BT.2020 Chromaticities</title>
         <tgroup cols="3" align="left">
         <tgroup cols="3" align="left">
@@ -1032,7 +1026,7 @@ the white reference are:</para>
       	  <term>The luminance (Y') and color difference (Cb and Cr) are obtained with the
       	  <term>The luminance (Y') and color difference (Cb and Cr) are obtained with the
 following <constant>V4L2_YCBCR_ENC_BT2020</constant> encoding:</term>
 following <constant>V4L2_YCBCR_ENC_BT2020</constant> encoding:</term>
 	  <listitem>
 	  <listitem>
-            <para>Y'&nbsp;=&nbsp;0.2627R'&nbsp;+&nbsp;0.6789G'&nbsp;+&nbsp;0.0593B'</para>
+            <para>Y'&nbsp;=&nbsp;0.2627R'&nbsp;+&nbsp;0.6780G'&nbsp;+&nbsp;0.0593B'</para>
             <para>Cb&nbsp;=&nbsp;-0.1396R'&nbsp;-&nbsp;0.3604G'&nbsp;+&nbsp;0.5B'</para>
             <para>Cb&nbsp;=&nbsp;-0.1396R'&nbsp;-&nbsp;0.3604G'&nbsp;+&nbsp;0.5B'</para>
             <para>Cr&nbsp;=&nbsp;0.5R'&nbsp;-&nbsp;0.4598G'&nbsp;-&nbsp;0.0402B'</para>
             <para>Cr&nbsp;=&nbsp;0.5R'&nbsp;-&nbsp;0.4598G'&nbsp;-&nbsp;0.0402B'</para>
 	  </listitem>
 	  </listitem>
@@ -1046,7 +1040,7 @@ clamped to the range [-0.5&hellip;0.5]. The Y'CbCr quantization is limited range
 	<varlistentry>
 	<varlistentry>
       	  <term>Luma:</term>
       	  <term>Luma:</term>
 	  <listitem>
 	  <listitem>
-            <para>Yc'&nbsp;=&nbsp;(0.2627R&nbsp;+&nbsp;0.6789G&nbsp;+&nbsp;0.0593B)'</para>
+            <para>Yc'&nbsp;=&nbsp;(0.2627R&nbsp;+&nbsp;0.6780G&nbsp;+&nbsp;0.0593B)'</para>
 	  </listitem>
 	  </listitem>
 	</varlistentry>
 	</varlistentry>
       </variablelist>
       </variablelist>
@@ -1054,7 +1048,7 @@ clamped to the range [-0.5&hellip;0.5]. The Y'CbCr quantization is limited range
 	<varlistentry>
 	<varlistentry>
       	  <term>B'&nbsp;-&nbsp;Yc'&nbsp;&le;&nbsp;0:</term>
       	  <term>B'&nbsp;-&nbsp;Yc'&nbsp;&le;&nbsp;0:</term>
 	  <listitem>
 	  <listitem>
-            <para>Cbc&nbsp;=&nbsp;(B'&nbsp;-&nbsp;Y')&nbsp;/&nbsp;1.9404</para>
+            <para>Cbc&nbsp;=&nbsp;(B'&nbsp;-&nbsp;Yc')&nbsp;/&nbsp;1.9404</para>
 	  </listitem>
 	  </listitem>
 	</varlistentry>
 	</varlistentry>
       </variablelist>
       </variablelist>
@@ -1062,7 +1056,7 @@ clamped to the range [-0.5&hellip;0.5]. The Y'CbCr quantization is limited range
 	<varlistentry>
 	<varlistentry>
       	  <term>B'&nbsp;-&nbsp;Yc'&nbsp;&gt;&nbsp;0:</term>
       	  <term>B'&nbsp;-&nbsp;Yc'&nbsp;&gt;&nbsp;0:</term>
 	  <listitem>
 	  <listitem>
-            <para>Cbc&nbsp;=&nbsp;(B'&nbsp;-&nbsp;Y')&nbsp;/&nbsp;1.5816</para>
+            <para>Cbc&nbsp;=&nbsp;(B'&nbsp;-&nbsp;Yc')&nbsp;/&nbsp;1.5816</para>
 	  </listitem>
 	  </listitem>
 	</varlistentry>
 	</varlistentry>
       </variablelist>
       </variablelist>
@@ -1086,8 +1080,8 @@ clamped to the range [-0.5&hellip;0.5]. The Y'CbCr quantization is limited range
 clamped to the range [-0.5&hellip;0.5]. The Yc'CbcCrc quantization is limited range.</para>
 clamped to the range [-0.5&hellip;0.5]. The Yc'CbcCrc quantization is limited range.</para>
     </section>
     </section>
 
 
-    <section>
-      <title id="col-smpte-240m">Colorspace SMPTE 240M (<constant>V4L2_COLORSPACE_SMPTE240M</constant>)</title>
+    <section id="col-smpte-240m">
+      <title>Colorspace SMPTE 240M (<constant>V4L2_COLORSPACE_SMPTE240M</constant>)</title>
       <para>The <xref linkend="smpte240m" /> standard was an interim standard used during the early days of HDTV (1988-1998).
       <para>The <xref linkend="smpte240m" /> standard was an interim standard used during the early days of HDTV (1988-1998).
 It has been superseded by Rec. 709. The default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_SMPTE240M</constant>.
 It has been superseded by Rec. 709. The default Y'CbCr encoding is <constant>V4L2_YCBCR_ENC_SMPTE240M</constant>.
 The default Y'CbCr quantization is limited range. The chromaticities of the primary colors and the
 The default Y'CbCr quantization is limited range. The chromaticities of the primary colors and the
@@ -1159,8 +1153,8 @@ following <constant>V4L2_YCBCR_ENC_SMPTE240M</constant> encoding:</term>
 clamped to the range [-0.5&hellip;0.5]. The Y'CbCr quantization is limited range.</para>
 clamped to the range [-0.5&hellip;0.5]. The Y'CbCr quantization is limited range.</para>
     </section>
     </section>
 
 
-    <section>
-      <title id="col-sysm">Colorspace NTSC 1953 (<constant>V4L2_COLORSPACE_470_SYSTEM_M</constant>)</title>
+    <section id="col-sysm">
+      <title>Colorspace NTSC 1953 (<constant>V4L2_COLORSPACE_470_SYSTEM_M</constant>)</title>
       <para>This standard defines the colorspace used by NTSC in 1953. In practice this
       <para>This standard defines the colorspace used by NTSC in 1953. In practice this
 colorspace is obsolete and SMPTE 170M should be used instead. The default Y'CbCr encoding
 colorspace is obsolete and SMPTE 170M should be used instead. The default Y'CbCr encoding
 is <constant>V4L2_YCBCR_ENC_601</constant>. The default Y'CbCr quantization is limited range.
 is <constant>V4L2_YCBCR_ENC_601</constant>. The default Y'CbCr quantization is limited range.
@@ -1237,8 +1231,8 @@ clamped to the range [-0.5&hellip;0.5]. The Y'CbCr quantization is limited range
 This transform is identical to one defined in SMPTE 170M/BT.601.</para>
 This transform is identical to one defined in SMPTE 170M/BT.601.</para>
     </section>
     </section>
 
 
-    <section>
-      <title id="col-sysbg">Colorspace EBU Tech. 3213 (<constant>V4L2_COLORSPACE_470_SYSTEM_BG</constant>)</title>
+    <section id="col-sysbg">
+      <title>Colorspace EBU Tech. 3213 (<constant>V4L2_COLORSPACE_470_SYSTEM_BG</constant>)</title>
       <para>The <xref linkend="tech3213" /> standard defines the colorspace used by PAL/SECAM in 1975. In practice this
       <para>The <xref linkend="tech3213" /> standard defines the colorspace used by PAL/SECAM in 1975. In practice this
 colorspace is obsolete and SMPTE 170M should be used instead. The default Y'CbCr encoding
 colorspace is obsolete and SMPTE 170M should be used instead. The default Y'CbCr encoding
 is <constant>V4L2_YCBCR_ENC_601</constant>. The default Y'CbCr quantization is limited range.
 is <constant>V4L2_YCBCR_ENC_601</constant>. The default Y'CbCr quantization is limited range.
@@ -1311,8 +1305,8 @@ clamped to the range [-0.5&hellip;0.5]. The Y'CbCr quantization is limited range
 This transform is identical to one defined in SMPTE 170M/BT.601.</para>
 This transform is identical to one defined in SMPTE 170M/BT.601.</para>
     </section>
     </section>
 
 
-    <section>
-      <title id="col-jpeg">Colorspace JPEG (<constant>V4L2_COLORSPACE_JPEG</constant>)</title>
+    <section id="col-jpeg">
+      <title>Colorspace JPEG (<constant>V4L2_COLORSPACE_JPEG</constant>)</title>
       <para>This colorspace defines the colorspace used by most (Motion-)JPEG formats. The chromaticities
       <para>This colorspace defines the colorspace used by most (Motion-)JPEG formats. The chromaticities
 of the primary colors and the white reference are identical to sRGB. The Y'CbCr encoding is
 of the primary colors and the white reference are identical to sRGB. The Y'CbCr encoding is
 <constant>V4L2_YCBCR_ENC_601</constant> with full range quantization where
 <constant>V4L2_YCBCR_ENC_601</constant> with full range quantization where

+ 434 - 337
Documentation/DocBook/media/v4l/subdev-formats.xml

@@ -482,6 +482,36 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>b<subscript>1</subscript></entry>
 	      <entry>b<subscript>1</subscript></entry>
 	      <entry>b<subscript>0</subscript></entry>
 	      <entry>b<subscript>0</subscript></entry>
 	    </row>
 	    </row>
+	    <row id="MEDIA-BUS-FMT-RBG888-1X24">
+	      <entry>MEDIA_BUS_FMT_RBG888_1X24</entry>
+	      <entry>0x100e</entry>
+	      <entry></entry>
+	      &dash-ent-8;
+	      <entry>r<subscript>7</subscript></entry>
+	      <entry>r<subscript>6</subscript></entry>
+	      <entry>r<subscript>5</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	    </row>
 	    <row id="MEDIA-BUS-FMT-RGB666-1X24_CPADHI">
 	    <row id="MEDIA-BUS-FMT-RGB666-1X24_CPADHI">
 	      <entry>MEDIA_BUS_FMT_RGB666_1X24_CPADHI</entry>
 	      <entry>MEDIA_BUS_FMT_RGB666_1X24_CPADHI</entry>
 	      <entry>0x1015</entry>
 	      <entry>0x1015</entry>
@@ -711,6 +741,43 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>b<subscript>1</subscript></entry>
 	      <entry>b<subscript>1</subscript></entry>
 	      <entry>b<subscript>0</subscript></entry>
 	      <entry>b<subscript>0</subscript></entry>
 	    </row>
 	    </row>
+	    <row id="MEDIA-BUS-FMT-RGB888-1X32-PADHI">
+	      <entry>MEDIA_BUS_FMT_RGB888_1X32_PADHI</entry>
+	      <entry>0x100f</entry>
+	      <entry></entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>0</entry>
+	      <entry>r<subscript>7</subscript></entry>
+	      <entry>r<subscript>6</subscript></entry>
+	      <entry>r<subscript>5</subscript></entry>
+	      <entry>r<subscript>4</subscript></entry>
+	      <entry>r<subscript>3</subscript></entry>
+	      <entry>r<subscript>2</subscript></entry>
+	      <entry>r<subscript>1</subscript></entry>
+	      <entry>r<subscript>0</subscript></entry>
+	      <entry>g<subscript>7</subscript></entry>
+	      <entry>g<subscript>6</subscript></entry>
+	      <entry>g<subscript>5</subscript></entry>
+	      <entry>g<subscript>4</subscript></entry>
+	      <entry>g<subscript>3</subscript></entry>
+	      <entry>g<subscript>2</subscript></entry>
+	      <entry>g<subscript>1</subscript></entry>
+	      <entry>g<subscript>0</subscript></entry>
+	      <entry>b<subscript>7</subscript></entry>
+	      <entry>b<subscript>6</subscript></entry>
+	      <entry>b<subscript>5</subscript></entry>
+	      <entry>b<subscript>4</subscript></entry>
+	      <entry>b<subscript>3</subscript></entry>
+	      <entry>b<subscript>2</subscript></entry>
+	      <entry>b<subscript>1</subscript></entry>
+	      <entry>b<subscript>0</subscript></entry>
+	    </row>
 	  </tbody>
 	  </tbody>
 	</tgroup>
 	</tgroup>
       </table>
       </table>
@@ -2575,11 +2642,15 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-UYVY8-1X16">
-	      <entry>MEDIA_BUS_FMT_UYVY8_1X16</entry>
-	      <entry>0x200f</entry>
+	    <row id="MEDIA-BUS-FMT-UYVY12-2X12">
+	      <entry>MEDIA_BUS_FMT_UYVY12_2X12</entry>
+	      <entry>0x201c</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &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>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2588,6 +2659,16 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2601,7 +2682,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &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>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2610,6 +2695,16 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <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>
+	      <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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2619,11 +2714,15 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-VYUY8-1X16">
-	      <entry>MEDIA_BUS_FMT_VYUY8_1X16</entry>
-	      <entry>0x2010</entry>
+	    <row id="MEDIA-BUS-FMT-VYUY12-2X12">
+	      <entry>MEDIA_BUS_FMT_VYUY12_2X12</entry>
+	      <entry>0x201d</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &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>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2632,6 +2731,16 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <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>
+	      <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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2645,7 +2754,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &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>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2654,6 +2767,16 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2663,11 +2786,15 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-YUYV8-1X16">
-	      <entry>MEDIA_BUS_FMT_YUYV8_1X16</entry>
-	      <entry>0x2011</entry>
+	    <row id="MEDIA-BUS-FMT-YUYV12-2X12">
+	      <entry>MEDIA_BUS_FMT_YUYV12_2X12</entry>
+	      <entry>0x201e</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2676,6 +2803,16 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <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>
+	      <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>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2689,7 +2826,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2698,6 +2839,16 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <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>
+	      <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>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2707,11 +2858,15 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-YVYU8-1X16">
-	      <entry>MEDIA_BUS_FMT_YVYU8_1X16</entry>
-	      <entry>0x2012</entry>
+	    <row id="MEDIA-BUS-FMT-YVYU12-2X12">
+	      <entry>MEDIA_BUS_FMT_YVYU12_2X12</entry>
+	      <entry>0x201f</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2720,6 +2875,16 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <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>
+	      <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>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2733,7 +2898,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-16;
+	      &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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2742,6 +2911,16 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <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>
+	      <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>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2751,11 +2930,19 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	    </row>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YDYUYDYV8-1X16">
-	      <entry>MEDIA_BUS_FMT_YDYUYDYV8_1X16</entry>
-	      <entry>0x2014</entry>
+	    <row id="MEDIA-BUS-FMT-UYVY8-1X16">
+	      <entry>MEDIA_BUS_FMT_UYVY8_1X16</entry>
+	      <entry>0x200f</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      &dash-ent-16;
 	      &dash-ent-16;
+	      <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>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2764,20 +2951,20 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
 	    </row>
 	    </row>
 	    <row>
 	    <row>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      &dash-ent-16;
 	      &dash-ent-16;
+	      <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>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2786,50 +2973,12 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</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>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
-	      <entry></entry>
-	      &dash-ent-16;
-	      <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>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	      <entry>d</entry>
-	    </row>
-	    <row>
-	      <entry></entry>
-	      <entry></entry>
+	    <row id="MEDIA-BUS-FMT-VYUY8-1X16">
+	      <entry>MEDIA_BUS_FMT_VYUY8_1X16</entry>
+	      <entry>0x2010</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      &dash-ent-16;
 	      &dash-ent-16;
-	      <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>7</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2838,24 +2987,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <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 id="MEDIA-BUS-FMT-UYVY10-1X20">
-	      <entry>MEDIA_BUS_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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2869,61 +3000,7 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <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="MEDIA-BUS-FMT-VYUY10-1X20">
-	      <entry>MEDIA_BUS_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>
+	      &dash-ent-16;
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2932,8 +3009,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</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>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2943,13 +3018,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-YUYV10-1X20">
-	      <entry>MEDIA_BUS_FMT_YUYV10_1X20</entry>
-	      <entry>0x200d</entry>
+	    <row id="MEDIA-BUS-FMT-YUYV8-1X16">
+	      <entry>MEDIA_BUS_FMT_YUYV8_1X16</entry>
+	      <entry>0x2011</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2958,8 +3031,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>u<subscript>9</subscript></entry>
-	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -2973,9 +3044,7 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -2984,8 +3053,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>v<subscript>9</subscript></entry>
-	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -2995,13 +3062,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-YVYU10-1X20">
-	      <entry>MEDIA_BUS_FMT_YVYU10_1X20</entry>
-	      <entry>0x200e</entry>
+	    <row id="MEDIA-BUS-FMT-YVYU8-1X16">
+	      <entry>MEDIA_BUS_FMT_YVYU8_1X16</entry>
+	      <entry>0x2012</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -3010,8 +3075,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>v<subscript>9</subscript></entry>
-	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -3025,9 +3088,7 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-12;
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -3036,8 +3097,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>u<subscript>9</subscript></entry>
-	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -3047,18 +3106,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	    </row>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YUV8-1X24">
-	      <entry>MEDIA_BUS_FMT_YUV8_1X24</entry>
-	      <entry>0x2025</entry>
+	    <row id="MEDIA-BUS-FMT-YDYUYDYV8-1X16">
+	      <entry>MEDIA_BUS_FMT_YDYUYDYV8_1X16</entry>
+	      <entry>0x2014</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -3067,31 +3119,20 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</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>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>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
 	    </row>
 	    </row>
-	    <row id="MEDIA-BUS-FMT-YUV10-1X30">
-	      <entry>MEDIA_BUS_FMT_YUV10_1X30</entry>
-	      <entry>0x2016</entry>
+	    <row>
 	      <entry></entry>
 	      <entry></entry>
-	      <entry>-</entry>
-	      <entry>-</entry>
-	      <entry>y<subscript>9</subscript></entry>
-	      <entry>y<subscript>8</subscript></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -3100,8 +3141,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
-	      <entry>u<subscript>9</subscript></entry>
-	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -3110,29 +3149,34 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	      <entry>u<subscript>0</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>
-	    <row id="MEDIA-BUS-FMT-AYUV8-1X32">
-	      <entry>MEDIA_BUS_FMT_AYUV8_1X32</entry>
-	      <entry>0x2017</entry>
+	    <row>
 	      <entry></entry>
 	      <entry></entry>
-	      <entry>a<subscript>7</subscript></entry>
-	      <entry>a<subscript>6</subscript></entry>
-	      <entry>a<subscript>5</subscript></entry>
-	      <entry>a<subscript>4</subscript></entry>
-	      <entry>a<subscript>3</subscript></entry>
-	      <entry>a<subscript>2</subscript></entry>
-	      <entry>a<subscript>1</subscript></entry>
-	      <entry>a<subscript>0</subscript></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-16;
+	      <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>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	      <entry>d</entry>
+	    </row>
+	    <row>
+	      <entry></entry>
+	      <entry></entry>
+	      <entry></entry>
+	      &dash-ent-16;
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>6</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
 	      <entry>y<subscript>5</subscript></entry>
@@ -3141,14 +3185,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</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>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>6</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
 	      <entry>v<subscript>5</subscript></entry>
@@ -3158,13 +3194,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-UYVY12-2X12">
-	      <entry>MEDIA_BUS_FMT_UYVY12_2X12</entry>
-	      <entry>0x201c</entry>
+	    <row id="MEDIA-BUS-FMT-UYVY10-1X20">
+	      <entry>MEDIA_BUS_FMT_UYVY10_1X20</entry>
+	      <entry>0x201a</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>u<subscript>11</subscript></entry>
-	      <entry>u<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>u<subscript>9</subscript></entry>
 	      <entry>u<subscript>9</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
@@ -3175,14 +3209,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</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>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3198,9 +3224,7 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>v<subscript>11</subscript></entry>
-	      <entry>v<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>v<subscript>9</subscript></entry>
 	      <entry>v<subscript>9</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
@@ -3211,14 +3235,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <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>
-	      <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>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3230,13 +3246,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-VYUY12-2X12">
-	      <entry>MEDIA_BUS_FMT_VYUY12_2X12</entry>
-	      <entry>0x201d</entry>
+	    <row id="MEDIA-BUS-FMT-VYUY10-1X20">
+	      <entry>MEDIA_BUS_FMT_VYUY10_1X20</entry>
+	      <entry>0x201b</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>v<subscript>11</subscript></entry>
-	      <entry>v<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>v<subscript>9</subscript></entry>
 	      <entry>v<subscript>9</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
@@ -3247,14 +3261,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <entry>v<subscript>2</subscript></entry>
 	      <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>
-	      <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>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3270,9 +3276,7 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>u<subscript>11</subscript></entry>
-	      <entry>u<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>u<subscript>9</subscript></entry>
 	      <entry>u<subscript>9</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
@@ -3283,14 +3287,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</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>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3302,13 +3298,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-YUYV12-2X12">
-	      <entry>MEDIA_BUS_FMT_YUYV12_2X12</entry>
-	      <entry>0x201e</entry>
+	    <row id="MEDIA-BUS-FMT-YUYV10-1X20">
+	      <entry>MEDIA_BUS_FMT_YUYV10_1X20</entry>
+	      <entry>0x200d</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3319,14 +3313,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <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>
-	      <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>9</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>8</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
@@ -3342,9 +3328,7 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3355,14 +3339,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <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>
-	      <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>9</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
@@ -3374,13 +3350,11 @@ see <xref linkend="colorspaces" />.</entry>
 	      <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="MEDIA-BUS-FMT-YVYU12-2X12">
-	      <entry>MEDIA_BUS_FMT_YVYU12_2X12</entry>
-	      <entry>0x201f</entry>
+	    <row id="MEDIA-BUS-FMT-YVYU10-1X20">
+	      <entry>MEDIA_BUS_FMT_YVYU10_1X20</entry>
+	      <entry>0x200e</entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3391,14 +3365,6 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <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>
-	      <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>9</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>8</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
 	      <entry>v<subscript>7</subscript></entry>
@@ -3414,9 +3380,7 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
 	      <entry></entry>
-	      &dash-ent-20;
-	      <entry>y<subscript>11</subscript></entry>
-	      <entry>y<subscript>10</subscript></entry>
+	      &dash-ent-12;
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>9</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>8</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
 	      <entry>y<subscript>7</subscript></entry>
@@ -3427,16 +3391,67 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>2</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>1</subscript></entry>
 	      <entry>y<subscript>0</subscript></entry>
 	      <entry>y<subscript>0</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>
-	    <row>
-	      <entry></entry>
+	    <row id="MEDIA-BUS-FMT-VUY8-1X24">
+	      <entry>MEDIA_BUS_FMT_VUY8_1X24</entry>
+	      <entry>0x201a</entry>
 	      <entry></entry>
 	      <entry></entry>
+	      &dash-ent-8;
+	      <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>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>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="MEDIA-BUS-FMT-YUV8-1X24">
+	      <entry>MEDIA_BUS_FMT_YUV8_1X24</entry>
+	      <entry>0x2025</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>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</entry>
+	      <entry>-</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>7</subscript></entry>
 	      <entry>u<subscript>7</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>6</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
 	      <entry>u<subscript>5</subscript></entry>
@@ -3445,6 +3460,14 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>2</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	      <entry>u<subscript>0</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>
 	    <row id="MEDIA-BUS-FMT-UYVY12-1X24">
 	    <row id="MEDIA-BUS-FMT-UYVY12-1X24">
 	      <entry>MEDIA_BUS_FMT_UYVY12_1X24</entry>
 	      <entry>MEDIA_BUS_FMT_UYVY12_1X24</entry>
@@ -3686,6 +3709,80 @@ see <xref linkend="colorspaces" />.</entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>1</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	      <entry>u<subscript>0</subscript></entry>
 	    </row>
 	    </row>
+	    <row id="MEDIA-BUS-FMT-YUV10-1X30">
+	      <entry>MEDIA_BUS_FMT_YUV10_1X30</entry>
+	      <entry>0x2016</entry>
+	      <entry></entry>
+	      <entry>-</entry>
+	      <entry>-</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>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>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="MEDIA-BUS-FMT-AYUV8-1X32">
+	      <entry>MEDIA_BUS_FMT_AYUV8_1X32</entry>
+	      <entry>0x2017</entry>
+	      <entry></entry>
+	      <entry>a<subscript>7</subscript></entry>
+	      <entry>a<subscript>6</subscript></entry>
+	      <entry>a<subscript>5</subscript></entry>
+	      <entry>a<subscript>4</subscript></entry>
+	      <entry>a<subscript>3</subscript></entry>
+	      <entry>a<subscript>2</subscript></entry>
+	      <entry>a<subscript>1</subscript></entry>
+	      <entry>a<subscript>0</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>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>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>
 	  </tbody>
 	  </tbody>
 	</tgroup>
 	</tgroup>
       </table>
       </table>

+ 9 - 0
Documentation/DocBook/media/v4l/v4l2.xml

@@ -136,6 +136,7 @@ Remote Controller chapter.</contrib>
       <year>2012</year>
       <year>2012</year>
       <year>2013</year>
       <year>2013</year>
       <year>2014</year>
       <year>2014</year>
+      <year>2015</year>
       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
 Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
 Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
 	Pawel Osciak</holder>
 	Pawel Osciak</holder>
@@ -151,6 +152,14 @@ structs, ioctls) must be noted in more detail in the history chapter
 (compat.xml), along with the possible impact on existing drivers and
 (compat.xml), along with the possible impact on existing drivers and
 applications. -->
 applications. -->
 
 
+      <revision>
+	<revnumber>3.21</revnumber>
+	<date>2015-02-13</date>
+	<authorinitials>mcc</authorinitials>
+	<revremark>Fix documentation for media controller device nodes and add support for DVB device nodes.
+Add support for Tuner sub-device.
+	</revremark>
+      </revision>
       <revision>
       <revision>
 	<revnumber>3.19</revnumber>
 	<revnumber>3.19</revnumber>
 	<date>2014-12-05</date>
 	<date>2014-12-05</date>

+ 6 - 3
Documentation/DocBook/media/v4l/vidioc-cropcap.xml

@@ -59,6 +59,11 @@ constant except when switching the video standard. Remember this
 switch can occur implicit when switching the video input or
 switch can occur implicit when switching the video input or
 output.</para>
 output.</para>
 
 
+<para>Do not use the multiplanar buffer types.  Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
+instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>
+and use <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>.</para>
+
     <para>This ioctl must be implemented for video capture or output devices that
     <para>This ioctl must be implemented for video capture or output devices that
 support cropping and/or scaling and/or have non-square pixels, and for overlay devices.</para>
 support cropping and/or scaling and/or have non-square pixels, and for overlay devices.</para>
 
 
@@ -73,9 +78,7 @@ support cropping and/or scaling and/or have non-square pixels, and for overlay d
 	    <entry>Type of the data stream, set by the application.
 	    <entry>Type of the data stream, set by the application.
 Only these types are valid here:
 Only these types are valid here:
 <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
 <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
-<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>,
-<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
-<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> and
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and
 <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>. See <xref linkend="v4l2-buf-type" />.</entry>
 <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>. See <xref linkend="v4l2-buf-type" />.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>

+ 114 - 7
Documentation/DocBook/media/v4l/vidioc-dqevent.xml

@@ -64,7 +64,7 @@
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
 	    <entry><structfield>type</structfield></entry>
 	    <entry><structfield>type</structfield></entry>
             <entry></entry>
             <entry></entry>
-	    <entry>Type of the event.</entry>
+	    <entry>Type of the event, see <xref linkend="event-type" />.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>union</entry>
 	    <entry>union</entry>
@@ -154,6 +154,113 @@
       </tgroup>
       </tgroup>
     </table>
     </table>
 
 
+    <table frame="none" pgwide="1" id="event-type">
+      <title>Event Types</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_EVENT_ALL</constant></entry>
+	    <entry>0</entry>
+	    <entry>All events. V4L2_EVENT_ALL is valid only for
+	    VIDIOC_UNSUBSCRIBE_EVENT for unsubscribing all events at once.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_EVENT_VSYNC</constant></entry>
+	    <entry>1</entry>
+	    <entry>This event is triggered on the vertical sync.
+	    This event has a &v4l2-event-vsync; associated with it.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_EVENT_EOS</constant></entry>
+	    <entry>2</entry>
+	    <entry>This event is triggered when the end of a stream is reached.
+	    This is typically used with MPEG decoders to report to the application
+	    when the last of the MPEG stream has been decoded.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_EVENT_CTRL</constant></entry>
+	    <entry>3</entry>
+	    <entry><para>This event requires that the <structfield>id</structfield>
+		matches the control ID from which you want to receive events.
+		This event is triggered if the control's value changes, if a
+		button control is pressed or if the control's flags change.
+	    	This event has a &v4l2-event-ctrl; associated with it. This struct
+		contains much of the same information as &v4l2-queryctrl; and
+		&v4l2-control;.</para>
+
+		<para>If the event is generated due to a call to &VIDIOC-S-CTRL; or
+		&VIDIOC-S-EXT-CTRLS;, then the event will <emphasis>not</emphasis> be sent to
+		the file handle that called the ioctl function. This prevents
+		nasty feedback loops. If you <emphasis>do</emphasis> want to get the
+		event, then set the <constant>V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK</constant>
+		flag.
+		</para>
+
+		<para>This event type will ensure that no information is lost when
+		more events are raised than there is room internally. In that
+		case the &v4l2-event-ctrl; of the second-oldest event is kept,
+		but the <structfield>changes</structfield> field of the
+		second-oldest event is ORed with the <structfield>changes</structfield>
+		field of the oldest event.</para>
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_EVENT_FRAME_SYNC</constant></entry>
+	    <entry>4</entry>
+	    <entry>
+	      <para>Triggered immediately when the reception of a
+	      frame has begun. This event has a
+	      &v4l2-event-frame-sync; associated with it.</para>
+
+	      <para>If the hardware needs to be stopped in the case of a
+	      buffer underrun it might not be able to generate this event.
+	      In such cases the <structfield>frame_sequence</structfield>
+	      field in &v4l2-event-frame-sync; will not be incremented. This
+	      causes two consecutive frame sequence numbers to have n times
+	      frame interval in between them.</para>
+	    </entry>
+	  </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>
+	    <entry><constant>V4L2_EVENT_MOTION_DET</constant></entry>
+	    <entry>6</entry>
+	    <entry>
+	      <para>Triggered whenever the motion detection state for one or more of the regions
+	      changes. This event has a &v4l2-event-motion-det; associated with it.</para>
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
+	    <entry>0x08000000</entry>
+	    <entry>Base event number for driver-private events.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
     <table frame="none" pgwide="1" id="v4l2-event-vsync">
     <table frame="none" pgwide="1" id="v4l2-event-vsync">
       <title>struct <structname>v4l2_event_vsync</structname></title>
       <title>struct <structname>v4l2_event_vsync</structname></title>
       <tgroup cols="3">
       <tgroup cols="3">
@@ -177,7 +284,7 @@
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
 	    <entry><structfield>changes</structfield></entry>
 	    <entry><structfield>changes</structfield></entry>
 	    <entry></entry>
 	    <entry></entry>
-	    <entry>A bitmask that tells what has changed. See <xref linkend="changes-flags" />.</entry>
+	    <entry>A bitmask that tells what has changed. See <xref linkend="ctrl-changes-flags" />.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
@@ -309,8 +416,8 @@
       </tgroup>
       </tgroup>
     </table>
     </table>
 
 
-    <table pgwide="1" frame="none" id="changes-flags">
-      <title>Changes</title>
+    <table pgwide="1" frame="none" id="ctrl-changes-flags">
+      <title>Control Changes</title>
       <tgroup cols="3">
       <tgroup cols="3">
 	&cs-def;
 	&cs-def;
 	<tbody valign="top">
 	<tbody valign="top">
@@ -318,9 +425,9 @@
 	    <entry><constant>V4L2_EVENT_CTRL_CH_VALUE</constant></entry>
 	    <entry><constant>V4L2_EVENT_CTRL_CH_VALUE</constant></entry>
 	    <entry>0x0001</entry>
 	    <entry>0x0001</entry>
 	    <entry>This control event was triggered because the value of the control
 	    <entry>This control event was triggered because the value of the control
-		changed. Special case: if a button control is pressed, then this
-		event is sent as well, even though there is not explicit value
-		associated with a button control.</entry>
+		changed. Special cases: Volatile controls do no generate this event;
+		If a control has the <constant>V4L2_CTRL_FLAG_EXECUTE_ON_WRITE</constant>
+		flag set, then this event is sent as well, regardless its value.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry><constant>V4L2_EVENT_CTRL_CH_FLAGS</constant></entry>
 	    <entry><constant>V4L2_EVENT_CTRL_CH_FLAGS</constant></entry>

+ 5 - 0
Documentation/DocBook/media/v4l/vidioc-g-crop.xml

@@ -70,6 +70,11 @@ structure or returns the &EINVAL; if cropping is not supported.</para>
 <constant>VIDIOC_S_CROP</constant> ioctl with a pointer to this
 <constant>VIDIOC_S_CROP</constant> ioctl with a pointer to this
 structure.</para>
 structure.</para>
 
 
+<para>Do not use the multiplanar buffer types.  Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
+instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>
+and use <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>.</para>
+
     <para>The driver first adjusts the requested dimensions against
     <para>The driver first adjusts the requested dimensions against
 hardware limits, &ie; the bounds given by the capture/output window,
 hardware limits, &ie; the bounds given by the capture/output window,
 and it rounds to the closest possible values of horizontal and
 and it rounds to the closest possible values of horizontal and

+ 14 - 4
Documentation/DocBook/media/v4l/vidioc-g-dv-timings.xml

@@ -318,10 +318,20 @@ can't generate such frequencies, then the flag will also be cleared.
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>V4L2_DV_FL_HALF_LINE</entry>
 	    <entry>V4L2_DV_FL_HALF_LINE</entry>
-	    <entry>Specific to interlaced formats: if set, then field 1 (aka the odd field)
-is really one half-line longer and field 2 (aka the even field) is really one half-line
-shorter, so each field has exactly the same number of half-lines. Whether half-lines can be
-detected or used depends on the hardware.
+	    <entry>Specific to interlaced formats: if set, then the vertical frontporch
+of field 1 (aka the odd field) is really one half-line longer and the vertical backporch
+of field 2 (aka the even field) is really one half-line shorter, so each field has exactly
+the same number of half-lines. Whether half-lines can be detected or used depends on
+the hardware.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_DV_FL_IS_CE_VIDEO</entry>
+	    <entry>If set, then this is a Consumer Electronics (CE) video format.
+Such formats differ from other formats (commonly called IT formats) in that if
+R'G'B' encoding is used then by default the R'G'B' values use limited range
+(i.e. 16-235) as opposed to full range (i.e. 0-255). All formats defined in CEA-861
+except for the 640x480p59.94 format are CE formats.
 	    </entry>
 	    </entry>
 	  </row>
 	  </row>
 	</tbody>
 	</tbody>

+ 2 - 2
Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml

@@ -240,9 +240,9 @@ where padding bytes after the last line of an image cross a system
 page boundary. Capture devices may write padding bytes, the value is
 page boundary. Capture devices may write padding bytes, the value is
 undefined. Output devices ignore the contents of padding
 undefined. Output devices ignore the contents of padding
 bytes.</para><para>When the image format is planar the
 bytes.</para><para>When the image format is planar the
-<structfield>bytesperline</structfield> value applies to the largest
+<structfield>bytesperline</structfield> value applies to the first
 plane and is divided by the same factor as the
 plane and is divided by the same factor as the
-<structfield>width</structfield> field for any smaller planes. For
+<structfield>width</structfield> field for the other planes. For
 example the Cb and Cr planes of a YUV 4:2:0 image have half as many
 example the Cb and Cr planes of a YUV 4:2:0 image have half as many
 padding bytes following each line as the Y plane. To avoid ambiguities
 padding bytes following each line as the Y plane. To avoid ambiguities
 drivers must return a <structfield>bytesperline</structfield> value
 drivers must return a <structfield>bytesperline</structfield> value

+ 2 - 2
Documentation/DocBook/media/v4l/vidioc-g-selection.xml

@@ -60,8 +60,8 @@
 
 
 <para>To query the cropping (composing) rectangle set &v4l2-selection;
 <para>To query the cropping (composing) rectangle set &v4l2-selection;
 <structfield> type </structfield> field to the respective buffer type.
 <structfield> type </structfield> field to the respective buffer type.
-Do not use multiplanar buffers.  Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
-instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>.  Use
+Do not use the multiplanar buffer types.  Use <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>
+instead of <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant> and use
 <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
 <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> instead of
 <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>.  The next step is
 <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>.  The next step is
 setting the value of &v4l2-selection; <structfield>target</structfield> field
 setting the value of &v4l2-selection; <structfield>target</structfield> field

+ 4 - 4
Documentation/DocBook/media/v4l/vidioc-querycap.xml

@@ -102,10 +102,10 @@ The bus_info must start with "PCI:" for PCI boards, "PCIe:" for PCI Express boar
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
 	    <entry><structfield>version</structfield></entry>
 	    <entry><structfield>version</structfield></entry>
 	    <entry><para>Version number of the driver.</para>
 	    <entry><para>Version number of the driver.</para>
-<para>Starting on kernel 3.1, the version reported is provided per
-V4L2 subsystem, following the same Kernel numberation scheme. However, it
-should not always return the same version as the kernel, if, for example,
-an stable or distribution-modified kernel uses the V4L2 stack from a
+<para>Starting with kernel 3.1, the version reported is provided by the
+V4L2 subsystem following the kernel numbering scheme. However, it
+may not always return the same version as the kernel if, for example,
+a stable or distribution-modified kernel uses the V4L2 stack from a
 newer kernel.</para>
 newer kernel.</para>
 <para>The version number is formatted using the
 <para>The version number is formatted using the
 <constant>KERNEL_VERSION()</constant> macro:</para></entry>
 <constant>KERNEL_VERSION()</constant> macro:</para></entry>

+ 11 - 1
Documentation/DocBook/media/v4l/vidioc-queryctrl.xml

@@ -600,7 +600,9 @@ writing a value will cause the device to carry out a given action
 changes continuously. A typical example would be the current gain value if the device
 changes continuously. A typical example would be the current gain value if the device
 is in auto-gain mode. In such a case the hardware calculates the gain value based on
 is in auto-gain mode. In such a case the hardware calculates the gain value based on
 the lighting conditions which can change over time. Note that setting a new value for
 the lighting conditions which can change over time. Note that setting a new value for
-a volatile control will have no effect. The new value will just be ignored.</entry>
+a volatile control will have no effect and no <constant>V4L2_EVENT_CTRL_CH_VALUE</constant>
+will be sent, unless the <constant>V4L2_CTRL_FLAG_EXECUTE_ON_WRITE</constant> flag
+(see below) is also set. Otherwise the new value will just be ignored.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry><constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant></entry>
 	    <entry><constant>V4L2_CTRL_FLAG_HAS_PAYLOAD</constant></entry>
@@ -610,6 +612,14 @@ using one of the pointer fields of &v4l2-ext-control;. This flag is set for cont
 that are an array, string, or have a compound type. In all cases you have to set a
 that are an array, string, or have a compound type. In all cases you have to set a
 pointer to memory containing the payload of the control.</entry>
 pointer to memory containing the payload of the control.</entry>
 	  </row>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_FLAG_EXECUTE_ON_WRITE</constant></entry>
+	    <entry>0x0200</entry>
+	    <entry>The value provided to the control will be propagated to the driver
+even if remains constant. This is required when the control represents an action
+on the hardware. For example: clearing an error flag or triggering the flash. All the
+controls of the type <constant>V4L2_CTRL_TYPE_BUTTON</constant> have this flag set.</entry>
+	  </row>
 	</tbody>
 	</tbody>
       </tgroup>
       </tgroup>
     </table>
     </table>

+ 9 - 4
Documentation/DocBook/media/v4l/vidioc-subdev-enum-frame-interval.xml

@@ -67,9 +67,9 @@
 
 
     <para>To enumerate frame intervals applications initialize the
     <para>To enumerate frame intervals applications initialize the
     <structfield>index</structfield>, <structfield>pad</structfield>,
     <structfield>index</structfield>, <structfield>pad</structfield>,
-    <structfield>code</structfield>, <structfield>width</structfield> and
-    <structfield>height</structfield> fields of
-    &v4l2-subdev-frame-interval-enum; and call the
+    <structfield>which</structfield>, <structfield>code</structfield>,
+    <structfield>width</structfield> and <structfield>height</structfield>
+    fields of &v4l2-subdev-frame-interval-enum; and call the
     <constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer
     <constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer
     to this structure. Drivers fill the rest of the structure or return
     to this structure. Drivers fill the rest of the structure or return
     an &EINVAL; if one of the input fields is invalid. All frame intervals are
     an &EINVAL; if one of the input fields is invalid. All frame intervals are
@@ -123,7 +123,12 @@
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
-	    <entry><structfield>reserved</structfield>[9]</entry>
+	    <entry><structfield>which</structfield></entry>
+	    <entry>Frame intervals to be enumerated, from &v4l2-subdev-format-whence;.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
 	    <entry>Reserved for future extensions. Applications and drivers must
 	    <entry>Reserved for future extensions. Applications and drivers must
 	    set the array to zero.</entry>
 	    set the array to zero.</entry>
 	  </row>
 	  </row>

+ 9 - 4
Documentation/DocBook/media/v4l/vidioc-subdev-enum-frame-size.xml

@@ -61,9 +61,9 @@
     ioctl.</para>
     ioctl.</para>
 
 
     <para>To enumerate frame sizes applications initialize the
     <para>To enumerate frame sizes applications initialize the
-    <structfield>pad</structfield>, <structfield>code</structfield> and
-    <structfield>index</structfield> fields of the
-    &v4l2-subdev-mbus-code-enum; and call the
+    <structfield>pad</structfield>, <structfield>which</structfield> ,
+    <structfield>code</structfield> and <structfield>index</structfield>
+    fields of the &v4l2-subdev-mbus-code-enum; and call the
     <constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to
     <constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to
     the structure. Drivers fill the minimum and maximum frame sizes or return
     the structure. Drivers fill the minimum and maximum frame sizes or return
     an &EINVAL; if one of the input parameters is invalid.</para>
     an &EINVAL; if one of the input parameters is invalid.</para>
@@ -127,7 +127,12 @@
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
-	    <entry><structfield>reserved</structfield>[9]</entry>
+	    <entry><structfield>which</structfield></entry>
+	    <entry>Frame sizes to be enumerated, from &v4l2-subdev-format-whence;.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
 	    <entry>Reserved for future extensions. Applications and drivers must
 	    <entry>Reserved for future extensions. Applications and drivers must
 	    set the array to zero.</entry>
 	    set the array to zero.</entry>
 	  </row>
 	  </row>

+ 8 - 3
Documentation/DocBook/media/v4l/vidioc-subdev-enum-mbus-code.xml

@@ -56,8 +56,8 @@
     </note>
     </note>
 
 
     <para>To enumerate media bus formats available at a given sub-device pad
     <para>To enumerate media bus formats available at a given sub-device pad
-    applications initialize the <structfield>pad</structfield> and
-    <structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and
+    applications initialize the <structfield>pad</structfield>, <structfield>which</structfield>
+    and <structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and
     call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a
     call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a
     pointer to this structure. Drivers fill the rest of the structure or return
     pointer to this structure. Drivers fill the rest of the structure or return
     an &EINVAL; if either the <structfield>pad</structfield> or
     an &EINVAL; if either the <structfield>pad</structfield> or
@@ -93,7 +93,12 @@
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
-	    <entry><structfield>reserved</structfield>[9]</entry>
+	    <entry><structfield>which</structfield></entry>
+	    <entry>Media bus format codes to be enumerated, from &v4l2-subdev-format-whence;.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
 	    <entry>Reserved for future extensions. Applications and drivers must
 	    <entry>Reserved for future extensions. Applications and drivers must
 	    set the array to zero.</entry>
 	    set the array to zero.</entry>
 	  </row>
 	  </row>

+ 3 - 108
Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml

@@ -60,7 +60,9 @@
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
 	    <entry><structfield>type</structfield></entry>
 	    <entry><structfield>type</structfield></entry>
-	    <entry>Type of the event.</entry>
+	    <entry>Type of the event, see <xref linkend="event-type" />. Note that
+<constant>V4L2_EVENT_ALL</constant> can be used with VIDIOC_UNSUBSCRIBE_EVENT
+for unsubscribing all events at once.</entry>
 	  </row>
 	  </row>
 	  <row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry>__u32</entry>
@@ -84,113 +86,6 @@
       </tgroup>
       </tgroup>
     </table>
     </table>
 
 
-    <table frame="none" pgwide="1" id="event-type">
-      <title>Event Types</title>
-      <tgroup cols="3">
-	&cs-def;
-	<tbody valign="top">
-	  <row>
-	    <entry><constant>V4L2_EVENT_ALL</constant></entry>
-	    <entry>0</entry>
-	    <entry>All events. V4L2_EVENT_ALL is valid only for
-	    VIDIOC_UNSUBSCRIBE_EVENT for unsubscribing all events at once.
-	    </entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_EVENT_VSYNC</constant></entry>
-	    <entry>1</entry>
-	    <entry>This event is triggered on the vertical sync.
-	    This event has a &v4l2-event-vsync; associated with it.
-	    </entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_EVENT_EOS</constant></entry>
-	    <entry>2</entry>
-	    <entry>This event is triggered when the end of a stream is reached.
-	    This is typically used with MPEG decoders to report to the application
-	    when the last of the MPEG stream has been decoded.
-	    </entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_EVENT_CTRL</constant></entry>
-	    <entry>3</entry>
-	    <entry><para>This event requires that the <structfield>id</structfield>
-		matches the control ID from which you want to receive events.
-		This event is triggered if the control's value changes, if a
-		button control is pressed or if the control's flags change.
-	    	This event has a &v4l2-event-ctrl; associated with it. This struct
-		contains much of the same information as &v4l2-queryctrl; and
-		&v4l2-control;.</para>
-
-		<para>If the event is generated due to a call to &VIDIOC-S-CTRL; or
-		&VIDIOC-S-EXT-CTRLS;, then the event will <emphasis>not</emphasis> be sent to
-		the file handle that called the ioctl function. This prevents
-		nasty feedback loops. If you <emphasis>do</emphasis> want to get the
-		event, then set the <constant>V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK</constant>
-		flag.
-		</para>
-
-		<para>This event type will ensure that no information is lost when
-		more events are raised than there is room internally. In that
-		case the &v4l2-event-ctrl; of the second-oldest event is kept,
-		but the <structfield>changes</structfield> field of the
-		second-oldest event is ORed with the <structfield>changes</structfield>
-		field of the oldest event.</para>
-	    </entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_EVENT_FRAME_SYNC</constant></entry>
-	    <entry>4</entry>
-	    <entry>
-	      <para>Triggered immediately when the reception of a
-	      frame has begun. This event has a
-	      &v4l2-event-frame-sync; associated with it.</para>
-
-	      <para>If the hardware needs to be stopped in the case of a
-	      buffer underrun it might not be able to generate this event.
-	      In such cases the <structfield>frame_sequence</structfield>
-	      field in &v4l2-event-frame-sync; will not be incremented. This
-	      causes two consecutive frame sequence numbers to have n times
-	      frame interval in between them.</para>
-	    </entry>
-	  </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>
-	    <entry><constant>V4L2_EVENT_MOTION_DET</constant></entry>
-	    <entry>6</entry>
-	    <entry>
-	      <para>Triggered whenever the motion detection state for one or more of the regions
-	      changes. This event has a &v4l2-event-motion-det; associated with it.</para>
-	    </entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry>
-	    <entry>0x08000000</entry>
-	    <entry>Base event number for driver-private events.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-
     <table pgwide="1" frame="none" id="event-flags">
     <table pgwide="1" frame="none" id="event-flags">
       <title>Event Flags</title>
       <title>Event Flags</title>
       <tgroup cols="3">
       <tgroup cols="3">

+ 1 - 1
Documentation/devicetree/bindings/media/exynos-jpeg-codec.txt

@@ -4,7 +4,7 @@ Required properties:
 
 
 - compatible	: should be one of:
 - compatible	: should be one of:
 		  "samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg",
 		  "samsung,s5pv210-jpeg", "samsung,exynos4210-jpeg",
-		  "samsung,exynos3250-jpeg";
+		  "samsung,exynos3250-jpeg", "samsung,exynos5420-jpeg";
 - reg		: address and length of the JPEG codec IP register set;
 - reg		: address and length of the JPEG codec IP register set;
 - interrupts	: specifies the JPEG codec IP interrupt;
 - interrupts	: specifies the JPEG codec IP interrupt;
 - clock-names   : should contain:
 - clock-names   : should contain:

+ 39 - 0
Documentation/devicetree/bindings/media/i2c/mt9v032.txt

@@ -0,0 +1,39 @@
+* Aptina 1/3-Inch WVGA CMOS Digital Image Sensor
+
+The Aptina MT9V032 is a 1/3-inch CMOS active pixel digital image sensor with
+an active array size of 752H x 480V. It is programmable through a simple
+two-wire serial interface.
+
+Required Properties:
+
+- compatible: value should be either one among the following
+	(a) "aptina,mt9v022" for MT9V022 color sensor
+	(b) "aptina,mt9v022m" for MT9V022 monochrome sensor
+	(c) "aptina,mt9v024" for MT9V024 color sensor
+	(d) "aptina,mt9v024m" for MT9V024 monochrome sensor
+	(e) "aptina,mt9v032" for MT9V032 color sensor
+	(f) "aptina,mt9v032m" for MT9V032 monochrome sensor
+	(g) "aptina,mt9v034" for MT9V034 color sensor
+	(h) "aptina,mt9v034m" for MT9V034 monochrome sensor
+
+Optional Properties:
+
+- link-frequencies: List of allowed link frequencies in Hz. Each frequency is
+	expressed as a 64-bit big-endian integer.
+
+For further reading on port node refer to
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+
+	mt9v032@5c {
+		compatible = "aptina,mt9v032";
+		reg = <0x5c>;
+
+		port {
+			mt9v032_out: endpoint {
+				link-frequencies = /bits/ 64
+					<13000000 26600000 27000000>;
+			};
+		};
+	};

+ 46 - 0
Documentation/devicetree/bindings/media/i2c/ov2640.txt

@@ -0,0 +1,46 @@
+* Omnivision OV2640 CMOS sensor
+
+The Omnivision OV2640 sensor support multiple resolutions output, such as
+CIF, SVGA, UXGA. It also can support YUV422/420, RGB565/555 or raw RGB
+output format.
+
+Required Properties:
+- compatible: should be "ovti,ov2640"
+- clocks: reference to the xvclk input clock.
+- clock-names: should be "xvclk".
+
+Optional Properties:
+- resetb-gpios: reference to the GPIO connected to the resetb pin, if any.
+- pwdn-gpios: reference to the GPIO connected to the pwdn pin, if any.
+
+The device node must contain one 'port' child node for its digital output
+video port, in accordance with the video interface bindings defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+
+	i2c1: i2c@f0018000 {
+		ov2640: camera@0x30 {
+			compatible = "ovti,ov2640";
+			reg = <0x30>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_pck1 &pinctrl_ov2640_pwdn &pinctrl_ov2640_resetb>;
+
+			resetb-gpios = <&pioE 24 GPIO_ACTIVE_LOW>;
+			pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>;
+
+			clocks = <&pck1>;
+			clock-names = "xvclk";
+
+			assigned-clocks = <&pck1>;
+			assigned-clock-rates = <25000000>;
+
+			port {
+				ov2640_0: endpoint {
+					remote-endpoint = <&isi_0>;
+					bus-width = <8>;
+				};
+			};
+		};
+	};

+ 38 - 0
Documentation/devicetree/bindings/media/i2c/ov2659.txt

@@ -0,0 +1,38 @@
+* OV2659 1/5-Inch 2Mp SOC Camera
+
+The Omnivision OV2659 is a 1/5-inch SOC camera, with an active array size of
+1632H x 1212V. It is programmable through a SCCB. The OV2659 sensor supports
+multiple resolutions output, such as UXGA, SVGA, 720p. It also can support
+YUV422, RGB565/555 or raw RGB output formats.
+
+Required Properties:
+- compatible: Must be "ovti,ov2659"
+- reg: I2C slave address
+- clocks: reference to the xvclk input clock.
+- clock-names: should be "xvclk".
+- link-frequencies: target pixel clock frequency.
+
+For further reading on port node refer to
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+
+	i2c0@1c22000 {
+		...
+		...
+		 ov2659@30 {
+			compatible = "ovti,ov2659";
+			reg = <0x30>;
+
+			clocks = <&clk_ov2659 0>;
+			clock-names = "xvclk";
+
+			port {
+				ov2659_0: endpoint {
+					remote-endpoint = <&vpfe_ep>;
+					link-frequencies = /bits/ 64 <70000000>;
+				};
+			};
+		};
+		...
+	};

+ 6 - 0
Documentation/devicetree/bindings/media/video-interfaces.txt

@@ -106,6 +106,12 @@ Optional endpoint properties
 - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
 - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
   instance, this is the actual frequency of the bus, not bits per clock per
   instance, this is the actual frequency of the bus, not bits per clock per
   lane value. An array of 64-bit unsigned integers.
   lane value. An array of 64-bit unsigned integers.
+- lane-polarities: an array of polarities of the lanes starting from the clock
+  lane and followed by the data lanes in the same order as in data-lanes.
+  Valid values are 0 (normal) and 1 (inverted). The length of the array
+  should be the combined length of data-lanes and clock-lanes properties.
+  If the lane-polarities property is omitted, the value must be interpreted
+  as 0 (normal). This property is valid for serial busses only.
 
 
 
 
 Example
 Example

+ 35 - 0
Documentation/devicetree/bindings/media/xilinx/video.txt

@@ -0,0 +1,35 @@
+DT bindings for Xilinx video IP cores
+-------------------------------------
+
+Xilinx video IP cores process video streams by acting as video sinks and/or
+sources. They are connected by links through their input and output ports,
+creating a video pipeline.
+
+Each video IP core is represented by an AMBA bus child node in the device
+tree using bindings documented in this directory. Connections between the IP
+cores are represented as defined in ../video-interfaces.txt.
+
+The whole  pipeline is represented by an AMBA bus child node in the device
+tree using bindings documented in ./xlnx,video.txt.
+
+Common properties
+-----------------
+
+The following properties are common to all Xilinx video IP cores.
+
+- xlnx,video-format: This property represents a video format transmitted on an
+  AXI bus between video IP cores, using its VF code as defined in "AXI4-Stream
+  Video IP and System Design Guide" [UG934]. How the format relates to the IP
+  core is decribed in the IP core bindings documentation.
+
+- xlnx,video-width: This property qualifies the video format with the sample
+  width expressed as a number of bits per pixel component. All components must
+  use the same width.
+
+- xlnx,cfa-pattern: When the video format is set to Mono/Sensor, this property
+  describes the sensor's color filter array pattern. Supported values are
+  "bggr", "gbrg", "grbg", "rggb" and "mono". If not specified, the pattern
+  defaults to "mono".
+
+
+[UG934] http://www.xilinx.com/support/documentation/ip_documentation/axi_videoip/v1_0/ug934_axi_videoIP.pdf

+ 33 - 0
Documentation/devicetree/bindings/media/xilinx/xlnx,v-tc.txt

@@ -0,0 +1,33 @@
+Xilinx Video Timing Controller (VTC)
+------------------------------------
+
+The Video Timing Controller is a general purpose video timing generator and
+detector.
+
+Required properties:
+
+  - compatible: Must be "xlnx,v-tc-6.1".
+
+  - reg: Physical base address and length of the registers set for the device.
+
+  - clocks: Must contain a clock specifier for the VTC core and timing
+    interfaces clock.
+
+Optional properties:
+
+  - xlnx,detector: The VTC has a timing detector
+  - xlnx,generator: The VTC has a timing generator
+
+  At least one of the xlnx,detector and xlnx,generator properties must be
+  specified.
+
+
+Example:
+
+	vtc: vtc@43c40000 {
+		compatible = "xlnx,v-tc-6.1";
+		reg = <0x43c40000 0x10000>;
+
+		clocks = <&clkc 15>;
+		xlnx,generator;
+	};

+ 71 - 0
Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt

@@ -0,0 +1,71 @@
+Xilinx Video Test Pattern Generator (TPG)
+-----------------------------------------
+
+Required properties:
+
+- compatible: Must contain at least one of
+
+    "xlnx,v-tpg-5.0" (TPG version 5.0)
+    "xlnx,v-tpg-6.0" (TPG version 6.0)
+
+  TPG versions backward-compatible with previous versions should list all
+  compatible versions in the newer to older order.
+
+- reg: Physical base address and length of the registers set for the device.
+
+- clocks: Reference to the video core clock.
+
+- xlnx,video-format, xlnx,video-width: Video format and width, as defined in
+  video.txt.
+
+- port: Video port, using the DT bindings defined in ../video-interfaces.txt.
+  The TPG has a single output port numbered 0.
+
+Optional properties:
+
+- xlnx,vtc: A phandle referencing the Video Timing Controller that generates
+  video timings for the TPG test patterns.
+
+- timing-gpios: Specifier for a GPIO that controls the timing mux at the TPG
+  input. The GPIO active level corresponds to the selection of VTC-generated
+  video timings.
+
+The xlnx,vtc and timing-gpios properties are mandatory when the TPG is
+synthesized with two ports and forbidden when synthesized with one port.
+
+Example:
+
+	tpg_0: tpg@40050000 {
+		compatible = "xlnx,v-tpg-6.0", "xlnx,v-tpg-5.0";
+		reg = <0x40050000 0x10000>;
+		clocks = <&clkc 15>;
+
+		xlnx,vtc = <&vtc_3>;
+		timing-gpios = <&ps7_gpio_0 55 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				xlnx,video-format = <XVIP_VF_YUV_422>;
+				xlnx,video-width = <8>;
+
+				tpg_in: endpoint {
+					remote-endpoint = <&adv7611_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+
+				xlnx,video-format = <XVIP_VF_YUV_422>;
+				xlnx,video-width = <8>;
+
+				tpg1_out: endpoint {
+					remote-endpoint = <&switch_in0>;
+				};
+			}:
+		};
+	};

+ 55 - 0
Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt

@@ -0,0 +1,55 @@
+Xilinx Video IP Pipeline (VIPP)
+-------------------------------
+
+General concept
+---------------
+
+Xilinx video IP pipeline processes video streams through one or more Xilinx
+video IP cores. Each video IP core is represented as documented in video.txt
+and IP core specific documentation, xlnx,v-*.txt, in this directory. The DT
+node of the VIPP represents as a top level node of the pipeline and defines
+mappings between DMAs and the video IP cores.
+
+Required properties:
+
+- compatible: Must be "xlnx,video".
+
+- dmas, dma-names: List of one DMA specifier and identifier string (as defined
+  in Documentation/devicetree/bindings/dma/dma.txt) per port. Each port
+  requires a DMA channel with the identifier string set to "port" followed by
+  the port index.
+
+- ports: Video port, using the DT bindings defined in ../video-interfaces.txt.
+
+Required port properties:
+
+- direction: should be either "input" or "output" depending on the direction
+  of stream.
+
+Example:
+
+	video_cap {
+		compatible = "xlnx,video";
+		dmas = <&vdma_1 1>, <&vdma_3 1>;
+		dma-names = "port0", "port1";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				direction = "input";
+				vcap0_in0: endpoint {
+					remote-endpoint = <&scaler0_out>;
+				};
+			};
+			port@1 {
+				reg = <1>;
+				direction = "input";
+				vcap0_in1: endpoint {
+					remote-endpoint = <&switch_out1>;
+				};
+			};
+		};
+	};

+ 1 - 0
Documentation/devicetree/bindings/vendor-prefixes.txt

@@ -21,6 +21,7 @@ ampire	Ampire Co., Ltd.
 ams	AMS AG
 ams	AMS AG
 amstaos	AMS-Taos Inc.
 amstaos	AMS-Taos Inc.
 apm	Applied Micro Circuits Corporation (APM)
 apm	Applied Micro Circuits Corporation (APM)
+aptina	Aptina Imaging
 arasan	Arasan Chip Systems
 arasan	Arasan Chip Systems
 arm	ARM Ltd.
 arm	ARM Ltd.
 armadeus	ARMadeus Systems SARL
 armadeus	ARMadeus Systems SARL

+ 3 - 1
Documentation/video4linux/v4l2-controls.txt

@@ -344,7 +344,9 @@ implement g_volatile_ctrl like this:
 	}
 	}
 
 
 Note that you use the 'new value' union as well in g_volatile_ctrl. In general
 Note that you use the 'new value' union as well in g_volatile_ctrl. In general
-controls that need to implement g_volatile_ctrl are read-only controls.
+controls that need to implement g_volatile_ctrl are read-only controls. If they
+are not, a V4L2_EVENT_CTRL_CH_VALUE will not be generated when the control
+changes.
 
 
 To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE:
 To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE:
 
 

+ 3 - 3
Documentation/video4linux/v4l2-framework.txt

@@ -793,8 +793,8 @@ video_register_device_no_warn() instead.
 
 
 Whenever a device node is created some attributes are also created for you.
 Whenever a device node is created some attributes are also created for you.
 If you look in /sys/class/video4linux you see the devices. Go into e.g.
 If you look in /sys/class/video4linux you see the devices. Go into e.g.
-video0 and you will see 'name', 'debug' and 'index' attributes. The 'name'
-attribute is the 'name' field of the video_device struct. The 'debug' attribute
+video0 and you will see 'name', 'dev_debug' and 'index' attributes. The 'name'
+attribute is the 'name' field of the video_device struct. The 'dev_debug' attribute
 can be used to enable core debugging. See the next section for more detailed
 can be used to enable core debugging. See the next section for more detailed
 information on this.
 information on this.
 
 
@@ -821,7 +821,7 @@ unregister the device if the registration failed.
 video device debugging
 video device debugging
 ----------------------
 ----------------------
 
 
-The 'debug' attribute that is created for each video, vbi, radio or swradio
+The 'dev_debug' attribute that is created for each video, vbi, radio or swradio
 device in /sys/class/video4linux/<devX>/ allows you to enable logging of
 device in /sys/class/video4linux/<devX>/ allows you to enable logging of
 file operations.
 file operations.
 
 

+ 5 - 0
Documentation/video4linux/vivid.txt

@@ -912,6 +912,11 @@ looped to the video input provided that:
   sequence and field counting in struct v4l2_buffer on the capture side may not
   sequence and field counting in struct v4l2_buffer on the capture side may not
   be 100% accurate.
   be 100% accurate.
 
 
+- field settings V4L2_FIELD_SEQ_TB/BT are not supported. While it is possible to
+  implement this, it would mean a lot of work to get this right. Since these
+  field values are rarely used the decision was made not to implement this for
+  now.
+
 - on the input side the "Standard Signal Mode" for the S-Video input or the
 - on the input side the "Standard Signal Mode" for the S-Video input or the
   "DV Timings Signal Mode" for the HDMI input should be configured so that a
   "DV Timings Signal Mode" for the HDMI input should be configured so that a
   valid signal is passed to the video input.
   valid signal is passed to the video input.

+ 22 - 11
MAINTAINERS

@@ -4474,7 +4474,7 @@ S:	Maintained
 F:	block/partitions/efi.*
 F:	block/partitions/efi.*
 
 
 STK1160 USB VIDEO CAPTURE DRIVER
 STK1160 USB VIDEO CAPTURE DRIVER
-M:	Ezequiel Garcia <elezegarcia@gmail.com>
+M:	Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
 L:	linux-media@vger.kernel.org
 L:	linux-media@vger.kernel.org
 T:	git git://linuxtv.org/media_tree.git
 T:	git git://linuxtv.org/media_tree.git
 S:	Maintained
 S:	Maintained
@@ -6166,16 +6166,6 @@ Q:	http://patchwork.linuxtv.org/project/linux-media/list/
 S:	Maintained
 S:	Maintained
 F:	drivers/media/dvb-frontends/m88rs2000*
 F:	drivers/media/dvb-frontends/m88rs2000*
 
 
-M88TS2022 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/m88ts2022*
-
 MA901 MASTERKIT USB FM RADIO DRIVER
 MA901 MASTERKIT USB FM RADIO DRIVER
 M:	Alexey Klimov <klimov.linux@gmail.com>
 M:	Alexey Klimov <klimov.linux@gmail.com>
 L:	linux-media@vger.kernel.org
 L:	linux-media@vger.kernel.org
@@ -6599,6 +6589,7 @@ M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 L:	linux-media@vger.kernel.org
 L:	linux-media@vger.kernel.org
 T:	git git://linuxtv.org/media_tree.git
 T:	git git://linuxtv.org/media_tree.git
 S:	Maintained
 S:	Maintained
+F:	Documentation/devicetree/bindings/media/i2c/mt9v032.txt
 F:	drivers/media/i2c/mt9v032.c
 F:	drivers/media/i2c/mt9v032.c
 F:	include/media/mt9v032.h
 F:	include/media/mt9v032.h
 
 
@@ -8992,6 +8983,16 @@ T:	git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
 S:	Maintained
 S:	Maintained
 F:	drivers/media/platform/am437x/
 F:	drivers/media/platform/am437x/
 
 
+OV2659 OMNIVISION SENSOR DRIVER
+M:	Lad, Prabhakar <prabhakar.csengg@gmail.com>
+L:	linux-media@vger.kernel.org
+W:	http://linuxtv.org/
+Q:	http://patchwork.linuxtv.org/project/linux-media/list/
+T:	git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
+S:	Maintained
+F:	drivers/media/i2c/ov2659.c
+F:	include/media/ov2659.h
+
 SIS 190 ETHERNET DRIVER
 SIS 190 ETHERNET DRIVER
 M:	Francois Romieu <romieu@fr.zoreil.com>
 M:	Francois Romieu <romieu@fr.zoreil.com>
 L:	netdev@vger.kernel.org
 L:	netdev@vger.kernel.org
@@ -10921,6 +10922,16 @@ L:	linux-serial@vger.kernel.org
 S:	Maintained
 S:	Maintained
 F:	drivers/tty/serial/uartlite.c
 F:	drivers/tty/serial/uartlite.c
 
 
+XILINX VIDEO IP CORES
+M:	Hyun Kwon <hyun.kwon@xilinx.com>
+M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+S:	Supported
+F:	Documentation/devicetree/bindings/media/xilinx/
+F:	drivers/media/platform/xilinx/
+F:	include/uapi/linux/xilinx-v4l2-controls.h
+
 XILLYBUS DRIVER
 XILLYBUS DRIVER
 M:	Eli Billauer <eli.billauer@gmail.com>
 M:	Eli Billauer <eli.billauer@gmail.com>
 L:	linux-kernel@vger.kernel.org
 L:	linux-kernel@vger.kernel.org

+ 21 - 36
arch/arm/mach-omap2/board-cm-t35.c

@@ -492,51 +492,36 @@ static struct twl4030_platform_data cm_t35_twldata = {
 #include <media/omap3isp.h>
 #include <media/omap3isp.h>
 #include "devices.h"
 #include "devices.h"
 
 
-static struct i2c_board_info cm_t35_isp_i2c_boardinfo[] = {
+static struct isp_platform_subdev cm_t35_isp_subdevs[] = {
 	{
 	{
-		I2C_BOARD_INFO("mt9t001", 0x5d),
-	},
-	{
-		I2C_BOARD_INFO("tvp5150", 0x5c),
-	},
-};
-
-static struct isp_subdev_i2c_board_info cm_t35_isp_primary_subdevs[] = {
-	{
-		.board_info = &cm_t35_isp_i2c_boardinfo[0],
-		.i2c_adapter_id = 3,
-	},
-	{ NULL, 0, },
-};
-
-static struct isp_subdev_i2c_board_info cm_t35_isp_secondary_subdevs[] = {
-	{
-		.board_info = &cm_t35_isp_i2c_boardinfo[1],
+		.board_info = &(struct i2c_board_info){
+			I2C_BOARD_INFO("mt9t001", 0x5d)
+		},
 		.i2c_adapter_id = 3,
 		.i2c_adapter_id = 3,
-	},
-	{ NULL, 0, },
-};
-
-static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = {
-	{
-		.subdevs = cm_t35_isp_primary_subdevs,
-		.interface = ISP_INTERFACE_PARALLEL,
-		.bus = {
-			.parallel = {
-				.clk_pol = 1,
+		.bus = &(struct isp_bus_cfg){
+			.interface = ISP_INTERFACE_PARALLEL,
+			.bus = {
+				.parallel = {
+					.clk_pol = 1,
+				},
 			},
 			},
 		},
 		},
 	},
 	},
 	{
 	{
-		.subdevs = cm_t35_isp_secondary_subdevs,
-		.interface = ISP_INTERFACE_PARALLEL,
-		.bus = {
-			.parallel = {
-				.clk_pol = 0,
+		.board_info = &(struct i2c_board_info){
+			I2C_BOARD_INFO("tvp5150", 0x5c),
+		},
+		.i2c_adapter_id = 3,
+		.bus = &(struct isp_bus_cfg){
+			.interface = ISP_INTERFACE_PARALLEL,
+			.bus = {
+				.parallel = {
+					.clk_pol = 0,
+				},
 			},
 			},
 		},
 		},
 	},
 	},
-	{ NULL, 0, },
+	{ 0 },
 };
 };
 
 
 static struct isp_platform_data cm_t35_isp_pdata = {
 static struct isp_platform_data cm_t35_isp_pdata = {

+ 3 - 73
arch/arm/mach-omap2/devices.c

@@ -74,82 +74,12 @@ omap_postcore_initcall(omap3_l3_init);
 static struct resource omap3isp_resources[] = {
 static struct resource omap3isp_resources[] = {
 	{
 	{
 		.start		= OMAP3430_ISP_BASE,
 		.start		= OMAP3430_ISP_BASE,
-		.end		= OMAP3430_ISP_END,
+		.end		= OMAP3430_ISP_BASE + 0x12fc,
 		.flags		= IORESOURCE_MEM,
 		.flags		= IORESOURCE_MEM,
 	},
 	},
 	{
 	{
-		.start		= OMAP3430_ISP_CCP2_BASE,
-		.end		= OMAP3430_ISP_CCP2_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_CCDC_BASE,
-		.end		= OMAP3430_ISP_CCDC_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_HIST_BASE,
-		.end		= OMAP3430_ISP_HIST_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_H3A_BASE,
-		.end		= OMAP3430_ISP_H3A_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_PREV_BASE,
-		.end		= OMAP3430_ISP_PREV_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_RESZ_BASE,
-		.end		= OMAP3430_ISP_RESZ_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_SBL_BASE,
-		.end		= OMAP3430_ISP_SBL_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_CSI2A_REGS1_BASE,
-		.end		= OMAP3430_ISP_CSI2A_REGS1_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_CSIPHY2_BASE,
-		.end		= OMAP3430_ISP_CSIPHY2_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3630_ISP_CSI2A_REGS2_BASE,
-		.end		= OMAP3630_ISP_CSI2A_REGS2_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3630_ISP_CSI2C_REGS1_BASE,
-		.end		= OMAP3630_ISP_CSI2C_REGS1_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3630_ISP_CSIPHY1_BASE,
-		.end		= OMAP3630_ISP_CSIPHY1_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3630_ISP_CSI2C_REGS2_BASE,
-		.end		= OMAP3630_ISP_CSI2C_REGS2_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE,
-		.end		= OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE + 3,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL,
-		.end		= OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL + 3,
+		.start		= OMAP3430_ISP_BASE2,
+		.end		= OMAP3430_ISP_BASE2 + 0x0600,
 		.flags		= IORESOURCE_MEM,
 		.flags		= IORESOURCE_MEM,
 	},
 	},
 	{
 	{

+ 3 - 33
arch/arm/mach-omap2/omap34xx.h

@@ -46,39 +46,9 @@
 
 
 #define OMAP34XX_IC_BASE	0x48200000
 #define OMAP34XX_IC_BASE	0x48200000
 
 
-#define OMAP3430_ISP_BASE		(L4_34XX_BASE + 0xBC000)
-#define OMAP3430_ISP_CBUFF_BASE		(OMAP3430_ISP_BASE + 0x0100)
-#define OMAP3430_ISP_CCP2_BASE		(OMAP3430_ISP_BASE + 0x0400)
-#define OMAP3430_ISP_CCDC_BASE		(OMAP3430_ISP_BASE + 0x0600)
-#define OMAP3430_ISP_HIST_BASE		(OMAP3430_ISP_BASE + 0x0A00)
-#define OMAP3430_ISP_H3A_BASE		(OMAP3430_ISP_BASE + 0x0C00)
-#define OMAP3430_ISP_PREV_BASE		(OMAP3430_ISP_BASE + 0x0E00)
-#define OMAP3430_ISP_RESZ_BASE		(OMAP3430_ISP_BASE + 0x1000)
-#define OMAP3430_ISP_SBL_BASE		(OMAP3430_ISP_BASE + 0x1200)
-#define OMAP3430_ISP_MMU_BASE		(OMAP3430_ISP_BASE + 0x1400)
-#define OMAP3430_ISP_CSI2A_REGS1_BASE	(OMAP3430_ISP_BASE + 0x1800)
-#define OMAP3430_ISP_CSIPHY2_BASE	(OMAP3430_ISP_BASE + 0x1970)
-#define OMAP3630_ISP_CSI2A_REGS2_BASE	(OMAP3430_ISP_BASE + 0x19C0)
-#define OMAP3630_ISP_CSI2C_REGS1_BASE	(OMAP3430_ISP_BASE + 0x1C00)
-#define OMAP3630_ISP_CSIPHY1_BASE	(OMAP3430_ISP_BASE + 0x1D70)
-#define OMAP3630_ISP_CSI2C_REGS2_BASE	(OMAP3430_ISP_BASE + 0x1DC0)
-
-#define OMAP3430_ISP_END		(OMAP3430_ISP_BASE         + 0x06F)
-#define OMAP3430_ISP_CBUFF_END		(OMAP3430_ISP_CBUFF_BASE   + 0x077)
-#define OMAP3430_ISP_CCP2_END		(OMAP3430_ISP_CCP2_BASE    + 0x1EF)
-#define OMAP3430_ISP_CCDC_END		(OMAP3430_ISP_CCDC_BASE    + 0x0A7)
-#define OMAP3430_ISP_HIST_END		(OMAP3430_ISP_HIST_BASE    + 0x047)
-#define OMAP3430_ISP_H3A_END		(OMAP3430_ISP_H3A_BASE     + 0x05F)
-#define OMAP3430_ISP_PREV_END		(OMAP3430_ISP_PREV_BASE    + 0x09F)
-#define OMAP3430_ISP_RESZ_END		(OMAP3430_ISP_RESZ_BASE    + 0x0AB)
-#define OMAP3430_ISP_SBL_END		(OMAP3430_ISP_SBL_BASE     + 0x0FB)
-#define OMAP3430_ISP_MMU_END		(OMAP3430_ISP_MMU_BASE     + 0x06F)
-#define OMAP3430_ISP_CSI2A_REGS1_END	(OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F)
-#define OMAP3430_ISP_CSIPHY2_END	(OMAP3430_ISP_CSIPHY2_BASE + 0x00B)
-#define OMAP3630_ISP_CSI2A_REGS2_END	(OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F)
-#define OMAP3630_ISP_CSI2C_REGS1_END	(OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F)
-#define OMAP3630_ISP_CSIPHY1_END	(OMAP3630_ISP_CSIPHY1_BASE + 0x00B)
-#define OMAP3630_ISP_CSI2C_REGS2_END	(OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F)
+#define OMAP3430_ISP_BASE	(L4_34XX_BASE + 0xBC000)
+#define OMAP3430_ISP_MMU_BASE	(OMAP3430_ISP_BASE + 0x1400)
+#define OMAP3430_ISP_BASE2	(OMAP3430_ISP_BASE + 0x1800)
 
 
 #define OMAP34XX_HSUSB_OTG_BASE	(L4_34XX_BASE + 0xAB000)
 #define OMAP34XX_HSUSB_OTG_BASE	(L4_34XX_BASE + 0xAB000)
 #define OMAP34XX_USBTLL_BASE	(L4_34XX_BASE + 0x62000)
 #define OMAP34XX_USBTLL_BASE	(L4_34XX_BASE + 0x62000)

+ 15 - 3
drivers/input/ff-memless.c

@@ -237,6 +237,18 @@ static u16 ml_calculate_direction(u16 direction, u16 force,
 		(force + new_force)) << 1;
 		(force + new_force)) << 1;
 }
 }
 
 
+#define FRAC_N 8
+static inline s16 fixp_new16(s16 a)
+{
+	return ((s32)a) >> (16 - FRAC_N);
+}
+
+static inline s16 fixp_mult(s16 a, s16 b)
+{
+	a = ((s32)a * 0x100) / 0x7fff;
+	return ((s32)(a * b)) >> FRAC_N;
+}
+
 /*
 /*
  * Combine two effects and apply gain.
  * Combine two effects and apply gain.
  */
  */
@@ -247,7 +259,7 @@ static void ml_combine_effects(struct ff_effect *effect,
 	struct ff_effect *new = state->effect;
 	struct ff_effect *new = state->effect;
 	unsigned int strong, weak, i;
 	unsigned int strong, weak, i;
 	int x, y;
 	int x, y;
-	fixp_t level;
+	s16 level;
 
 
 	switch (new->type) {
 	switch (new->type) {
 	case FF_CONSTANT:
 	case FF_CONSTANT:
@@ -255,8 +267,8 @@ static void ml_combine_effects(struct ff_effect *effect,
 		level = fixp_new16(apply_envelope(state,
 		level = fixp_new16(apply_envelope(state,
 					new->u.constant.level,
 					new->u.constant.level,
 					&new->u.constant.envelope));
 					&new->u.constant.envelope));
-		x = fixp_mult(fixp_sin(i), level) * gain / 0xffff;
-		y = fixp_mult(-fixp_cos(i), level) * gain / 0xffff;
+		x = fixp_mult(fixp_sin16(i), level) * gain / 0xffff;
+		y = fixp_mult(-fixp_cos16(i), level) * gain / 0xffff;
 		/*
 		/*
 		 * here we abuse ff_ramp to hold x and y of constant force
 		 * here we abuse ff_ramp to hold x and y of constant force
 		 * If in future any driver wants something else than x and y
 		 * If in future any driver wants something else than x and y

+ 2 - 0
drivers/input/touchscreen/Kconfig

@@ -980,7 +980,9 @@ config TOUCHSCREEN_SUN4I
 config TOUCHSCREEN_SUR40
 config TOUCHSCREEN_SUR40
 	tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
 	tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
 	depends on USB
 	depends on USB
+	depends on MEDIA_USB_SUPPORT
 	select INPUT_POLLDEV
 	select INPUT_POLLDEV
+	select VIDEOBUF2_DMA_SG
 	help
 	help
 	  Say Y here if you want support for the Samsung SUR40 touchscreen
 	  Say Y here if you want support for the Samsung SUR40 touchscreen
 	  (also known as Microsoft Surface 2.0 or Microsoft PixelSense).
 	  (also known as Microsoft Surface 2.0 or Microsoft PixelSense).

+ 422 - 12
drivers/input/touchscreen/sur40.c

@@ -1,7 +1,7 @@
 /*
 /*
  * Surface2.0/SUR40/PixelSense input driver
  * Surface2.0/SUR40/PixelSense input driver
  *
  *
- * Copyright (c) 2013 by Florian 'floe' Echtler <floe@butterbrot.org>
+ * Copyright (c) 2014 by Florian 'floe' Echtler <floe@butterbrot.org>
  *
  *
  * Derived from the USB Skeleton driver 1.1,
  * Derived from the USB Skeleton driver 1.1,
  * Copyright (c) 2003 Greg Kroah-Hartman (greg@kroah.com)
  * Copyright (c) 2003 Greg Kroah-Hartman (greg@kroah.com)
@@ -12,6 +12,9 @@
  * and from the generic hid-multitouch driver,
  * and from the generic hid-multitouch driver,
  * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
  * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
  *
  *
+ * and from the v4l2-pci-skeleton driver,
+ * Copyright (c) Copyright 2014 Cisco Systems, Inc.
+ *
  * 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
  * published by the Free Software Foundation; either version 2 of
  * published by the Free Software Foundation; either version 2 of
@@ -31,6 +34,11 @@
 #include <linux/input-polldev.h>
 #include <linux/input-polldev.h>
 #include <linux/input/mt.h>
 #include <linux/input/mt.h>
 #include <linux/usb/input.h>
 #include <linux/usb/input.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-dma-sg.h>
 
 
 /* read 512 bytes from endpoint 0x86 -> get header + blobs */
 /* read 512 bytes from endpoint 0x86 -> get header + blobs */
 struct sur40_header {
 struct sur40_header {
@@ -82,9 +90,19 @@ struct sur40_data {
 	struct sur40_blob   blobs[];
 	struct sur40_blob   blobs[];
 } __packed;
 } __packed;
 
 
+/* read 512 bytes from endpoint 0x82 -> get header below
+ * continue reading 16k blocks until header.size bytes read */
+struct sur40_image_header {
+	__le32 magic;     /* "SUBF" */
+	__le32 packet_id;
+	__le32 size;      /* always 0x0007e900 = 960x540 */
+	__le32 timestamp; /* milliseconds (increases by 16 or 17 each frame) */
+	__le32 unknown;   /* "epoch?" always 02/03 00 00 00 */
+} __packed;
 
 
 /* version information */
 /* version information */
 #define DRIVER_SHORT   "sur40"
 #define DRIVER_SHORT   "sur40"
+#define DRIVER_LONG    "Samsung SUR40"
 #define DRIVER_AUTHOR  "Florian 'floe' Echtler <floe@butterbrot.org>"
 #define DRIVER_AUTHOR  "Florian 'floe' Echtler <floe@butterbrot.org>"
 #define DRIVER_DESC    "Surface2.0/SUR40/PixelSense input driver"
 #define DRIVER_DESC    "Surface2.0/SUR40/PixelSense input driver"
 
 
@@ -99,6 +117,13 @@ struct sur40_data {
 /* touch data endpoint */
 /* touch data endpoint */
 #define TOUCH_ENDPOINT 0x86
 #define TOUCH_ENDPOINT 0x86
 
 
+/* video data endpoint */
+#define VIDEO_ENDPOINT 0x82
+
+/* video header fields */
+#define VIDEO_HEADER_MAGIC 0x46425553
+#define VIDEO_PACKET_SIZE  16384
+
 /* polling interval (ms) */
 /* polling interval (ms) */
 #define POLL_INTERVAL 10
 #define POLL_INTERVAL 10
 
 
@@ -113,21 +138,23 @@ struct sur40_data {
 #define SUR40_GET_STATE   0xc5 /*  4 bytes state (?) */
 #define SUR40_GET_STATE   0xc5 /*  4 bytes state (?) */
 #define SUR40_GET_SENSORS 0xb1 /*  8 bytes sensors   */
 #define SUR40_GET_SENSORS 0xb1 /*  8 bytes sensors   */
 
 
-/*
- * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
- * here by mistake which is very likely to have corrupted the firmware EEPROM
- * on two separate SUR40 devices. Thanks to Alan Stern who spotted this bug.
- * Should you ever run into a similar problem, the background story to this
- * incident and instructions on how to fix the corrupted EEPROM are available
- * at https://floe.butterbrot.org/matrix/hacking/surface/brick.html
-*/
-
+/* master device state */
 struct sur40_state {
 struct sur40_state {
 
 
 	struct usb_device *usbdev;
 	struct usb_device *usbdev;
 	struct device *dev;
 	struct device *dev;
 	struct input_polled_dev *input;
 	struct input_polled_dev *input;
 
 
+	struct v4l2_device v4l2;
+	struct video_device vdev;
+	struct mutex lock;
+
+	struct vb2_queue queue;
+	struct vb2_alloc_ctx *alloc_ctx;
+	struct list_head buf_list;
+	spinlock_t qlock;
+	int sequence;
+
 	struct sur40_data *bulk_in_buffer;
 	struct sur40_data *bulk_in_buffer;
 	size_t bulk_in_size;
 	size_t bulk_in_size;
 	u8 bulk_in_epaddr;
 	u8 bulk_in_epaddr;
@@ -135,6 +162,27 @@ struct sur40_state {
 	char phys[64];
 	char phys[64];
 };
 };
 
 
+struct sur40_buffer {
+	struct vb2_buffer vb;
+	struct list_head list;
+};
+
+/* forward declarations */
+static const struct video_device sur40_video_device;
+static const struct v4l2_pix_format sur40_video_format;
+static const struct vb2_queue sur40_queue;
+static void sur40_process_video(struct sur40_state *sur40);
+
+/*
+ * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT
+ * here by mistake which is very likely to have corrupted the firmware EEPROM
+ * on two separate SUR40 devices. Thanks to Alan Stern who spotted this bug.
+ * Should you ever run into a similar problem, the background story to this
+ * incident and instructions on how to fix the corrupted EEPROM are available
+ * at https://floe.butterbrot.org/matrix/hacking/surface/brick.html
+*/
+
+/* command wrapper */
 static int sur40_command(struct sur40_state *dev,
 static int sur40_command(struct sur40_state *dev,
 			 u8 command, u16 index, void *buffer, u16 size)
 			 u8 command, u16 index, void *buffer, u16 size)
 {
 {
@@ -247,7 +295,6 @@ static void sur40_report_blob(struct sur40_blob *blob, struct input_dev *input)
 /* core function: poll for new input data */
 /* core function: poll for new input data */
 static void sur40_poll(struct input_polled_dev *polldev)
 static void sur40_poll(struct input_polled_dev *polldev)
 {
 {
-
 	struct sur40_state *sur40 = polldev->private;
 	struct sur40_state *sur40 = polldev->private;
 	struct input_dev *input = polldev->input;
 	struct input_dev *input = polldev->input;
 	int result, bulk_read, need_blobs, packet_blobs, i;
 	int result, bulk_read, need_blobs, packet_blobs, i;
@@ -314,6 +361,86 @@ static void sur40_poll(struct input_polled_dev *polldev)
 
 
 	input_mt_sync_frame(input);
 	input_mt_sync_frame(input);
 	input_sync(input);
 	input_sync(input);
+
+	sur40_process_video(sur40);
+}
+
+/* deal with video data */
+static void sur40_process_video(struct sur40_state *sur40)
+{
+
+	struct sur40_image_header *img = (void *)(sur40->bulk_in_buffer);
+	struct sur40_buffer *new_buf;
+	struct usb_sg_request sgr;
+	struct sg_table *sgt;
+	int result, bulk_read;
+
+	if (!vb2_start_streaming_called(&sur40->queue))
+		return;
+
+	/* get a new buffer from the list */
+	spin_lock(&sur40->qlock);
+	if (list_empty(&sur40->buf_list)) {
+		dev_dbg(sur40->dev, "buffer queue empty\n");
+		spin_unlock(&sur40->qlock);
+		return;
+	}
+	new_buf = list_entry(sur40->buf_list.next, struct sur40_buffer, list);
+	list_del(&new_buf->list);
+	spin_unlock(&sur40->qlock);
+
+	/* retrieve data via bulk read */
+	result = usb_bulk_msg(sur40->usbdev,
+			usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT),
+			sur40->bulk_in_buffer, sur40->bulk_in_size,
+			&bulk_read, 1000);
+
+	if (result < 0) {
+		dev_err(sur40->dev, "error in usb_bulk_read\n");
+		goto err_poll;
+	}
+
+	if (bulk_read != sizeof(struct sur40_image_header)) {
+		dev_err(sur40->dev, "received %d bytes (%zd expected)\n",
+			bulk_read, sizeof(struct sur40_image_header));
+		goto err_poll;
+	}
+
+	if (le32_to_cpu(img->magic) != VIDEO_HEADER_MAGIC) {
+		dev_err(sur40->dev, "image magic mismatch\n");
+		goto err_poll;
+	}
+
+	if (le32_to_cpu(img->size) != sur40_video_format.sizeimage) {
+		dev_err(sur40->dev, "image size mismatch\n");
+		goto err_poll;
+	}
+
+	sgt = vb2_dma_sg_plane_desc(&new_buf->vb, 0);
+
+	result = usb_sg_init(&sgr, sur40->usbdev,
+		usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0,
+		sgt->sgl, sgt->nents, sur40_video_format.sizeimage, 0);
+	if (result < 0) {
+		dev_err(sur40->dev, "error %d in usb_sg_init\n", result);
+		goto err_poll;
+	}
+
+	usb_sg_wait(&sgr);
+	if (sgr.status < 0) {
+		dev_err(sur40->dev, "error %d in usb_sg_wait\n", sgr.status);
+		goto err_poll;
+	}
+
+	/* mark as finished */
+	v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp);
+	new_buf->vb.v4l2_buf.sequence = sur40->sequence++;
+	new_buf->vb.v4l2_buf.field = V4L2_FIELD_NONE;
+	vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE);
+	return;
+
+err_poll:
+	vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_ERROR);
 }
 }
 
 
 /* Initialize input device parameters. */
 /* Initialize input device parameters. */
@@ -377,6 +504,11 @@ static int sur40_probe(struct usb_interface *interface,
 		goto err_free_dev;
 		goto err_free_dev;
 	}
 	}
 
 
+	/* initialize locks/lists */
+	INIT_LIST_HEAD(&sur40->buf_list);
+	spin_lock_init(&sur40->qlock);
+	mutex_init(&sur40->lock);
+
 	/* Set up polled input device control structure */
 	/* Set up polled input device control structure */
 	poll_dev->private = sur40;
 	poll_dev->private = sur40;
 	poll_dev->poll_interval = POLL_INTERVAL;
 	poll_dev->poll_interval = POLL_INTERVAL;
@@ -387,7 +519,7 @@ static int sur40_probe(struct usb_interface *interface,
 	/* Set up regular input device structure */
 	/* Set up regular input device structure */
 	sur40_input_setup(poll_dev->input);
 	sur40_input_setup(poll_dev->input);
 
 
-	poll_dev->input->name = "Samsung SUR40";
+	poll_dev->input->name = DRIVER_LONG;
 	usb_to_input_id(usbdev, &poll_dev->input->id);
 	usb_to_input_id(usbdev, &poll_dev->input->id);
 	usb_make_path(usbdev, sur40->phys, sizeof(sur40->phys));
 	usb_make_path(usbdev, sur40->phys, sizeof(sur40->phys));
 	strlcat(sur40->phys, "/input0", sizeof(sur40->phys));
 	strlcat(sur40->phys, "/input0", sizeof(sur40->phys));
@@ -408,6 +540,7 @@ static int sur40_probe(struct usb_interface *interface,
 		goto err_free_polldev;
 		goto err_free_polldev;
 	}
 	}
 
 
+	/* register the polled input device */
 	error = input_register_polled_device(poll_dev);
 	error = input_register_polled_device(poll_dev);
 	if (error) {
 	if (error) {
 		dev_err(&interface->dev,
 		dev_err(&interface->dev,
@@ -415,12 +548,54 @@ static int sur40_probe(struct usb_interface *interface,
 		goto err_free_buffer;
 		goto err_free_buffer;
 	}
 	}
 
 
+	/* register the video master device */
+	snprintf(sur40->v4l2.name, sizeof(sur40->v4l2.name), "%s", DRIVER_LONG);
+	error = v4l2_device_register(sur40->dev, &sur40->v4l2);
+	if (error) {
+		dev_err(&interface->dev,
+			"Unable to register video master device.");
+		goto err_unreg_v4l2;
+	}
+
+	/* initialize the lock and subdevice */
+	sur40->queue = sur40_queue;
+	sur40->queue.drv_priv = sur40;
+	sur40->queue.lock = &sur40->lock;
+
+	/* initialize the queue */
+	error = vb2_queue_init(&sur40->queue);
+	if (error)
+		goto err_unreg_v4l2;
+
+	sur40->alloc_ctx = vb2_dma_sg_init_ctx(sur40->dev);
+	if (IS_ERR(sur40->alloc_ctx)) {
+		dev_err(sur40->dev, "Can't allocate buffer context");
+		goto err_unreg_v4l2;
+	}
+
+	sur40->vdev = sur40_video_device;
+	sur40->vdev.v4l2_dev = &sur40->v4l2;
+	sur40->vdev.lock = &sur40->lock;
+	sur40->vdev.queue = &sur40->queue;
+	video_set_drvdata(&sur40->vdev, sur40);
+
+	error = video_register_device(&sur40->vdev, VFL_TYPE_GRABBER, -1);
+	if (error) {
+		dev_err(&interface->dev,
+			"Unable to register video subdevice.");
+		goto err_unreg_video;
+	}
+
 	/* we can register the device now, as it is ready */
 	/* we can register the device now, as it is ready */
 	usb_set_intfdata(interface, sur40);
 	usb_set_intfdata(interface, sur40);
 	dev_dbg(&interface->dev, "%s is now attached\n", DRIVER_DESC);
 	dev_dbg(&interface->dev, "%s is now attached\n", DRIVER_DESC);
 
 
 	return 0;
 	return 0;
 
 
+err_unreg_video:
+	video_unregister_device(&sur40->vdev);
+err_unreg_v4l2:
+	v4l2_device_unregister(&sur40->v4l2);
 err_free_buffer:
 err_free_buffer:
 	kfree(sur40->bulk_in_buffer);
 	kfree(sur40->bulk_in_buffer);
 err_free_polldev:
 err_free_polldev:
@@ -436,6 +611,10 @@ static void sur40_disconnect(struct usb_interface *interface)
 {
 {
 	struct sur40_state *sur40 = usb_get_intfdata(interface);
 	struct sur40_state *sur40 = usb_get_intfdata(interface);
 
 
+	video_unregister_device(&sur40->vdev);
+	v4l2_device_unregister(&sur40->v4l2);
+	vb2_dma_sg_cleanup_ctx(sur40->alloc_ctx);
+
 	input_unregister_polled_device(sur40->input);
 	input_unregister_polled_device(sur40->input);
 	input_free_polled_device(sur40->input);
 	input_free_polled_device(sur40->input);
 	kfree(sur40->bulk_in_buffer);
 	kfree(sur40->bulk_in_buffer);
@@ -445,12 +624,243 @@ static void sur40_disconnect(struct usb_interface *interface)
 	dev_dbg(&interface->dev, "%s is now disconnected\n", DRIVER_DESC);
 	dev_dbg(&interface->dev, "%s is now disconnected\n", DRIVER_DESC);
 }
 }
 
 
+/*
+ * Setup the constraints of the queue: besides setting the number of planes
+ * per buffer and the size and allocation context of each plane, it also
+ * checks if sufficient buffers have been allocated. Usually 3 is a good
+ * minimum number: many DMA engines need a minimum of 2 buffers in the
+ * queue and you need to have another available for userspace processing.
+ */
+static int sur40_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+		       unsigned int *nbuffers, unsigned int *nplanes,
+		       unsigned int sizes[], void *alloc_ctxs[])
+{
+	struct sur40_state *sur40 = vb2_get_drv_priv(q);
+
+	if (q->num_buffers + *nbuffers < 3)
+		*nbuffers = 3 - q->num_buffers;
+
+	if (fmt && fmt->fmt.pix.sizeimage < sur40_video_format.sizeimage)
+		return -EINVAL;
+
+	*nplanes = 1;
+	sizes[0] = fmt ? fmt->fmt.pix.sizeimage : sur40_video_format.sizeimage;
+	alloc_ctxs[0] = sur40->alloc_ctx;
+
+	return 0;
+}
+
+/*
+ * Prepare the buffer for queueing to the DMA engine: check and set the
+ * payload size.
+ */
+static int sur40_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned long size = sur40_video_format.sizeimage;
+
+	if (vb2_plane_size(vb, 0) < size) {
+		dev_err(&sur40->usbdev->dev, "buffer too small (%lu < %lu)\n",
+			 vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(vb, 0, size);
+	return 0;
+}
+
+/*
+ * Queue this buffer to the DMA engine.
+ */
+static void sur40_buffer_queue(struct vb2_buffer *vb)
+{
+	struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
+	struct sur40_buffer *buf = (struct sur40_buffer *)vb;
+
+	spin_lock(&sur40->qlock);
+	list_add_tail(&buf->list, &sur40->buf_list);
+	spin_unlock(&sur40->qlock);
+}
+
+static void return_all_buffers(struct sur40_state *sur40,
+			       enum vb2_buffer_state state)
+{
+	struct sur40_buffer *buf, *node;
+
+	spin_lock(&sur40->qlock);
+	list_for_each_entry_safe(buf, node, &sur40->buf_list, list) {
+		vb2_buffer_done(&buf->vb, state);
+		list_del(&buf->list);
+	}
+	spin_unlock(&sur40->qlock);
+}
+
+/*
+ * Start streaming. First check if the minimum number of buffers have been
+ * queued. If not, then return -ENOBUFS and the vb2 framework will call
+ * this function again the next time a buffer has been queued until enough
+ * buffers are available to actually start the DMA engine.
+ */
+static int sur40_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct sur40_state *sur40 = vb2_get_drv_priv(vq);
+
+	sur40->sequence = 0;
+	return 0;
+}
+
+/*
+ * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued
+ * and passed on to the vb2 framework marked as STATE_ERROR.
+ */
+static void sur40_stop_streaming(struct vb2_queue *vq)
+{
+	struct sur40_state *sur40 = vb2_get_drv_priv(vq);
+
+	/* Release all active buffers */
+	return_all_buffers(sur40, VB2_BUF_STATE_ERROR);
+}
+
+/* V4L ioctl */
+static int sur40_vidioc_querycap(struct file *file, void *priv,
+				 struct v4l2_capability *cap)
+{
+	struct sur40_state *sur40 = video_drvdata(file);
+
+	strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver));
+	strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card));
+	usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info));
+	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
+		V4L2_CAP_READWRITE |
+		V4L2_CAP_STREAMING;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+	return 0;
+}
+
+static int sur40_vidioc_enum_input(struct file *file, void *priv,
+				   struct v4l2_input *i)
+{
+	if (i->index != 0)
+		return -EINVAL;
+	i->type = V4L2_INPUT_TYPE_CAMERA;
+	i->std = V4L2_STD_UNKNOWN;
+	strlcpy(i->name, "In-Cell Sensor", sizeof(i->name));
+	i->capabilities = 0;
+	return 0;
+}
+
+static int sur40_vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+	return (i == 0) ? 0 : -EINVAL;
+}
+
+static int sur40_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+	*i = 0;
+	return 0;
+}
+
+static int sur40_vidioc_fmt(struct file *file, void *priv,
+			    struct v4l2_format *f)
+{
+	f->fmt.pix = sur40_video_format;
+	return 0;
+}
+
+static int sur40_vidioc_enum_fmt(struct file *file, void *priv,
+				 struct v4l2_fmtdesc *f)
+{
+	if (f->index != 0)
+		return -EINVAL;
+	strlcpy(f->description, "8-bit greyscale", sizeof(f->description));
+	f->pixelformat = V4L2_PIX_FMT_GREY;
+	f->flags = 0;
+	return 0;
+}
+
 static const struct usb_device_id sur40_table[] = {
 static const struct usb_device_id sur40_table[] = {
 	{ USB_DEVICE(ID_MICROSOFT, ID_SUR40) },  /* Samsung SUR40 */
 	{ USB_DEVICE(ID_MICROSOFT, ID_SUR40) },  /* Samsung SUR40 */
 	{ }                                      /* terminating null entry */
 	{ }                                      /* terminating null entry */
 };
 };
 MODULE_DEVICE_TABLE(usb, sur40_table);
 MODULE_DEVICE_TABLE(usb, sur40_table);
 
 
+/* V4L2 structures */
+static const struct vb2_ops sur40_queue_ops = {
+	.queue_setup		= sur40_queue_setup,
+	.buf_prepare		= sur40_buffer_prepare,
+	.buf_queue		= sur40_buffer_queue,
+	.start_streaming	= sur40_start_streaming,
+	.stop_streaming		= sur40_stop_streaming,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+static const struct vb2_queue sur40_queue = {
+	.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+	/*
+	 * VB2_USERPTR in currently not enabled: passing a user pointer to
+	 * dma-sg will result in segment sizes that are not a multiple of
+	 * 512 bytes, which is required by the host controller.
+	*/
+	.io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF,
+	.buf_struct_size = sizeof(struct sur40_buffer),
+	.ops = &sur40_queue_ops,
+	.mem_ops = &vb2_dma_sg_memops,
+	.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
+	.min_buffers_needed = 3,
+};
+
+static const struct v4l2_file_operations sur40_video_fops = {
+	.owner = THIS_MODULE,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.unlocked_ioctl = video_ioctl2,
+	.read = vb2_fop_read,
+	.mmap = vb2_fop_mmap,
+	.poll = vb2_fop_poll,
+};
+
+static const struct v4l2_ioctl_ops sur40_video_ioctl_ops = {
+
+	.vidioc_querycap	= sur40_vidioc_querycap,
+
+	.vidioc_enum_fmt_vid_cap = sur40_vidioc_enum_fmt,
+	.vidioc_try_fmt_vid_cap	= sur40_vidioc_fmt,
+	.vidioc_s_fmt_vid_cap	= sur40_vidioc_fmt,
+	.vidioc_g_fmt_vid_cap	= sur40_vidioc_fmt,
+
+	.vidioc_enum_input	= sur40_vidioc_enum_input,
+	.vidioc_g_input		= sur40_vidioc_g_input,
+	.vidioc_s_input		= sur40_vidioc_s_input,
+
+	.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,
+};
+
+static const struct video_device sur40_video_device = {
+	.name = DRIVER_LONG,
+	.fops = &sur40_video_fops,
+	.ioctl_ops = &sur40_video_ioctl_ops,
+	.release = video_device_release_empty,
+};
+
+static const struct v4l2_pix_format sur40_video_format = {
+	.pixelformat = V4L2_PIX_FMT_GREY,
+	.width  = SENSOR_RES_X / 2,
+	.height = SENSOR_RES_Y / 2,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_SRGB,
+	.bytesperline = SENSOR_RES_X / 2,
+	.sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
+};
+
 /* USB-specific object needed to register this driver with the USB subsystem. */
 /* USB-specific object needed to register this driver with the USB subsystem. */
 static struct usb_driver sur40_driver = {
 static struct usb_driver sur40_driver = {
 	.name = DRIVER_SHORT,
 	.name = DRIVER_SHORT,

+ 9 - 1
drivers/media/Kconfig

@@ -87,13 +87,21 @@ config MEDIA_RC_SUPPORT
 
 
 config MEDIA_CONTROLLER
 config MEDIA_CONTROLLER
 	bool "Media Controller API"
 	bool "Media Controller API"
-	depends on MEDIA_CAMERA_SUPPORT
+	depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
 	---help---
 	---help---
 	  Enable the media controller API used to query media devices internal
 	  Enable the media controller API used to query media devices internal
 	  topology and configure it dynamically.
 	  topology and configure it dynamically.
 
 
 	  This API is mostly used by camera interfaces in embedded platforms.
 	  This API is mostly used by camera interfaces in embedded platforms.
 
 
+config MEDIA_CONTROLLER_DVB
+	bool "Enable Media controller for DVB"
+	depends on MEDIA_CONTROLLER
+	---help---
+	  Enable the media controller API support for DVB.
+
+	  This is currently experimental.
+
 #
 #
 # Video4Linux support
 # Video4Linux support
 #	Only enables if one of the V4L2 types (ATV, webcam, radio) is selected
 #	Only enables if one of the V4L2 types (ATV, webcam, radio) is selected

+ 4 - 15
drivers/media/common/saa7146/saa7146_fops.c

@@ -587,26 +587,20 @@ int saa7146_vv_release(struct saa7146_dev* dev)
 }
 }
 EXPORT_SYMBOL_GPL(saa7146_vv_release);
 EXPORT_SYMBOL_GPL(saa7146_vv_release);
 
 
-int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
+int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev,
 			    char *name, int type)
 			    char *name, int type)
 {
 {
-	struct video_device *vfd;
 	int err;
 	int err;
 	int i;
 	int i;
 
 
 	DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type);
 	DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type);
 
 
-	// released by vfd->release
-	vfd = video_device_alloc();
-	if (vfd == NULL)
-		return -ENOMEM;
-
 	vfd->fops = &video_fops;
 	vfd->fops = &video_fops;
 	if (type == VFL_TYPE_GRABBER)
 	if (type == VFL_TYPE_GRABBER)
 		vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;
 		vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;
 	else
 	else
 		vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
 		vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
-	vfd->release = video_device_release;
+	vfd->release = video_device_release_empty;
 	vfd->lock = &dev->v4l2_lock;
 	vfd->lock = &dev->v4l2_lock;
 	vfd->v4l2_dev = &dev->v4l2_dev;
 	vfd->v4l2_dev = &dev->v4l2_dev;
 	vfd->tvnorms = 0;
 	vfd->tvnorms = 0;
@@ -618,25 +612,20 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
 	err = video_register_device(vfd, type, -1);
 	err = video_register_device(vfd, type, -1);
 	if (err < 0) {
 	if (err < 0) {
 		ERR("cannot register v4l2 device. skipping.\n");
 		ERR("cannot register v4l2 device. skipping.\n");
-		video_device_release(vfd);
 		return err;
 		return err;
 	}
 	}
 
 
 	pr_info("%s: registered device %s [v4l2]\n",
 	pr_info("%s: registered device %s [v4l2]\n",
 		dev->name, video_device_node_name(vfd));
 		dev->name, video_device_node_name(vfd));
-
-	*vid = vfd;
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(saa7146_register_device);
 EXPORT_SYMBOL_GPL(saa7146_register_device);
 
 
-int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
+int saa7146_unregister_device(struct video_device *vfd, struct saa7146_dev *dev)
 {
 {
 	DEB_EE("dev:%p\n", dev);
 	DEB_EE("dev:%p\n", dev);
 
 
-	video_unregister_device(*vid);
-	*vid = NULL;
-
+	video_unregister_device(vfd);
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(saa7146_unregister_device);
 EXPORT_SYMBOL_GPL(saa7146_unregister_device);

+ 2 - 2
drivers/media/common/saa7146/saa7146_vbi.c

@@ -95,7 +95,7 @@ static int vbi_workaround(struct saa7146_dev *dev)
 
 
 		/* prepare to wait to be woken up by the irq-handler */
 		/* prepare to wait to be woken up by the irq-handler */
 		add_wait_queue(&vv->vbi_wq, &wait);
 		add_wait_queue(&vv->vbi_wq, &wait);
-		current->state = TASK_INTERRUPTIBLE;
+		set_current_state(TASK_INTERRUPTIBLE);
 
 
 		/* start rps1 to enable workaround */
 		/* start rps1 to enable workaround */
 		saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
 		saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
@@ -106,7 +106,7 @@ static int vbi_workaround(struct saa7146_dev *dev)
 		DEB_VBI("brs bug workaround %d/1\n", i);
 		DEB_VBI("brs bug workaround %d/1\n", i);
 
 
 		remove_wait_queue(&vv->vbi_wq, &wait);
 		remove_wait_queue(&vv->vbi_wq, &wait);
-		current->state = TASK_RUNNING;
+		__set_current_state(TASK_RUNNING);
 
 
 		/* disable rps1 irqs */
 		/* disable rps1 irqs */
 		SAA7146_IER_DISABLE(dev,MASK_28);
 		SAA7146_IER_DISABLE(dev,MASK_28);

+ 2 - 6
drivers/media/common/siano/sms-cards.c

@@ -21,10 +21,6 @@
 #include "smsir.h"
 #include "smsir.h"
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-static int sms_dbg;
-module_param_named(cards_dbg, sms_dbg, int, 0644);
-MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
-
 static struct sms_board sms_boards[] = {
 static struct sms_board sms_boards[] = {
 	[SMS_BOARD_UNKNOWN] = {
 	[SMS_BOARD_UNKNOWN] = {
 		.name	= "Unknown board",
 		.name	= "Unknown board",
@@ -232,7 +228,7 @@ int sms_board_event(struct smscore_device_t *coredev,
 		break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
 		break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
 
 
 	default:
 	default:
-		sms_err("Unknown SMS board event");
+		pr_err("Unknown SMS board event\n");
 		break;
 		break;
 	}
 	}
 	return 0;
 	return 0;
@@ -342,7 +338,7 @@ int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
 	int board_id = smscore_get_board_id(coredev);
 	int board_id = smscore_get_board_id(coredev);
 	struct sms_board *board = sms_get_board(board_id);
 	struct sms_board *board = sms_get_board(board_id);
 
 
-	sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
+	pr_debug("%s: LNA %s\n", __func__, onoff ? "enabled" : "disabled");
 
 
 	switch (board_id) {
 	switch (board_id) {
 	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
 	case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:

+ 2 - 1
drivers/media/common/siano/sms-cards.h

@@ -20,8 +20,9 @@
 #ifndef __SMS_CARDS_H__
 #ifndef __SMS_CARDS_H__
 #define __SMS_CARDS_H__
 #define __SMS_CARDS_H__
 
 
-#include <linux/usb.h>
 #include "smscoreapi.h"
 #include "smscoreapi.h"
+
+#include <linux/usb.h>
 #include "smsir.h"
 #include "smsir.h"
 
 
 #define SMS_BOARD_UNKNOWN 0
 #define SMS_BOARD_UNKNOWN 0

+ 81 - 83
drivers/media/common/siano/smscoreapi.c

@@ -21,6 +21,8 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
  */
 
 
+#include "smscoreapi.h"
+
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/module.h>
@@ -34,14 +36,9 @@
 #include <linux/wait.h>
 #include <linux/wait.h>
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
 
 
-#include "smscoreapi.h"
 #include "sms-cards.h"
 #include "sms-cards.h"
 #include "smsir.h"
 #include "smsir.h"
 
 
-static int sms_dbg;
-module_param_named(debug, sms_dbg, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
-
 struct smscore_device_notifyee_t {
 struct smscore_device_notifyee_t {
 	struct list_head entry;
 	struct list_head entry;
 	hotplug_t hotplug;
 	hotplug_t hotplug;
@@ -460,7 +457,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
 		strcpy(entry->devpath, devpath);
 		strcpy(entry->devpath, devpath);
 		list_add(&entry->entry, &g_smscore_registry);
 		list_add(&entry->entry, &g_smscore_registry);
 	} else
 	} else
-		sms_err("failed to create smscore_registry.");
+		pr_err("failed to create smscore_registry.\n");
 	kmutex_unlock(&g_smscore_registrylock);
 	kmutex_unlock(&g_smscore_registrylock);
 	return entry;
 	return entry;
 }
 }
@@ -473,7 +470,7 @@ int smscore_registry_getmode(char *devpath)
 	if (entry)
 	if (entry)
 		return entry->mode;
 		return entry->mode;
 	else
 	else
-		sms_err("No registry found.");
+		pr_err("No registry found.\n");
 
 
 	return default_mode;
 	return default_mode;
 }
 }
@@ -487,7 +484,7 @@ static enum sms_device_type_st smscore_registry_gettype(char *devpath)
 	if (entry)
 	if (entry)
 		return entry->type;
 		return entry->type;
 	else
 	else
-		sms_err("No registry found.");
+		pr_err("No registry found.\n");
 
 
 	return -EINVAL;
 	return -EINVAL;
 }
 }
@@ -500,7 +497,7 @@ static void smscore_registry_setmode(char *devpath, int mode)
 	if (entry)
 	if (entry)
 		entry->mode = mode;
 		entry->mode = mode;
 	else
 	else
-		sms_err("No registry found.");
+		pr_err("No registry found.\n");
 }
 }
 
 
 static void smscore_registry_settype(char *devpath,
 static void smscore_registry_settype(char *devpath,
@@ -512,7 +509,7 @@ static void smscore_registry_settype(char *devpath,
 	if (entry)
 	if (entry)
 		entry->type = type;
 		entry->type = type;
 	else
 	else
-		sms_err("No registry found.");
+		pr_err("No registry found.\n");
 }
 }
 
 
 
 
@@ -635,10 +632,8 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
 	struct smscore_buffer_t *cb;
 	struct smscore_buffer_t *cb;
 
 
 	cb = kzalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
 	cb = kzalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
-	if (!cb) {
-		sms_info("kzalloc(...) failed");
+	if (!cb)
 		return NULL;
 		return NULL;
-	}
 
 
 	cb->p = buffer;
 	cb->p = buffer;
 	cb->offset_in_common = buffer - (u8 *) common_buffer;
 	cb->offset_in_common = buffer - (u8 *) common_buffer;
@@ -658,16 +653,19 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
  * @return 0 on success, <0 on error.
  * @return 0 on success, <0 on error.
  */
  */
 int smscore_register_device(struct smsdevice_params_t *params,
 int smscore_register_device(struct smsdevice_params_t *params,
-			    struct smscore_device_t **coredev)
+			    struct smscore_device_t **coredev,
+			    void *mdev)
 {
 {
 	struct smscore_device_t *dev;
 	struct smscore_device_t *dev;
 	u8 *buffer;
 	u8 *buffer;
 
 
 	dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
 	dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
-	if (!dev) {
-		sms_info("kzalloc(...) failed");
+	if (!dev)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
+
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	dev->media_dev = mdev;
+#endif
 
 
 	/* init list entry so it could be safe in smscore_unregister_device */
 	/* init list entry so it could be safe in smscore_unregister_device */
 	INIT_LIST_HEAD(&dev->entry);
 	INIT_LIST_HEAD(&dev->entry);
@@ -722,7 +720,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
 		smscore_putbuffer(dev, cb);
 		smscore_putbuffer(dev, cb);
 	}
 	}
 
 
-	sms_info("allocated %d buffers", dev->num_buffers);
+	pr_debug("allocated %d buffers\n", dev->num_buffers);
 
 
 	dev->mode = DEVICE_MODE_NONE;
 	dev->mode = DEVICE_MODE_NONE;
 	dev->board_id = SMS_BOARD_UNKNOWN;
 	dev->board_id = SMS_BOARD_UNKNOWN;
@@ -746,7 +744,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
 
 
 	*coredev = dev;
 	*coredev = dev;
 
 
-	sms_info("device %p created", dev);
+	pr_debug("device %p created\n", dev);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -763,7 +761,7 @@ static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
 
 
 	rc = coredev->sendrequest_handler(coredev->context, buffer, size);
 	rc = coredev->sendrequest_handler(coredev->context, buffer, size);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_info("sendrequest returned error %d", rc);
+		pr_info("sendrequest returned error %d\n", rc);
 		return rc;
 		return rc;
 	}
 	}
 
 
@@ -786,11 +784,11 @@ static int smscore_init_ir(struct smscore_device_t *coredev)
 	coredev->ir.dev = NULL;
 	coredev->ir.dev = NULL;
 	ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
 	ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
 	if (ir_io) {/* only if IR port exist we use IR sub-module */
 	if (ir_io) {/* only if IR port exist we use IR sub-module */
-		sms_info("IR loading");
+		pr_debug("IR loading\n");
 		rc = sms_ir_init(coredev);
 		rc = sms_ir_init(coredev);
 
 
 		if	(rc != 0)
 		if	(rc != 0)
-			sms_err("Error initialization DTV IR sub-module");
+			pr_err("Error initialization DTV IR sub-module\n");
 		else {
 		else {
 			buffer = kmalloc(sizeof(struct sms_msg_data2) +
 			buffer = kmalloc(sizeof(struct sms_msg_data2) +
 						SMS_DMA_ALIGNMENT,
 						SMS_DMA_ALIGNMENT,
@@ -812,11 +810,10 @@ static int smscore_init_ir(struct smscore_device_t *coredev)
 
 
 				kfree(buffer);
 				kfree(buffer);
 			} else
 			} else
-				sms_err
-				("Sending IR initialization message failed");
+				pr_err("Sending IR initialization message failed\n");
 		}
 		}
 	} else
 	} else
-		sms_info("IR port has not been detected");
+		pr_info("IR port has not been detected\n");
 
 
 	return 0;
 	return 0;
 }
 }
@@ -835,13 +832,13 @@ static int smscore_configure_board(struct smscore_device_t *coredev)
 
 
 	board = sms_get_board(coredev->board_id);
 	board = sms_get_board(coredev->board_id);
 	if (!board) {
 	if (!board) {
-		sms_err("no board configuration exist.");
+		pr_err("no board configuration exist.\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
 	if (board->mtu) {
 	if (board->mtu) {
 		struct sms_msg_data mtu_msg;
 		struct sms_msg_data mtu_msg;
-		sms_debug("set max transmit unit %d", board->mtu);
+		pr_debug("set max transmit unit %d\n", board->mtu);
 
 
 		mtu_msg.x_msg_header.msg_src_id = 0;
 		mtu_msg.x_msg_header.msg_src_id = 0;
 		mtu_msg.x_msg_header.msg_dst_id = HIF_TASK;
 		mtu_msg.x_msg_header.msg_dst_id = HIF_TASK;
@@ -856,7 +853,7 @@ static int smscore_configure_board(struct smscore_device_t *coredev)
 
 
 	if (board->crystal) {
 	if (board->crystal) {
 		struct sms_msg_data crys_msg;
 		struct sms_msg_data crys_msg;
-		sms_debug("set crystal value %d", board->crystal);
+		pr_debug("set crystal value %d\n", board->crystal);
 
 
 		SMS_INIT_MSG(&crys_msg.x_msg_header,
 		SMS_INIT_MSG(&crys_msg.x_msg_header,
 				MSG_SMS_NEW_CRYSTAL_REQ,
 				MSG_SMS_NEW_CRYSTAL_REQ,
@@ -890,12 +887,12 @@ int smscore_start_device(struct smscore_device_t *coredev)
 
 
 	rc = smscore_set_device_mode(coredev, mode);
 	rc = smscore_set_device_mode(coredev, mode);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_info("set device mode faile , rc %d", rc);
+		pr_info("set device mode failed , rc %d\n", rc);
 		return rc;
 		return rc;
 	}
 	}
 	rc = smscore_configure_board(coredev);
 	rc = smscore_configure_board(coredev);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_info("configure board failed , rc %d", rc);
+		pr_info("configure board failed , rc %d\n", rc);
 		return rc;
 		return rc;
 	}
 	}
 
 
@@ -904,7 +901,7 @@ int smscore_start_device(struct smscore_device_t *coredev)
 	rc = smscore_notify_callbacks(coredev, coredev->device, 1);
 	rc = smscore_notify_callbacks(coredev, coredev->device, 1);
 	smscore_init_ir(coredev);
 	smscore_init_ir(coredev);
 
 
-	sms_info("device %p started, rc %d", coredev, rc);
+	pr_debug("device %p started, rc %d\n", coredev, rc);
 
 
 	kmutex_unlock(&g_smscore_deviceslock);
 	kmutex_unlock(&g_smscore_deviceslock);
 
 
@@ -927,7 +924,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
 
 
 	mem_address = firmware->start_address;
 	mem_address = firmware->start_address;
 
 
-	sms_info("loading FW to addr 0x%x size %d",
+	pr_debug("loading FW to addr 0x%x size %d\n",
 		 mem_address, firmware->length);
 		 mem_address, firmware->length);
 	if (coredev->preload_handler) {
 	if (coredev->preload_handler) {
 		rc = coredev->preload_handler(coredev->context);
 		rc = coredev->preload_handler(coredev->context);
@@ -941,14 +938,14 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	if (coredev->mode != DEVICE_MODE_NONE) {
 	if (coredev->mode != DEVICE_MODE_NONE) {
-		sms_debug("sending reload command.");
+		pr_debug("sending reload command.\n");
 		SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_START_REQ,
 		SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_START_REQ,
 			     sizeof(struct sms_msg_hdr));
 			     sizeof(struct sms_msg_hdr));
 		rc = smscore_sendrequest_and_wait(coredev, msg,
 		rc = smscore_sendrequest_and_wait(coredev, msg,
 						  msg->x_msg_header.msg_length,
 						  msg->x_msg_header.msg_length,
 						  &coredev->reload_start_done);
 						  &coredev->reload_start_done);
 		if (rc < 0) {
 		if (rc < 0) {
-			sms_err("device reload failed, rc %d", rc);
+			pr_err("device reload failed, rc %d\n", rc);
 			goto exit_fw_download;
 			goto exit_fw_download;
 		}
 		}
 		mem_address = *(u32 *) &payload[20];
 		mem_address = *(u32 *) &payload[20];
@@ -982,7 +979,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
 	if (rc < 0)
 	if (rc < 0)
 		goto exit_fw_download;
 		goto exit_fw_download;
 
 
-	sms_debug("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x",
+	pr_debug("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x\n",
 		calc_checksum);
 		calc_checksum);
 	SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ,
 	SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ,
 			sizeof(msg->x_msg_header) +
 			sizeof(msg->x_msg_header) +
@@ -1001,7 +998,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
 		struct sms_msg_data *trigger_msg =
 		struct sms_msg_data *trigger_msg =
 			(struct sms_msg_data *) msg;
 			(struct sms_msg_data *) msg;
 
 
-		sms_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ");
+		pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n");
 		SMS_INIT_MSG(&msg->x_msg_header,
 		SMS_INIT_MSG(&msg->x_msg_header,
 				MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
 				MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
 				sizeof(struct sms_msg_hdr) +
 				sizeof(struct sms_msg_hdr) +
@@ -1037,12 +1034,13 @@ exit_fw_download:
 	kfree(msg);
 	kfree(msg);
 
 
 	if (coredev->postload_handler) {
 	if (coredev->postload_handler) {
-		sms_debug("rc=%d, postload=0x%p", rc, coredev->postload_handler);
+		pr_debug("rc=%d, postload=0x%p\n",
+			 rc, coredev->postload_handler);
 		if (rc >= 0)
 		if (rc >= 0)
 			return coredev->postload_handler(coredev->context);
 			return coredev->postload_handler(coredev->context);
 	}
 	}
 
 
-	sms_debug("rc=%d", rc);
+	pr_debug("rc=%d\n", rc);
 	return rc;
 	return rc;
 }
 }
 
 
@@ -1121,11 +1119,11 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
 	if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX)
 	if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX)
 		return NULL;
 		return NULL;
 
 
-	sms_debug("trying to get fw name from sms_boards board_id %d mode %d",
+	pr_debug("trying to get fw name from sms_boards board_id %d mode %d\n",
 		  board_id, mode);
 		  board_id, mode);
 	fw = sms_get_board(board_id)->fw;
 	fw = sms_get_board(board_id)->fw;
 	if (!fw || !fw[mode]) {
 	if (!fw || !fw[mode]) {
-		sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d",
+		pr_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d\n",
 			  mode, type);
 			  mode, type);
 		return smscore_fw_lkup[type][mode];
 		return smscore_fw_lkup[type][mode];
 	}
 	}
@@ -1154,10 +1152,10 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
 
 
 	char *fw_filename = smscore_get_fw_filename(coredev, mode);
 	char *fw_filename = smscore_get_fw_filename(coredev, mode);
 	if (!fw_filename) {
 	if (!fw_filename) {
-		sms_err("mode %d not supported on this device", mode);
+		pr_err("mode %d not supported on this device\n", mode);
 		return -ENOENT;
 		return -ENOENT;
 	}
 	}
-	sms_debug("Firmware name: %s", fw_filename);
+	pr_debug("Firmware name: %s\n", fw_filename);
 
 
 	if (loadfirmware_handler == NULL && !(coredev->device_flags
 	if (loadfirmware_handler == NULL && !(coredev->device_flags
 			& SMS_DEVICE_FAMILY2))
 			& SMS_DEVICE_FAMILY2))
@@ -1165,14 +1163,14 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
 
 
 	rc = request_firmware(&fw, fw_filename, coredev->device);
 	rc = request_firmware(&fw, fw_filename, coredev->device);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_err("failed to open firmware file \"%s\"", fw_filename);
+		pr_err("failed to open firmware file '%s'\n", fw_filename);
 		return rc;
 		return rc;
 	}
 	}
-	sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size);
+	pr_debug("read fw %s, buffer size=0x%zx\n", fw_filename, fw->size);
 	fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
 	fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
 			 GFP_KERNEL | GFP_DMA);
 			 GFP_KERNEL | GFP_DMA);
 	if (!fw_buf) {
 	if (!fw_buf) {
-		sms_err("failed to allocate firmware buffer");
+		pr_err("failed to allocate firmware buffer\n");
 		rc = -ENOMEM;
 		rc = -ENOMEM;
 	} else {
 	} else {
 		memcpy(fw_buf, fw->data, fw->size);
 		memcpy(fw_buf, fw->data, fw->size);
@@ -1226,18 +1224,18 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
 		if (num_buffers == coredev->num_buffers)
 		if (num_buffers == coredev->num_buffers)
 			break;
 			break;
 		if (++retry > 10) {
 		if (++retry > 10) {
-			sms_info("exiting although not all buffers released.");
+			pr_info("exiting although not all buffers released.\n");
 			break;
 			break;
 		}
 		}
 
 
-		sms_info("waiting for %d buffer(s)",
+		pr_debug("waiting for %d buffer(s)\n",
 			 coredev->num_buffers - num_buffers);
 			 coredev->num_buffers - num_buffers);
 		kmutex_unlock(&g_smscore_deviceslock);
 		kmutex_unlock(&g_smscore_deviceslock);
 		msleep(100);
 		msleep(100);
 		kmutex_lock(&g_smscore_deviceslock);
 		kmutex_lock(&g_smscore_deviceslock);
 	}
 	}
 
 
-	sms_info("freed %d buffers", num_buffers);
+	pr_debug("freed %d buffers\n", num_buffers);
 
 
 	if (coredev->common_buffer)
 	if (coredev->common_buffer)
 		dma_free_coherent(NULL, coredev->common_buffer_size,
 		dma_free_coherent(NULL, coredev->common_buffer_size,
@@ -1250,7 +1248,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
 
 
 	kmutex_unlock(&g_smscore_deviceslock);
 	kmutex_unlock(&g_smscore_deviceslock);
 
 
-	sms_info("device %p destroyed", coredev);
+	pr_debug("device %p destroyed\n", coredev);
 }
 }
 EXPORT_SYMBOL_GPL(smscore_unregister_device);
 EXPORT_SYMBOL_GPL(smscore_unregister_device);
 
 
@@ -1271,7 +1269,7 @@ static int smscore_detect_mode(struct smscore_device_t *coredev)
 	rc = smscore_sendrequest_and_wait(coredev, msg, msg->msg_length,
 	rc = smscore_sendrequest_and_wait(coredev, msg, msg->msg_length,
 					  &coredev->version_ex_done);
 					  &coredev->version_ex_done);
 	if (rc == -ETIME) {
 	if (rc == -ETIME) {
-		sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
+		pr_err("MSG_SMS_GET_VERSION_EX_REQ failed first try\n");
 
 
 		if (wait_for_completion_timeout(&coredev->resume_done,
 		if (wait_for_completion_timeout(&coredev->resume_done,
 						msecs_to_jiffies(5000))) {
 						msecs_to_jiffies(5000))) {
@@ -1279,7 +1277,7 @@ static int smscore_detect_mode(struct smscore_device_t *coredev)
 				coredev, msg, msg->msg_length,
 				coredev, msg, msg->msg_length,
 				&coredev->version_ex_done);
 				&coredev->version_ex_done);
 			if (rc < 0)
 			if (rc < 0)
-				sms_err("MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d",
+				pr_err("MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n",
 					rc);
 					rc);
 		} else
 		} else
 			rc = -ETIME;
 			rc = -ETIME;
@@ -1308,7 +1306,7 @@ static int smscore_init_device(struct smscore_device_t *coredev, int mode)
 	buffer = kmalloc(sizeof(struct sms_msg_data) +
 	buffer = kmalloc(sizeof(struct sms_msg_data) +
 			SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
 			SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
 	if (!buffer) {
 	if (!buffer) {
-		sms_err("Could not allocate buffer for init device message.");
+		pr_err("Could not allocate buffer for init device message.\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
@@ -1339,10 +1337,10 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
 {
 {
 	int rc = 0;
 	int rc = 0;
 
 
-	sms_debug("set device mode to %d", mode);
+	pr_debug("set device mode to %d\n", mode);
 	if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
 	if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
 		if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) {
 		if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) {
-			sms_err("invalid mode specified %d", mode);
+			pr_err("invalid mode specified %d\n", mode);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 
 
@@ -1351,13 +1349,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
 		if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
 		if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
 			rc = smscore_detect_mode(coredev);
 			rc = smscore_detect_mode(coredev);
 			if (rc < 0) {
 			if (rc < 0) {
-				sms_err("mode detect failed %d", rc);
+				pr_err("mode detect failed %d\n", rc);
 				return rc;
 				return rc;
 			}
 			}
 		}
 		}
 
 
 		if (coredev->mode == mode) {
 		if (coredev->mode == mode) {
-			sms_info("device mode %d already set", mode);
+			pr_debug("device mode %d already set\n", mode);
 			return 0;
 			return 0;
 		}
 		}
 
 
@@ -1365,19 +1363,19 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
 			rc = smscore_load_firmware_from_file(coredev,
 			rc = smscore_load_firmware_from_file(coredev,
 							     mode, NULL);
 							     mode, NULL);
 			if (rc >= 0)
 			if (rc >= 0)
-				sms_info("firmware download success");
+				pr_debug("firmware download success\n");
 		} else {
 		} else {
-			sms_info("mode %d is already supported by running firmware",
+			pr_debug("mode %d is already supported by running firmware\n",
 				 mode);
 				 mode);
 		}
 		}
 		if (coredev->fw_version >= 0x800) {
 		if (coredev->fw_version >= 0x800) {
 			rc = smscore_init_device(coredev, mode);
 			rc = smscore_init_device(coredev, mode);
 			if (rc < 0)
 			if (rc < 0)
-				sms_err("device init failed, rc %d.", rc);
+				pr_err("device init failed, rc %d.\n", rc);
 		}
 		}
 	} else {
 	} else {
 		if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) {
 		if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) {
-			sms_err("invalid mode specified %d", mode);
+			pr_err("invalid mode specified %d\n", mode);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 
 
@@ -1414,9 +1412,9 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
 	}
 	}
 
 
 	if (rc < 0)
 	if (rc < 0)
-		sms_err("return error code %d.", rc);
+		pr_err("return error code %d.\n", rc);
 	else
 	else
-		sms_debug("Success setting device mode.");
+		pr_debug("Success setting device mode.\n");
 
 
 	return rc;
 	return rc;
 }
 }
@@ -1495,7 +1493,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
 		last_sample_time = time_now;
 		last_sample_time = time_now;
 
 
 	if (time_now - last_sample_time > 10000) {
 	if (time_now - last_sample_time > 10000) {
-		sms_debug("data rate %d bytes/secs",
+		pr_debug("data rate %d bytes/secs\n",
 			  (int)((data_total * 1000) /
 			  (int)((data_total * 1000) /
 				(time_now - last_sample_time)));
 				(time_now - last_sample_time)));
 
 
@@ -1539,7 +1537,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
 		{
 		{
 			struct sms_version_res *ver =
 			struct sms_version_res *ver =
 				(struct sms_version_res *) phdr;
 				(struct sms_version_res *) phdr;
-			sms_debug("Firmware id %d prots 0x%x ver %d.%d",
+			pr_debug("Firmware id %d prots 0x%x ver %d.%d\n",
 				  ver->firmware_id, ver->supported_protocols,
 				  ver->firmware_id, ver->supported_protocols,
 				  ver->rom_ver_major, ver->rom_ver_minor);
 				  ver->rom_ver_major, ver->rom_ver_minor);
 
 
@@ -1562,7 +1560,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
 		{
 		{
 			struct sms_msg_data *validity = (struct sms_msg_data *) phdr;
 			struct sms_msg_data *validity = (struct sms_msg_data *) phdr;
 
 
-			sms_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x",
+			pr_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x\n",
 				validity->msg_data[0]);
 				validity->msg_data[0]);
 			complete(&coredev->data_validity_done);
 			complete(&coredev->data_validity_done);
 			break;
 			break;
@@ -1588,7 +1586,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
 		{
 		{
 			u32 *msgdata = (u32 *) phdr;
 			u32 *msgdata = (u32 *) phdr;
 			coredev->gpio_get_res = msgdata[1];
 			coredev->gpio_get_res = msgdata[1];
-			sms_debug("gpio level %d",
+			pr_debug("gpio level %d\n",
 					coredev->gpio_get_res);
 					coredev->gpio_get_res);
 			complete(&coredev->gpio_get_level_done);
 			complete(&coredev->gpio_get_level_done);
 			break;
 			break;
@@ -1615,7 +1613,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
 			break;
 			break;
 
 
 		default:
 		default:
-			sms_debug("message %s(%d) not handled.",
+			pr_debug("message %s(%d) not handled.\n",
 				  smscore_translate_msg(phdr->msg_type),
 				  smscore_translate_msg(phdr->msg_type),
 				  phdr->msg_type);
 				  phdr->msg_type);
 			break;
 			break;
@@ -1681,7 +1679,7 @@ static int smscore_validate_client(struct smscore_device_t *coredev,
 	struct smscore_client_t *registered_client;
 	struct smscore_client_t *registered_client;
 
 
 	if (!client) {
 	if (!client) {
-		sms_err("bad parameter.");
+		pr_err("bad parameter.\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 	registered_client = smscore_find_client(coredev, data_type, id);
 	registered_client = smscore_find_client(coredev, data_type, id);
@@ -1689,12 +1687,12 @@ static int smscore_validate_client(struct smscore_device_t *coredev,
 		return 0;
 		return 0;
 
 
 	if (registered_client) {
 	if (registered_client) {
-		sms_err("The msg ID already registered to another client.");
+		pr_err("The msg ID already registered to another client.\n");
 		return -EEXIST;
 		return -EEXIST;
 	}
 	}
 	listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
 	listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
 	if (!listentry) {
 	if (!listentry) {
-		sms_err("Can't allocate memory for client id.");
+		pr_err("Can't allocate memory for client id.\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 	listentry->id = id;
 	listentry->id = id;
@@ -1726,13 +1724,13 @@ int smscore_register_client(struct smscore_device_t *coredev,
 	/* check that no other channel with same parameters exists */
 	/* check that no other channel with same parameters exists */
 	if (smscore_find_client(coredev, params->data_type,
 	if (smscore_find_client(coredev, params->data_type,
 				params->initial_id)) {
 				params->initial_id)) {
-		sms_err("Client already exist.");
+		pr_err("Client already exist.\n");
 		return -EEXIST;
 		return -EEXIST;
 	}
 	}
 
 
 	newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
 	newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
 	if (!newclient) {
 	if (!newclient) {
-		sms_err("Failed to allocate memory for client.");
+		pr_err("Failed to allocate memory for client.\n");
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
@@ -1746,7 +1744,7 @@ int smscore_register_client(struct smscore_device_t *coredev,
 	smscore_validate_client(coredev, newclient, params->data_type,
 	smscore_validate_client(coredev, newclient, params->data_type,
 				params->initial_id);
 				params->initial_id);
 	*client = newclient;
 	*client = newclient;
-	sms_debug("%p %d %d", params->context, params->data_type,
+	pr_debug("%p %d %d\n", params->context, params->data_type,
 		  params->initial_id);
 		  params->initial_id);
 
 
 	return 0;
 	return 0;
@@ -1775,7 +1773,7 @@ void smscore_unregister_client(struct smscore_client_t *client)
 		kfree(identry);
 		kfree(identry);
 	}
 	}
 
 
-	sms_info("%p", client->context);
+	pr_debug("%p\n", client->context);
 
 
 	list_del(&client->entry);
 	list_del(&client->entry);
 	kfree(client);
 	kfree(client);
@@ -1803,7 +1801,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
 	int rc;
 	int rc;
 
 
 	if (client == NULL) {
 	if (client == NULL) {
-		sms_err("Got NULL client");
+		pr_err("Got NULL client\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -1811,7 +1809,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
 
 
 	/* check that no other channel with same id exists */
 	/* check that no other channel with same id exists */
 	if (coredev == NULL) {
 	if (coredev == NULL) {
-		sms_err("Got NULL coredev");
+		pr_err("Got NULL coredev\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -2016,9 +2014,9 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin_num,
 
 
 	if (rc != 0) {
 	if (rc != 0) {
 		if (rc == -ETIME)
 		if (rc == -ETIME)
-			sms_err("smscore_gpio_configure timeout");
+			pr_err("smscore_gpio_configure timeout\n");
 		else
 		else
-			sms_err("smscore_gpio_configure error");
+			pr_err("smscore_gpio_configure error\n");
 	}
 	}
 free:
 free:
 	kfree(buffer);
 	kfree(buffer);
@@ -2065,9 +2063,9 @@ int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 pin_num,
 
 
 	if (rc != 0) {
 	if (rc != 0) {
 		if (rc == -ETIME)
 		if (rc == -ETIME)
-			sms_err("smscore_gpio_set_level timeout");
+			pr_err("smscore_gpio_set_level timeout\n");
 		else
 		else
-			sms_err("smscore_gpio_set_level error");
+			pr_err("smscore_gpio_set_level error\n");
 	}
 	}
 	kfree(buffer);
 	kfree(buffer);
 
 
@@ -2113,9 +2111,9 @@ int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 pin_num,
 
 
 	if (rc != 0) {
 	if (rc != 0) {
 		if (rc == -ETIME)
 		if (rc == -ETIME)
-			sms_err("smscore_gpio_get_level timeout");
+			pr_err("smscore_gpio_get_level timeout\n");
 		else
 		else
-			sms_err("smscore_gpio_get_level error");
+			pr_err("smscore_gpio_get_level error\n");
 	}
 	}
 	kfree(buffer);
 	kfree(buffer);
 
 
@@ -2163,7 +2161,7 @@ static void __exit smscore_module_exit(void)
 	}
 	}
 	kmutex_unlock(&g_smscore_registrylock);
 	kmutex_unlock(&g_smscore_registrylock);
 
 
-	sms_debug("");
+	pr_debug("\n");
 }
 }
 
 
 module_init(smscore_module_init);
 module_init(smscore_module_init);

+ 10 - 22
drivers/media/common/siano/smscoreapi.h

@@ -22,6 +22,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef __SMS_CORE_API_H__
 #ifndef __SMS_CORE_API_H__
 #define __SMS_CORE_API_H__
 #define __SMS_CORE_API_H__
 
 
+#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
+
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
@@ -31,6 +33,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <linux/wait.h>
 #include <linux/wait.h>
 #include <linux/timer.h>
 #include <linux/timer.h>
 
 
+#include <media/media-device.h>
+
 #include <asm/page.h>
 #include <asm/page.h>
 
 
 #include "smsir.h"
 #include "smsir.h"
@@ -215,6 +219,10 @@ struct smscore_device_t {
 	bool is_usb_device;
 	bool is_usb_device;
 
 
 	int led_state;
 	int led_state;
+
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	struct media_device *media_dev;
+#endif
 };
 };
 
 
 /* GPIO definitions for antenna frequency domain control (SMS8021) */
 /* GPIO definitions for antenna frequency domain control (SMS8021) */
@@ -1115,7 +1123,8 @@ extern int smscore_register_hotplug(hotplug_t hotplug);
 extern void smscore_unregister_hotplug(hotplug_t hotplug);
 extern void smscore_unregister_hotplug(hotplug_t hotplug);
 
 
 extern int smscore_register_device(struct smsdevice_params_t *params,
 extern int smscore_register_device(struct smsdevice_params_t *params,
-				   struct smscore_device_t **coredev);
+				   struct smscore_device_t **coredev,
+				   void *mdev);
 extern void smscore_unregister_device(struct smscore_device_t *coredev);
 extern void smscore_unregister_device(struct smscore_device_t *coredev);
 
 
 extern int smscore_start_device(struct smscore_device_t *coredev);
 extern int smscore_start_device(struct smscore_device_t *coredev);
@@ -1168,25 +1177,4 @@ int smscore_led_state(struct smscore_device_t *core, int led);
 
 
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
 
-#define DBG_INFO 1
-#define DBG_ADV  2
-
-#define sms_printk(kern, fmt, arg...) \
-	printk(kern "%s: " fmt "\n", __func__, ##arg)
-
-#define dprintk(kern, lvl, fmt, arg...) do {\
-	if (sms_dbg & lvl) \
-		sms_printk(kern, fmt, ##arg); \
-} while (0)
-
-#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
-#define sms_err(fmt, arg...) \
-	sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
-#define sms_warn(fmt, arg...)  sms_printk(KERN_WARNING, fmt, ##arg)
-#define sms_info(fmt, arg...) \
-	dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
-#define sms_debug(fmt, arg...) \
-	dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
-
-
 #endif /* __SMS_CORE_API_H__ */
 #endif /* __SMS_CORE_API_H__ */

+ 2 - 4
drivers/media/common/siano/smsdvb-debugfs.c

@@ -17,7 +17,7 @@
  *
  *
  ***********************************************************************/
  ***********************************************************************/
 
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include "smscoreapi.h"
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
@@ -31,8 +31,6 @@
 #include "dvb_demux.h"
 #include "dvb_demux.h"
 #include "dvb_frontend.h"
 #include "dvb_frontend.h"
 
 
-#include "smscoreapi.h"
-
 #include "smsdvb.h"
 #include "smsdvb.h"
 
 
 static struct dentry *smsdvb_debugfs_usb_root;
 static struct dentry *smsdvb_debugfs_usb_root;
@@ -536,7 +534,7 @@ int smsdvb_debugfs_register(void)
 	 */
 	 */
 	d = debugfs_create_dir("smsdvb", usb_debug_root);
 	d = debugfs_create_dir("smsdvb", usb_debug_root);
 	if (IS_ERR_OR_NULL(d)) {
 	if (IS_ERR_OR_NULL(d)) {
-		sms_err("Couldn't create sysfs node for smsdvb");
+		pr_err("Couldn't create sysfs node for smsdvb\n");
 		return PTR_ERR(d);
 		return PTR_ERR(d);
 	} else {
 	} else {
 		smsdvb_debugfs_usb_root = d;
 		smsdvb_debugfs_usb_root = d;

+ 43 - 31
drivers/media/common/siano/smsdvb-main.c

@@ -19,6 +19,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 ****************************************************************/
 ****************************************************************/
 
 
+#include "smscoreapi.h"
+
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/init.h>
@@ -29,7 +31,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "dvb_demux.h"
 #include "dvb_demux.h"
 #include "dvb_frontend.h"
 #include "dvb_frontend.h"
 
 
-#include "smscoreapi.h"
 #include "sms-cards.h"
 #include "sms-cards.h"
 
 
 #include "smsdvb.h"
 #include "smsdvb.h"
@@ -39,11 +40,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 static struct list_head g_smsdvb_clients;
 static struct list_head g_smsdvb_clients;
 static struct mutex g_smsdvb_clientslock;
 static struct mutex g_smsdvb_clientslock;
 
 
-static int sms_dbg;
-module_param_named(debug, sms_dbg, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
-
-
 static u32 sms_to_guard_interval_table[] = {
 static u32 sms_to_guard_interval_table[] = {
 	[0] = GUARD_INTERVAL_1_32,
 	[0] = GUARD_INTERVAL_1_32,
 	[1] = GUARD_INTERVAL_1_16,
 	[1] = GUARD_INTERVAL_1_16,
@@ -82,48 +78,48 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client,
 	struct smscore_device_t *coredev = client->coredev;
 	struct smscore_device_t *coredev = client->coredev;
 	switch (event) {
 	switch (event) {
 	case DVB3_EVENT_INIT:
 	case DVB3_EVENT_INIT:
-		sms_debug("DVB3_EVENT_INIT");
+		pr_debug("DVB3_EVENT_INIT\n");
 		sms_board_event(coredev, BOARD_EVENT_BIND);
 		sms_board_event(coredev, BOARD_EVENT_BIND);
 		break;
 		break;
 	case DVB3_EVENT_SLEEP:
 	case DVB3_EVENT_SLEEP:
-		sms_debug("DVB3_EVENT_SLEEP");
+		pr_debug("DVB3_EVENT_SLEEP\n");
 		sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
 		sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
 		break;
 		break;
 	case DVB3_EVENT_HOTPLUG:
 	case DVB3_EVENT_HOTPLUG:
-		sms_debug("DVB3_EVENT_HOTPLUG");
+		pr_debug("DVB3_EVENT_HOTPLUG\n");
 		sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
 		sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
 		break;
 		break;
 	case DVB3_EVENT_FE_LOCK:
 	case DVB3_EVENT_FE_LOCK:
 		if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
 		if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
 			client->event_fe_state = DVB3_EVENT_FE_LOCK;
 			client->event_fe_state = DVB3_EVENT_FE_LOCK;
-			sms_debug("DVB3_EVENT_FE_LOCK");
+			pr_debug("DVB3_EVENT_FE_LOCK\n");
 			sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
 			sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
 		}
 		}
 		break;
 		break;
 	case DVB3_EVENT_FE_UNLOCK:
 	case DVB3_EVENT_FE_UNLOCK:
 		if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
 		if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
 			client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
 			client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
-			sms_debug("DVB3_EVENT_FE_UNLOCK");
+			pr_debug("DVB3_EVENT_FE_UNLOCK\n");
 			sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
 			sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
 		}
 		}
 		break;
 		break;
 	case DVB3_EVENT_UNC_OK:
 	case DVB3_EVENT_UNC_OK:
 		if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
 		if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
 			client->event_unc_state = DVB3_EVENT_UNC_OK;
 			client->event_unc_state = DVB3_EVENT_UNC_OK;
-			sms_debug("DVB3_EVENT_UNC_OK");
+			pr_debug("DVB3_EVENT_UNC_OK\n");
 			sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
 			sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
 		}
 		}
 		break;
 		break;
 	case DVB3_EVENT_UNC_ERR:
 	case DVB3_EVENT_UNC_ERR:
 		if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
 		if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
 			client->event_unc_state = DVB3_EVENT_UNC_ERR;
 			client->event_unc_state = DVB3_EVENT_UNC_ERR;
-			sms_debug("DVB3_EVENT_UNC_ERR");
+			pr_debug("DVB3_EVENT_UNC_ERR\n");
 			sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
 			sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
 		}
 		}
 		break;
 		break;
 
 
 	default:
 	default:
-		sms_err("Unknown dvb3 api event");
+		pr_err("Unknown dvb3 api event\n");
 		break;
 		break;
 	}
 	}
 }
 }
@@ -590,7 +586,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
 		is_status_update = true;
 		is_status_update = true;
 		break;
 		break;
 	default:
 	default:
-		sms_info("message not handled");
+		pr_debug("message not handled\n");
 	}
 	}
 	smscore_putbuffer(client->coredev, cb);
 	smscore_putbuffer(client->coredev, cb);
 
 
@@ -613,6 +609,19 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
 	return 0;
 	return 0;
 }
 }
 
 
+static void smsdvb_media_device_unregister(struct smsdvb_client_t *client)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	struct smscore_device_t *coredev = client->coredev;
+
+	if (!coredev->media_dev)
+		return;
+	media_device_unregister(coredev->media_dev);
+	kfree(coredev->media_dev);
+	coredev->media_dev = NULL;
+#endif
+}
+
 static void smsdvb_unregister_client(struct smsdvb_client_t *client)
 static void smsdvb_unregister_client(struct smsdvb_client_t *client)
 {
 {
 	/* must be called under clientslock */
 	/* must be called under clientslock */
@@ -624,6 +633,7 @@ static void smsdvb_unregister_client(struct smsdvb_client_t *client)
 	dvb_unregister_frontend(&client->frontend);
 	dvb_unregister_frontend(&client->frontend);
 	dvb_dmxdev_release(&client->dmxdev);
 	dvb_dmxdev_release(&client->dmxdev);
 	dvb_dmx_release(&client->demux);
 	dvb_dmx_release(&client->demux);
+	smsdvb_media_device_unregister(client);
 	dvb_unregister_adapter(&client->adapter);
 	dvb_unregister_adapter(&client->adapter);
 	kfree(client);
 	kfree(client);
 }
 }
@@ -643,7 +653,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed)
 		container_of(feed->demux, struct smsdvb_client_t, demux);
 		container_of(feed->demux, struct smsdvb_client_t, demux);
 	struct sms_msg_data pid_msg;
 	struct sms_msg_data pid_msg;
 
 
-	sms_debug("add pid %d(%x)",
+	pr_debug("add pid %d(%x)\n",
 		  feed->pid, feed->pid);
 		  feed->pid, feed->pid);
 
 
 	client->feed_users++;
 	client->feed_users++;
@@ -665,7 +675,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
 		container_of(feed->demux, struct smsdvb_client_t, demux);
 		container_of(feed->demux, struct smsdvb_client_t, demux);
 	struct sms_msg_data pid_msg;
 	struct sms_msg_data pid_msg;
 
 
-	sms_debug("remove pid %d(%x)",
+	pr_debug("remove pid %d(%x)\n",
 		  feed->pid, feed->pid);
 		  feed->pid, feed->pid);
 
 
 	client->feed_users--;
 	client->feed_users--;
@@ -835,7 +845,7 @@ static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
 static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
 				    struct dvb_frontend_tune_settings *tune)
 				    struct dvb_frontend_tune_settings *tune)
 {
 {
-	sms_debug("");
+	pr_debug("\n");
 
 
 	tune->min_delay_ms = 400;
 	tune->min_delay_ms = 400;
 	tune->step_size = 250000;
 	tune->step_size = 250000;
@@ -869,7 +879,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
 	msg.Data[0] = c->frequency;
 	msg.Data[0] = c->frequency;
 	msg.Data[2] = 12000000;
 	msg.Data[2] = 12000000;
 
 
-	sms_info("%s: freq %d band %d", __func__, c->frequency,
+	pr_debug("%s: freq %d band %d\n", __func__, c->frequency,
 		 c->bandwidth_hz);
 		 c->bandwidth_hz);
 
 
 	switch (c->bandwidth_hz / 1000000) {
 	switch (c->bandwidth_hz / 1000000) {
@@ -954,7 +964,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
 
 
 	c->bandwidth_hz = 6000000;
 	c->bandwidth_hz = 6000000;
 
 
-	sms_info("%s: freq %d segwidth %d segindex %d", __func__,
+	pr_debug("freq %d segwidth %d segindex %d\n",
 		 c->frequency, c->isdbt_sb_segment_count,
 		 c->frequency, c->isdbt_sb_segment_count,
 		 c->isdbt_sb_segment_idx);
 		 c->isdbt_sb_segment_idx);
 
 
@@ -1082,10 +1092,8 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
 	if (!arrival)
 	if (!arrival)
 		return 0;
 		return 0;
 	client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
 	client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
-	if (!client) {
-		sms_err("kmalloc() failed");
+	if (!client)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	/* register dvb adapter */
 	/* register dvb adapter */
 	rc = dvb_register_adapter(&client->adapter,
 	rc = dvb_register_adapter(&client->adapter,
@@ -1093,9 +1101,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
 					smscore_get_board_id(coredev))->name,
 					smscore_get_board_id(coredev))->name,
 				  THIS_MODULE, device, adapter_nr);
 				  THIS_MODULE, device, adapter_nr);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_err("dvb_register_adapter() failed %d", rc);
+		pr_err("dvb_register_adapter() failed %d\n", rc);
 		goto adapter_error;
 		goto adapter_error;
 	}
 	}
+	dvb_register_media_controller(&client->adapter, coredev->media_dev);
 
 
 	/* init dvb demux */
 	/* init dvb demux */
 	client->demux.dmx.capabilities = DMX_TS_FILTERING;
 	client->demux.dmx.capabilities = DMX_TS_FILTERING;
@@ -1106,7 +1115,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
 
 
 	rc = dvb_dmx_init(&client->demux);
 	rc = dvb_dmx_init(&client->demux);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_err("dvb_dmx_init failed %d", rc);
+		pr_err("dvb_dmx_init failed %d\n", rc);
 		goto dvbdmx_error;
 		goto dvbdmx_error;
 	}
 	}
 
 
@@ -1117,7 +1126,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
 
 
 	rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
 	rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_err("dvb_dmxdev_init failed %d", rc);
+		pr_err("dvb_dmxdev_init failed %d\n", rc);
 		goto dmxdev_error;
 		goto dmxdev_error;
 	}
 	}
 
 
@@ -1138,7 +1147,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
 
 
 	rc = dvb_register_frontend(&client->adapter, &client->frontend);
 	rc = dvb_register_frontend(&client->adapter, &client->frontend);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_err("frontend registration failed %d", rc);
+		pr_err("frontend registration failed %d\n", rc);
 		goto frontend_error;
 		goto frontend_error;
 	}
 	}
 
 
@@ -1150,7 +1159,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
 
 
 	rc = smscore_register_client(coredev, &params, &client->smsclient);
 	rc = smscore_register_client(coredev, &params, &client->smsclient);
 	if (rc < 0) {
 	if (rc < 0) {
-		sms_err("smscore_register_client() failed %d", rc);
+		pr_err("smscore_register_client() failed %d\n", rc);
 		goto client_error;
 		goto client_error;
 	}
 	}
 
 
@@ -1169,12 +1178,14 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
 	client->event_unc_state = -1;
 	client->event_unc_state = -1;
 	sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
 	sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
 
 
-	sms_info("success");
 	sms_board_setup(coredev);
 	sms_board_setup(coredev);
 
 
 	if (smsdvb_debugfs_create(client) < 0)
 	if (smsdvb_debugfs_create(client) < 0)
-		sms_info("failed to create debugfs node");
+		pr_info("failed to create debugfs node\n");
+
+	dvb_create_media_graph(&client->adapter);
 
 
+	pr_info("DVB interface registered.\n");
 	return 0;
 	return 0;
 
 
 client_error:
 client_error:
@@ -1187,6 +1198,7 @@ dmxdev_error:
 	dvb_dmx_release(&client->demux);
 	dvb_dmx_release(&client->demux);
 
 
 dvbdmx_error:
 dvbdmx_error:
+	smsdvb_media_device_unregister(client);
 	dvb_unregister_adapter(&client->adapter);
 	dvb_unregister_adapter(&client->adapter);
 
 
 adapter_error:
 adapter_error:
@@ -1205,7 +1217,7 @@ static int __init smsdvb_module_init(void)
 
 
 	rc = smscore_register_hotplug(smsdvb_hotplug);
 	rc = smscore_register_hotplug(smsdvb_hotplug);
 
 
-	sms_debug("");
+	pr_debug("\n");
 
 
 	return rc;
 	return rc;
 }
 }

+ 9 - 9
drivers/media/common/siano/smsir.c

@@ -25,10 +25,11 @@
  ****************************************************************/
  ****************************************************************/
 
 
 
 
+#include "smscoreapi.h"
+
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/input.h>
 #include <linux/input.h>
 
 
-#include "smscoreapi.h"
 #include "smsir.h"
 #include "smsir.h"
 #include "sms-cards.h"
 #include "sms-cards.h"
 
 
@@ -56,16 +57,14 @@ int sms_ir_init(struct smscore_device_t *coredev)
 	int board_id = smscore_get_board_id(coredev);
 	int board_id = smscore_get_board_id(coredev);
 	struct rc_dev *dev;
 	struct rc_dev *dev;
 
 
-	sms_log("Allocating rc device");
+	pr_debug("Allocating rc device\n");
 	dev = rc_allocate_device();
 	dev = rc_allocate_device();
-	if (!dev) {
-		sms_err("Not enough memory");
+	if (!dev)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	coredev->ir.controller = 0;	/* Todo: vega/nova SPI number */
 	coredev->ir.controller = 0;	/* Todo: vega/nova SPI number */
 	coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
 	coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
-	sms_log("IR port %d, timeout %d ms",
+	pr_debug("IR port %d, timeout %d ms\n",
 			coredev->ir.controller, coredev->ir.timeout);
 			coredev->ir.controller, coredev->ir.timeout);
 
 
 	snprintf(coredev->ir.name, sizeof(coredev->ir.name),
 	snprintf(coredev->ir.name, sizeof(coredev->ir.name),
@@ -92,11 +91,12 @@ int sms_ir_init(struct smscore_device_t *coredev)
 	dev->map_name = sms_get_board(board_id)->rc_codes;
 	dev->map_name = sms_get_board(board_id)->rc_codes;
 	dev->driver_name = MODULE_NAME;
 	dev->driver_name = MODULE_NAME;
 
 
-	sms_log("Input device (IR) %s is set for key events", dev->input_name);
+	pr_debug("Input device (IR) %s is set for key events\n",
+		 dev->input_name);
 
 
 	err = rc_register_device(dev);
 	err = rc_register_device(dev);
 	if (err < 0) {
 	if (err < 0) {
-		sms_err("Failed to register device");
+		pr_err("Failed to register device\n");
 		rc_free_device(dev);
 		rc_free_device(dev);
 		return err;
 		return err;
 	}
 	}
@@ -109,5 +109,5 @@ void sms_ir_exit(struct smscore_device_t *coredev)
 {
 {
 	rc_unregister_device(coredev->ir.dev);
 	rc_unregister_device(coredev->ir.dev);
 
 
-	sms_log("");
+	pr_debug("\n");
 }
 }

+ 8 - 3
drivers/media/dvb-core/dmxdev.c

@@ -1136,10 +1136,13 @@ static const struct file_operations dvb_demux_fops = {
 	.llseek = default_llseek,
 	.llseek = default_llseek,
 };
 };
 
 
-static struct dvb_device dvbdev_demux = {
+static const struct dvb_device dvbdev_demux = {
 	.priv = NULL,
 	.priv = NULL,
 	.users = 1,
 	.users = 1,
 	.writers = 1,
 	.writers = 1,
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	.name = "dvb-demux",
+#endif
 	.fops = &dvb_demux_fops
 	.fops = &dvb_demux_fops
 };
 };
 
 
@@ -1209,13 +1212,15 @@ static const struct file_operations dvb_dvr_fops = {
 	.llseek = default_llseek,
 	.llseek = default_llseek,
 };
 };
 
 
-static struct dvb_device dvbdev_dvr = {
+static const struct dvb_device dvbdev_dvr = {
 	.priv = NULL,
 	.priv = NULL,
 	.readers = 1,
 	.readers = 1,
 	.users = 1,
 	.users = 1,
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	.name = "dvb-dvr",
+#endif
 	.fops = &dvb_dvr_fops
 	.fops = &dvb_dvr_fops
 };
 };
-
 int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
 int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
 {
 {
 	int i;
 	int i;

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

@@ -245,6 +245,7 @@
 #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM	0x3009
 #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM	0x3009
 #define USB_PID_TECHNOTREND_CONNECT_CT3650		0x300d
 #define USB_PID_TECHNOTREND_CONNECT_CT3650		0x300d
+#define USB_PID_TECHNOTREND_CONNECT_S2_4600             0x3011
 #define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI		0x3012
 #define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI		0x3012
 #define USB_PID_TECHNOTREND_TVSTICK_CT2_4400		0x3014
 #define USB_PID_TECHNOTREND_TVSTICK_CT2_4400		0x3014
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
@@ -318,6 +319,7 @@
 #define USB_PID_GRANDTEC_DVBT_USB2_COLD			0x0bc6
 #define USB_PID_GRANDTEC_DVBT_USB2_COLD			0x0bc6
 #define USB_PID_GRANDTEC_DVBT_USB2_WARM			0x0bc7
 #define USB_PID_GRANDTEC_DVBT_USB2_WARM			0x0bc7
 #define USB_PID_WINFAST_DTV2000DS			0x6a04
 #define USB_PID_WINFAST_DTV2000DS			0x6a04
+#define USB_PID_WINFAST_DTV2000DS_PLUS			0x6f12
 #define USB_PID_WINFAST_DTV_DONGLE_COLD			0x6025
 #define USB_PID_WINFAST_DTV_DONGLE_COLD			0x6025
 #define USB_PID_WINFAST_DTV_DONGLE_WARM			0x6026
 #define USB_PID_WINFAST_DTV_DONGLE_WARM			0x6026
 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P		0x6f00
 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P		0x6f00
@@ -385,4 +387,5 @@
 #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
 #define USB_PID_SVEON_STV27                             0xd3af
+#define USB_PID_TURBOX_DTT_2000                         0xd3a4
 #endif
 #endif

+ 16 - 14
drivers/media/dvb-core/dvb_ca_en50221.c

@@ -1638,15 +1638,17 @@ static const struct file_operations dvb_ca_fops = {
 	.llseek = noop_llseek,
 	.llseek = noop_llseek,
 };
 };
 
 
-static struct dvb_device dvbdev_ca = {
+static const struct dvb_device dvbdev_ca = {
 	.priv = NULL,
 	.priv = NULL,
 	.users = 1,
 	.users = 1,
 	.readers = 1,
 	.readers = 1,
 	.writers = 1,
 	.writers = 1,
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	.name = "dvb-ca-en50221",
+#endif
 	.fops = &dvb_ca_fops,
 	.fops = &dvb_ca_fops,
 };
 };
 
 
-
 /* ******************************************************************************** */
 /* ******************************************************************************** */
 /* Initialisation/shutdown functions */
 /* Initialisation/shutdown functions */
 
 
@@ -1676,14 +1678,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 	/* initialise the system data */
 	/* initialise the system data */
 	if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) {
 	if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
-		goto error;
+		goto exit;
 	}
 	}
 	ca->pub = pubca;
 	ca->pub = pubca;
 	ca->flags = flags;
 	ca->flags = flags;
 	ca->slot_count = slot_count;
 	ca->slot_count = slot_count;
 	if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) {
 	if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
-		goto error;
+		goto free_ca;
 	}
 	}
 	init_waitqueue_head(&ca->wait_queue);
 	init_waitqueue_head(&ca->wait_queue);
 	ca->open = 0;
 	ca->open = 0;
@@ -1694,7 +1696,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 	/* register the DVB device */
 	/* register the DVB device */
 	ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
 	ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
 	if (ret)
 	if (ret)
-		goto error;
+		goto free_slot_info;
 
 
 	/* now initialise each slot */
 	/* now initialise each slot */
 	for (i = 0; i < slot_count; i++) {
 	for (i = 0; i < slot_count; i++) {
@@ -1709,7 +1711,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 
 
 	if (signal_pending(current)) {
 	if (signal_pending(current)) {
 		ret = -EINTR;
 		ret = -EINTR;
-		goto error;
+		goto unregister_device;
 	}
 	}
 	mb();
 	mb();
 
 
@@ -1720,17 +1722,17 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 		ret = PTR_ERR(ca->thread);
 		ret = PTR_ERR(ca->thread);
 		printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
 		printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
 			ret);
 			ret);
-		goto error;
+		goto unregister_device;
 	}
 	}
 	return 0;
 	return 0;
 
 
-error:
-	if (ca != NULL) {
-		if (ca->dvbdev != NULL)
-			dvb_unregister_device(ca->dvbdev);
-		kfree(ca->slot_info);
-		kfree(ca);
-	}
+unregister_device:
+	dvb_unregister_device(ca->dvbdev);
+free_slot_info:
+	kfree(ca->slot_info);
+free_ca:
+	kfree(ca);
+exit:
 	pubca->private = NULL;
 	pubca->private = NULL;
 	return ret;
 	return ret;
 }
 }

+ 123 - 1
drivers/media/dvb-core/dvb_frontend.c

@@ -131,6 +131,11 @@ struct dvb_frontend_private {
 	int quality;
 	int quality;
 	unsigned int check_wrapped;
 	unsigned int check_wrapped;
 	enum dvbfe_search algo_status;
 	enum dvbfe_search algo_status;
+
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	struct media_pipeline pipe;
+	struct media_entity *pipe_start_entity;
+#endif
 };
 };
 
 
 static void dvb_frontend_wakeup(struct dvb_frontend *fe);
 static void dvb_frontend_wakeup(struct dvb_frontend *fe);
@@ -590,12 +595,106 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe)
 	wake_up_interruptible(&fepriv->wait_queue);
 	wake_up_interruptible(&fepriv->wait_queue);
 }
 }
 
 
+/**
+ * dvb_enable_media_tuner() - tries to enable the DVB tuner
+ *
+ * @fe:		struct dvb_frontend pointer
+ *
+ * This function ensures that just one media tuner is enabled for a given
+ * frontend. It has two different behaviors:
+ * - For trivial devices with just one tuner:
+ *   it just enables the existing tuner->fe link
+ * - For devices with more than one tuner:
+ *   It is up to the driver to implement the logic that will enable one tuner
+ *   and disable the other ones. However, if more than one tuner is enabled for
+ *   the same frontend, it will print an error message and return -EINVAL.
+ *
+ * At return, it will return the error code returned by media_entity_setup_link,
+ * or 0 if everything is OK, if no tuner is linked to the frontend or if the
+ * mdev is NULL.
+ */
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+static int dvb_enable_media_tuner(struct dvb_frontend *fe)
+{
+	struct dvb_frontend_private *fepriv = fe->frontend_priv;
+	struct dvb_adapter *adapter = fe->dvb;
+	struct media_device *mdev = adapter->mdev;
+	struct media_entity  *entity, *source;
+	struct media_link *link, *found_link = NULL;
+	int i, ret, n_links = 0, active_links = 0;
+
+	fepriv->pipe_start_entity = NULL;
+
+	if (!mdev)
+		return 0;
+
+	entity = fepriv->dvbdev->entity;
+	fepriv->pipe_start_entity = entity;
+
+	for (i = 0; i < entity->num_links; i++) {
+		link = &entity->links[i];
+		if (link->sink->entity == entity) {
+			found_link = link;
+			n_links++;
+			if (link->flags & MEDIA_LNK_FL_ENABLED)
+				active_links++;
+		}
+	}
+
+	if (!n_links || active_links == 1 || !found_link)
+		return 0;
+
+	/*
+	 * If a frontend has more than one tuner linked, it is up to the driver
+	 * to select with one will be the active one, as the frontend core can't
+	 * guess. If the driver doesn't do that, it is a bug.
+	 */
+	if (n_links > 1 && active_links != 1) {
+		dev_err(fe->dvb->device,
+			"WARNING: there are %d active links among %d tuners. This is a driver's bug!\n",
+			active_links, n_links);
+		return -EINVAL;
+	}
+
+	source = found_link->source->entity;
+	fepriv->pipe_start_entity = source;
+	for (i = 0; i < source->num_links; i++) {
+		struct media_entity *sink;
+		int flags = 0;
+
+		link = &source->links[i];
+		sink = link->sink->entity;
+
+		if (sink == entity)
+			flags = MEDIA_LNK_FL_ENABLED;
+
+		ret = media_entity_setup_link(link, flags);
+		if (ret) {
+			dev_err(fe->dvb->device,
+				"Couldn't change link %s->%s to %s. Error %d\n",
+				source->name, sink->name,
+				flags ? "enabled" : "disabled",
+				ret);
+			return ret;
+		} else
+			dev_dbg(fe->dvb->device,
+				"link %s->%s was %s\n",
+				source->name, sink->name,
+				flags ? "ENABLED" : "disabled");
+	}
+	return 0;
+}
+#endif
+
 static int dvb_frontend_thread(void *data)
 static int dvb_frontend_thread(void *data)
 {
 {
 	struct dvb_frontend *fe = data;
 	struct dvb_frontend *fe = data;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	fe_status_t s;
 	fe_status_t s;
 	enum dvbfe_algo algo;
 	enum dvbfe_algo algo;
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	int ret;
+#endif
 
 
 	bool re_tune = false;
 	bool re_tune = false;
 	bool semheld = false;
 	bool semheld = false;
@@ -609,6 +708,20 @@ static int dvb_frontend_thread(void *data)
 	fepriv->wakeup = 0;
 	fepriv->wakeup = 0;
 	fepriv->reinitialise = 0;
 	fepriv->reinitialise = 0;
 
 
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	ret = dvb_enable_media_tuner(fe);
+	if (ret) {
+		/* FIXME: return an error if it fails */
+		dev_info(fe->dvb->device,
+			"proceeding with FE task\n");
+	} else if (fepriv->pipe_start_entity) {
+		ret = media_entity_pipeline_start(fepriv->pipe_start_entity,
+						  &fepriv->pipe);
+		if (ret)
+			return ret;
+	}
+#endif
+
 	dvb_frontend_init(fe);
 	dvb_frontend_init(fe);
 
 
 	set_freezable();
 	set_freezable();
@@ -718,6 +831,12 @@ restart:
 		}
 		}
 	}
 	}
 
 
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	if (fepriv->pipe_start_entity)
+		media_entity_pipeline_stop(fepriv->pipe_start_entity);
+	fepriv->pipe_start_entity = NULL;
+#endif
+
 	if (dvb_powerdown_on_sleep) {
 	if (dvb_powerdown_on_sleep) {
 		if (fe->ops.set_voltage)
 		if (fe->ops.set_voltage)
 			fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
 			fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
@@ -2612,11 +2731,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 			  struct dvb_frontend* fe)
 			  struct dvb_frontend* fe)
 {
 {
 	struct dvb_frontend_private *fepriv;
 	struct dvb_frontend_private *fepriv;
-	static const struct dvb_device dvbdev_template = {
+	const struct dvb_device dvbdev_template = {
 		.users = ~0,
 		.users = ~0,
 		.writers = 1,
 		.writers = 1,
 		.readers = (~0)-1,
 		.readers = (~0)-1,
 		.fops = &dvb_frontend_fops,
 		.fops = &dvb_frontend_fops,
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+		.name = fe->ops.info.name,
+#endif
 		.kernel_ioctl = dvb_frontend_ioctl
 		.kernel_ioctl = dvb_frontend_ioctl
 	};
 	};
 
 

+ 4 - 2
drivers/media/dvb-core/dvb_net.c

@@ -1461,14 +1461,16 @@ static const struct file_operations dvb_net_fops = {
 	.llseek = noop_llseek,
 	.llseek = noop_llseek,
 };
 };
 
 
-static struct dvb_device dvbdev_net = {
+static const struct dvb_device dvbdev_net = {
 	.priv = NULL,
 	.priv = NULL,
 	.users = 1,
 	.users = 1,
 	.writers = 1,
 	.writers = 1,
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	.name = "dvb-net",
+#endif
 	.fops = &dvb_net_fops,
 	.fops = &dvb_net_fops,
 };
 };
 
 
-
 void dvb_net_release (struct dvb_net *dvbnet)
 void dvb_net_release (struct dvb_net *dvbnet)
 {
 {
 	int i;
 	int i;

+ 143 - 1
drivers/media/dvb-core/dvbdev.c

@@ -180,6 +180,93 @@ skip:
 	return -ENFILE;
 	return -ENFILE;
 }
 }
 
 
+static void dvb_register_media_device(struct dvb_device *dvbdev,
+				      int type, int minor)
+{
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	int ret = 0, npads;
+
+	if (!dvbdev->adapter->mdev)
+		return;
+
+	dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
+	if (!dvbdev->entity)
+		return;
+
+	dvbdev->entity->info.dev.major = DVB_MAJOR;
+	dvbdev->entity->info.dev.minor = minor;
+	dvbdev->entity->name = dvbdev->name;
+
+	switch (type) {
+	case DVB_DEVICE_CA:
+	case DVB_DEVICE_DEMUX:
+	case DVB_DEVICE_FRONTEND:
+		npads = 2;
+		break;
+	case DVB_DEVICE_NET:
+		npads = 0;
+		break;
+	default:
+		npads = 1;
+	}
+
+	if (npads) {
+		dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
+				       GFP_KERNEL);
+		if (!dvbdev->pads) {
+			kfree(dvbdev->entity);
+			return;
+		}
+	}
+
+	switch (type) {
+	case DVB_DEVICE_FRONTEND:
+		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_FE;
+		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+		break;
+	case DVB_DEVICE_DEMUX:
+		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DEMUX;
+		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+		break;
+	case DVB_DEVICE_DVR:
+		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DVR;
+		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+		break;
+	case DVB_DEVICE_CA:
+		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA;
+		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+		break;
+	case DVB_DEVICE_NET:
+		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_NET;
+		break;
+	default:
+		kfree(dvbdev->entity);
+		dvbdev->entity = NULL;
+		return;
+	}
+
+	if (npads)
+		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0);
+	if (!ret)
+		ret = media_device_register_entity(dvbdev->adapter->mdev,
+						   dvbdev->entity);
+	if (ret < 0) {
+		printk(KERN_ERR
+			"%s: media_device_register_entity failed for %s\n",
+			__func__, dvbdev->entity->name);
+		kfree(dvbdev->pads);
+		kfree(dvbdev->entity);
+		dvbdev->entity = NULL;
+		return;
+	}
+
+	printk(KERN_DEBUG "%s: media device '%s' registered.\n",
+		__func__, dvbdev->entity->name);
+#endif
+}
 
 
 int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 			const struct dvb_device *template, void *priv, int type)
 			const struct dvb_device *template, void *priv, int type)
@@ -258,10 +345,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 		       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
 		       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
 		return PTR_ERR(clsdev);
 		return PTR_ERR(clsdev);
 	}
 	}
-
 	dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
 	dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
 		adap->num, dnames[type], id, minor, minor);
 		adap->num, dnames[type], id, minor, minor);
 
 
+	dvb_register_media_device(dvbdev, type, minor);
+
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL(dvb_register_device);
 EXPORT_SYMBOL(dvb_register_device);
@@ -278,12 +366,66 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
 
 
 	device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
 	device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
 
 
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	if (dvbdev->entity) {
+		media_device_unregister_entity(dvbdev->entity);
+		kfree(dvbdev->entity);
+		kfree(dvbdev->pads);
+	}
+#endif
+
 	list_del (&dvbdev->list_head);
 	list_del (&dvbdev->list_head);
 	kfree (dvbdev->fops);
 	kfree (dvbdev->fops);
 	kfree (dvbdev);
 	kfree (dvbdev);
 }
 }
 EXPORT_SYMBOL(dvb_unregister_device);
 EXPORT_SYMBOL(dvb_unregister_device);
 
 
+
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+void dvb_create_media_graph(struct dvb_adapter *adap)
+{
+	struct media_device *mdev = adap->mdev;
+	struct media_entity *entity, *tuner = NULL, *fe = NULL;
+	struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL;
+
+	if (!mdev)
+		return;
+
+	media_device_for_each_entity(entity, mdev) {
+		switch (entity->type) {
+		case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
+			tuner = entity;
+			break;
+		case MEDIA_ENT_T_DEVNODE_DVB_FE:
+			fe = entity;
+			break;
+		case MEDIA_ENT_T_DEVNODE_DVB_DEMUX:
+			demux = entity;
+			break;
+		case MEDIA_ENT_T_DEVNODE_DVB_DVR:
+			dvr = entity;
+			break;
+		case MEDIA_ENT_T_DEVNODE_DVB_CA:
+			ca = entity;
+			break;
+		}
+	}
+
+	if (tuner && fe)
+		media_entity_create_link(tuner, 0, fe, 0, 0);
+
+	if (fe && demux)
+		media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
+
+	if (demux && dvr)
+		media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
+
+	if (demux && ca)
+		media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
+}
+EXPORT_SYMBOL_GPL(dvb_create_media_graph);
+#endif
+
 static int dvbdev_check_free_adapter_num(int num)
 static int dvbdev_check_free_adapter_num(int num)
 {
 {
 	struct list_head *entry;
 	struct list_head *entry;

+ 27 - 0
drivers/media/dvb-core/dvbdev.h

@@ -27,6 +27,7 @@
 #include <linux/poll.h>
 #include <linux/poll.h>
 #include <linux/fs.h>
 #include <linux/fs.h>
 #include <linux/list.h>
 #include <linux/list.h>
+#include <media/media-device.h>
 
 
 #define DVB_MAJOR 212
 #define DVB_MAJOR 212
 
 
@@ -71,6 +72,10 @@ struct dvb_adapter {
 	int mfe_shared;			/* indicates mutually exclusive frontends */
 	int mfe_shared;			/* indicates mutually exclusive frontends */
 	struct dvb_device *mfe_dvbdev;	/* frontend device in use */
 	struct dvb_device *mfe_dvbdev;	/* frontend device in use */
 	struct mutex mfe_lock;		/* access lock for thread creation */
 	struct mutex mfe_lock;		/* access lock for thread creation */
+
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	struct media_device *mdev;
+#endif
 };
 };
 
 
 
 
@@ -92,6 +97,15 @@ struct dvb_device {
 	/* don't really need those !? -- FIXME: use video_usercopy  */
 	/* don't really need those !? -- FIXME: use video_usercopy  */
 	int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg);
 	int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg);
 
 
+	/* Needed for media controller register/unregister */
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	const char *name;
+
+	/* Allocated and filled inside dvbdev.c */
+	struct media_entity *entity;
+	struct media_pad *pads;
+#endif
+
 	void *priv;
 	void *priv;
 };
 };
 
 
@@ -109,6 +123,19 @@ extern int dvb_register_device (struct dvb_adapter *adap,
 
 
 extern void dvb_unregister_device (struct dvb_device *dvbdev);
 extern void dvb_unregister_device (struct dvb_device *dvbdev);
 
 
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+void dvb_create_media_graph(struct dvb_adapter *adap);
+static inline void dvb_register_media_controller(struct dvb_adapter *adap,
+						 struct media_device *mdev)
+{
+	adap->mdev = mdev;
+}
+
+#else
+static inline void dvb_create_media_graph(struct dvb_adapter *adap) {}
+#define dvb_register_media_controller(a, b) {}
+#endif
+
 extern int dvb_generic_open (struct inode *inode, struct file *file);
 extern int dvb_generic_open (struct inode *inode, struct file *file);
 extern int dvb_generic_release (struct inode *inode, struct file *file);
 extern int dvb_generic_release (struct inode *inode, struct file *file);
 extern long dvb_generic_ioctl (struct file *file,
 extern long dvb_generic_ioctl (struct file *file,

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

@@ -577,6 +577,14 @@ config DVB_LGDT3305
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
 	  to support this frontend.
 
 
+config DVB_LGDT3306A
+	tristate "LG Electronics LGDT3306A based"
+	depends on DVB_CORE && I2C
+	default m if !MEDIA_SUBDRV_AUTOSELECT
+	help
+	  An ATSC 8VSB and QAM-B 64/256 demodulator module. Say Y when you want
+	  to support this frontend.
+
 config DVB_LG2160
 config DVB_LG2160
 	tristate "LG Electronics LG216x based"
 	tristate "LG Electronics LG216x based"
 	depends on DVB_CORE && I2C
 	depends on DVB_CORE && I2C

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

@@ -54,6 +54,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
 obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
 obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
 obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
 obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
 obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
 obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
+obj-$(CONFIG_DVB_LGDT3306A) += lgdt3306a.o
 obj-$(CONFIG_DVB_LG2160) += lg2160.o
 obj-$(CONFIG_DVB_LG2160) += lg2160.o
 obj-$(CONFIG_DVB_CX24123) += cx24123.o
 obj-$(CONFIG_DVB_CX24123) += cx24123.o
 obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
 obj-$(CONFIG_DVB_LNBP21) += lnbp21.o

+ 1 - 1
drivers/media/dvb-frontends/a8293.h

@@ -27,7 +27,7 @@ struct a8293_config {
 	u8 i2c_addr;
 	u8 i2c_addr;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_A8293)
+#if IS_REACHABLE(CONFIG_DVB_A8293)
 extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
 extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
 	struct i2c_adapter *i2c, const struct a8293_config *cfg);
 	struct i2c_adapter *i2c, const struct a8293_config *cfg);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/af9013.h

@@ -103,7 +103,7 @@ struct af9013_config {
 	u8 gpio[4];
 	u8 gpio[4];
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_AF9013)
+#if IS_REACHABLE(CONFIG_DVB_AF9013)
 extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
 extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
 	struct i2c_adapter *i2c);
 	struct i2c_adapter *i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/atbm8830.h

@@ -61,7 +61,7 @@ struct atbm8830_config {
 	u8 agc_hold_loop;
 	u8 agc_hold_loop;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_ATBM8830)
+#if IS_REACHABLE(CONFIG_DVB_ATBM8830)
 extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
 extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
 		struct i2c_adapter *i2c);
 		struct i2c_adapter *i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/au8522.h

@@ -61,7 +61,7 @@ struct au8522_config {
 	enum au8522_if_freq qam_if;
 	enum au8522_if_freq qam_if;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_AU8522_DTV)
+#if IS_REACHABLE(CONFIG_DVB_AU8522_DTV)
 extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
 extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
 					  struct i2c_adapter *i2c);
 					  struct i2c_adapter *i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/bcm3510.h

@@ -34,7 +34,7 @@ struct bcm3510_config
 	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
 	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_BCM3510)
+#if IS_REACHABLE(CONFIG_DVB_BCM3510)
 extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
 extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
 					   struct i2c_adapter* i2c);
 					   struct i2c_adapter* i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/cx22700.h

@@ -31,7 +31,7 @@ struct cx22700_config
 	u8 demod_address;
 	u8 demod_address;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_CX22700)
+#if IS_REACHABLE(CONFIG_DVB_CX22700)
 extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
 extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
 					   struct i2c_adapter* i2c);
 					   struct i2c_adapter* i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/cx22702.h

@@ -41,7 +41,7 @@ struct cx22702_config {
 	u8 output_mode;
 	u8 output_mode;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_CX22702)
+#if IS_REACHABLE(CONFIG_DVB_CX22702)
 extern struct dvb_frontend *cx22702_attach(
 extern struct dvb_frontend *cx22702_attach(
 	const struct cx22702_config *config,
 	const struct cx22702_config *config,
 	struct i2c_adapter *i2c);
 	struct i2c_adapter *i2c);

+ 1 - 1
drivers/media/dvb-frontends/cx24110.h

@@ -46,7 +46,7 @@ static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val)
 	return 0;
 	return 0;
 }
 }
 
 
-#if IS_ENABLED(CONFIG_DVB_CX24110)
+#if IS_REACHABLE(CONFIG_DVB_CX24110)
 extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
 extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
 					   struct i2c_adapter* i2c);
 					   struct i2c_adapter* i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/cx24113.h

@@ -32,7 +32,7 @@ struct cx24113_config {
 	u32 xtal_khz;
 	u32 xtal_khz;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_TUNER_CX24113)
+#if IS_REACHABLE(CONFIG_DVB_TUNER_CX24113)
 extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *,
 extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *,
 	const struct cx24113_config *config, struct i2c_adapter *i2c);
 	const struct cx24113_config *config, struct i2c_adapter *i2c);
 
 

+ 1 - 1
drivers/media/dvb-frontends/cx24116.h

@@ -41,7 +41,7 @@ struct cx24116_config {
 	u16 i2c_wr_max;
 	u16 i2c_wr_max;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_CX24116)
+#if IS_REACHABLE(CONFIG_DVB_CX24116)
 extern struct dvb_frontend *cx24116_attach(
 extern struct dvb_frontend *cx24116_attach(
 	const struct cx24116_config *config,
 	const struct cx24116_config *config,
 	struct i2c_adapter *i2c);
 	struct i2c_adapter *i2c);

+ 1 - 1
drivers/media/dvb-frontends/cx24117.h

@@ -30,7 +30,7 @@ struct cx24117_config {
 	u8 demod_address;
 	u8 demod_address;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_CX24117)
+#if IS_REACHABLE(CONFIG_DVB_CX24117)
 extern struct dvb_frontend *cx24117_attach(
 extern struct dvb_frontend *cx24117_attach(
 	const struct cx24117_config *config,
 	const struct cx24117_config *config,
 	struct i2c_adapter *i2c);
 	struct i2c_adapter *i2c);

+ 1 - 1
drivers/media/dvb-frontends/cx24123.h

@@ -39,7 +39,7 @@ struct cx24123_config {
 	void (*agc_callback) (struct dvb_frontend *);
 	void (*agc_callback) (struct dvb_frontend *);
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_CX24123)
+#if IS_REACHABLE(CONFIG_DVB_CX24123)
 extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
 extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
 					   struct i2c_adapter *i2c);
 					   struct i2c_adapter *i2c);
 extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
 extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);

+ 1 - 1
drivers/media/dvb-frontends/cxd2820r.h

@@ -72,7 +72,7 @@ struct cxd2820r_config {
 };
 };
 
 
 
 
-#if IS_ENABLED(CONFIG_DVB_CXD2820R)
+#if IS_REACHABLE(CONFIG_DVB_CXD2820R)
 extern struct dvb_frontend *cxd2820r_attach(
 extern struct dvb_frontend *cxd2820r_attach(
 	const struct cxd2820r_config *config,
 	const struct cxd2820r_config *config,
 	struct i2c_adapter *i2c,
 	struct i2c_adapter *i2c,

+ 1 - 1
drivers/media/dvb-frontends/dib0070.h

@@ -48,7 +48,7 @@ struct dib0070_config {
 	u8 vga_filter;
 	u8 vga_filter;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_TUNER_DIB0070)
+#if IS_REACHABLE(CONFIG_DVB_TUNER_DIB0070)
 extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
 extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
 extern u16 dib0070_wbd_offset(struct dvb_frontend *);
 extern u16 dib0070_wbd_offset(struct dvb_frontend *);
 extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
 extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);

+ 1 - 1
drivers/media/dvb-frontends/dib0090.h

@@ -75,7 +75,7 @@ struct dib0090_config {
 	u8 force_crystal_mode;
 	u8 force_crystal_mode;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_TUNER_DIB0090)
+#if IS_REACHABLE(CONFIG_DVB_TUNER_DIB0090)
 extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
 extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
 extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
 extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
 extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
 extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);

+ 1 - 1
drivers/media/dvb-frontends/dib3000.h

@@ -41,7 +41,7 @@ struct dib_fe_xfer_ops
 	int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
 	int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_DIB3000MB)
+#if IS_REACHABLE(CONFIG_DVB_DIB3000MB)
 extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
 extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
 					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
 					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/dib3000mc.h

@@ -41,7 +41,7 @@ struct dib3000mc_config {
 #define DEFAULT_DIB3000MC_I2C_ADDRESS 16
 #define DEFAULT_DIB3000MC_I2C_ADDRESS 16
 #define DEFAULT_DIB3000P_I2C_ADDRESS  24
 #define DEFAULT_DIB3000P_I2C_ADDRESS  24
 
 
-#if IS_ENABLED(CONFIG_DVB_DIB3000MC)
+#if IS_REACHABLE(CONFIG_DVB_DIB3000MC)
 extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
 extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
 					     u8 i2c_addr,
 					     u8 i2c_addr,
 					     struct dib3000mc_config *cfg);
 					     struct dib3000mc_config *cfg);

+ 1 - 1
drivers/media/dvb-frontends/dib7000m.h

@@ -40,7 +40,7 @@ struct dib7000m_config {
 
 
 #define DEFAULT_DIB7000M_I2C_ADDRESS 18
 #define DEFAULT_DIB7000M_I2C_ADDRESS 18
 
 
-#if IS_ENABLED(CONFIG_DVB_DIB7000M)
+#if IS_REACHABLE(CONFIG_DVB_DIB7000M)
 extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
 extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
 					    u8 i2c_addr,
 					    u8 i2c_addr,
 					    struct dib7000m_config *cfg);
 					    struct dib7000m_config *cfg);

+ 1 - 1
drivers/media/dvb-frontends/dib7000p.h

@@ -66,7 +66,7 @@ struct dib7000p_ops {
 	struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
 	struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_DIB7000P)
+#if IS_REACHABLE(CONFIG_DVB_DIB7000P)
 void *dib7000p_attach(struct dib7000p_ops *ops);
 void *dib7000p_attach(struct dib7000p_ops *ops);
 #else
 #else
 static inline void *dib7000p_attach(struct dib7000p_ops *ops)
 static inline void *dib7000p_attach(struct dib7000p_ops *ops)

+ 1 - 1
drivers/media/dvb-frontends/dib8000.h

@@ -63,7 +63,7 @@ struct dib8000_ops {
 	struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
 	struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_DIB8000)
+#if IS_REACHABLE(CONFIG_DVB_DIB8000)
 void *dib8000_attach(struct dib8000_ops *ops);
 void *dib8000_attach(struct dib8000_ops *ops);
 #else
 #else
 static inline int dib8000_attach(struct dib8000_ops *ops)
 static inline int dib8000_attach(struct dib8000_ops *ops)

+ 1 - 1
drivers/media/dvb-frontends/dib9000.h

@@ -27,7 +27,7 @@ struct dib9000_config {
 
 
 #define DEFAULT_DIB9000_I2C_ADDRESS 18
 #define DEFAULT_DIB9000_I2C_ADDRESS 18
 
 
-#if IS_ENABLED(CONFIG_DVB_DIB9000)
+#if IS_REACHABLE(CONFIG_DVB_DIB9000)
 extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg);
 extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg);
 extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
 extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
 extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe);
 extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe);

+ 1 - 1
drivers/media/dvb-frontends/drx39xyj/drx39xxj.h

@@ -34,7 +34,7 @@ struct drx39xxj_state {
 	const struct firmware *fw;
 	const struct firmware *fw;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_DRX39XYJ)
+#if IS_REACHABLE(CONFIG_DVB_DRX39XYJ)
 struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c);
 struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c);
 #else
 #else
 static inline struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) {
 static inline struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) {

+ 1 - 1
drivers/media/dvb-frontends/drxd.h

@@ -52,7 +52,7 @@ struct drxd_config {
 	 s16(*osc_deviation) (void *priv, s16 dev, int flag);
 	 s16(*osc_deviation) (void *priv, s16 dev, int flag);
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_DRXD)
+#if IS_REACHABLE(CONFIG_DVB_DRXD)
 extern
 extern
 struct dvb_frontend *drxd_attach(const struct drxd_config *config,
 struct dvb_frontend *drxd_attach(const struct drxd_config *config,
 				 void *priv, struct i2c_adapter *i2c,
 				 void *priv, struct i2c_adapter *i2c,

+ 1 - 1
drivers/media/dvb-frontends/drxk.h

@@ -51,7 +51,7 @@ struct drxk_config {
 	int		 qam_demod_parameter_count;
 	int		 qam_demod_parameter_count;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_DRXK)
+#if IS_REACHABLE(CONFIG_DVB_DRXK)
 extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 					struct i2c_adapter *i2c);
 					struct i2c_adapter *i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/ds3000.h

@@ -35,7 +35,7 @@ struct ds3000_config {
 	void (*set_lock_led)(struct dvb_frontend *fe, int offon);
 	void (*set_lock_led)(struct dvb_frontend *fe, int offon);
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_DS3000)
+#if IS_REACHABLE(CONFIG_DVB_DS3000)
 extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
 extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
 					struct i2c_adapter *i2c);
 					struct i2c_adapter *i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/dvb-pll.h

@@ -38,7 +38,7 @@
  * @param pll_desc_id dvb_pll_desc to use.
  * @param pll_desc_id dvb_pll_desc to use.
  * @return Frontend pointer on success, NULL on failure
  * @return Frontend pointer on success, NULL on failure
  */
  */
-#if IS_ENABLED(CONFIG_DVB_PLL)
+#if IS_REACHABLE(CONFIG_DVB_PLL)
 extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
 extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
 					   int pll_addr,
 					   int pll_addr,
 					   struct i2c_adapter *i2c,
 					   struct i2c_adapter *i2c,

+ 1 - 1
drivers/media/dvb-frontends/dvb_dummy_fe.h

@@ -26,7 +26,7 @@
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/frontend.h>
 #include "dvb_frontend.h"
 #include "dvb_frontend.h"
 
 
-#if IS_ENABLED(CONFIG_DVB_DUMMY_FE)
+#if IS_REACHABLE(CONFIG_DVB_DUMMY_FE)
 extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
 extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
 extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
 extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
 extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
 extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);

+ 1 - 1
drivers/media/dvb-frontends/ec100.h

@@ -31,7 +31,7 @@ struct ec100_config {
 };
 };
 
 
 
 
-#if IS_ENABLED(CONFIG_DVB_EC100)
+#if IS_REACHABLE(CONFIG_DVB_EC100)
 extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
 extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
 	struct i2c_adapter *i2c);
 	struct i2c_adapter *i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/hd29l2.h

@@ -51,7 +51,7 @@ struct hd29l2_config {
 };
 };
 
 
 
 
-#if IS_ENABLED(CONFIG_DVB_HD29L2)
+#if IS_REACHABLE(CONFIG_DVB_HD29L2)
 extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
 extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
 	struct i2c_adapter *i2c);
 	struct i2c_adapter *i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/isl6405.h

@@ -55,7 +55,7 @@
 #define ISL6405_ENT2	0x20
 #define ISL6405_ENT2	0x20
 #define ISL6405_ISEL2	0x40
 #define ISL6405_ISEL2	0x40
 
 
-#if IS_ENABLED(CONFIG_DVB_ISL6405)
+#if IS_REACHABLE(CONFIG_DVB_ISL6405)
 /* override_set and override_clear control which system register bits (above)
 /* override_set and override_clear control which system register bits (above)
  * to always set & clear
  * to always set & clear
  */
  */

+ 1 - 1
drivers/media/dvb-frontends/isl6421.h

@@ -39,7 +39,7 @@
 #define ISL6421_ISEL1	0x20
 #define ISL6421_ISEL1	0x20
 #define ISL6421_DCL	0x40
 #define ISL6421_DCL	0x40
 
 
-#if IS_ENABLED(CONFIG_DVB_ISL6421)
+#if IS_REACHABLE(CONFIG_DVB_ISL6421)
 /* override_set and override_clear control which system register bits (above) to always set & clear */
 /* override_set and override_clear control which system register bits (above) to always set & clear */
 extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
 extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
 			  u8 override_set, u8 override_clear, bool override_tone);
 			  u8 override_set, u8 override_clear, bool override_tone);

+ 1 - 1
drivers/media/dvb-frontends/isl6423.h

@@ -42,7 +42,7 @@ struct isl6423_config {
 	u8 mod_extern;
 	u8 mod_extern;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_ISL6423)
+#if IS_REACHABLE(CONFIG_DVB_ISL6423)
 
 
 
 
 extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
 extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,

+ 1 - 1
drivers/media/dvb-frontends/itd1000.h

@@ -29,7 +29,7 @@ struct itd1000_config {
 	u8 i2c_address;
 	u8 i2c_address;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_TUNER_ITD1000)
+#if IS_REACHABLE(CONFIG_DVB_TUNER_ITD1000)
 extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg);
 extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg);
 #else
 #else
 static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
 static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)

+ 1 - 1
drivers/media/dvb-frontends/ix2505v.h

@@ -49,7 +49,7 @@ struct ix2505v_config {
 
 
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_IX2505V)
+#if IS_REACHABLE(CONFIG_DVB_IX2505V)
 extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
 extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
 	const struct ix2505v_config *config, struct i2c_adapter *i2c);
 	const struct ix2505v_config *config, struct i2c_adapter *i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/l64781.h

@@ -31,7 +31,7 @@ struct l64781_config
 	u8 demod_address;
 	u8 demod_address;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_L64781)
+#if IS_REACHABLE(CONFIG_DVB_L64781)
 extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
 extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
 					  struct i2c_adapter* i2c);
 					  struct i2c_adapter* i2c);
 #else
 #else

+ 1 - 1
drivers/media/dvb-frontends/lg2160.h

@@ -67,7 +67,7 @@ struct lg2160_config {
 	enum lg_chip_type lg_chip;
 	enum lg_chip_type lg_chip;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_LG2160)
+#if IS_REACHABLE(CONFIG_DVB_LG2160)
 extern
 extern
 struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
 struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
 				     struct i2c_adapter *i2c_adap);
 				     struct i2c_adapter *i2c_adap);

+ 1 - 1
drivers/media/dvb-frontends/lgdt3305.h

@@ -80,7 +80,7 @@ struct lgdt3305_config {
 	enum lgdt_demod_chip_type demod_chip;
 	enum lgdt_demod_chip_type demod_chip;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_LGDT3305)
+#if IS_REACHABLE(CONFIG_DVB_LGDT3305)
 extern
 extern
 struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
 struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
 				     struct i2c_adapter *i2c_adap);
 				     struct i2c_adapter *i2c_adap);

+ 2144 - 0
drivers/media/dvb-frontends/lgdt3306a.c

@@ -0,0 +1,2144 @@
+/*
+ *    Support for LGDT3306A - 8VSB/QAM-B
+ *
+ *    Copyright (C) 2013 Fred Richter <frichter@hauppauge.com>
+ *    - driver structure based on lgdt3305.[ch] by Michael Krufky
+ *    - code based on LG3306_V0.35 API by LG Electronics Inc.
+ *
+ *    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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <asm/div64.h>
+#include <linux/dvb/frontend.h>
+#include "dvb_math.h"
+#include "lgdt3306a.h"
+
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
+
+#define DBG_INFO 1
+#define DBG_REG  2
+#define DBG_DUMP 4 /* FGR - comment out to remove dump code */
+
+#define lg_debug(fmt, arg...) \
+	printk(KERN_DEBUG pr_fmt(fmt), ## arg)
+
+#define dbg_info(fmt, arg...)					\
+	do {							\
+		if (debug & DBG_INFO)				\
+			lg_debug(fmt, ## arg);			\
+	} while (0)
+
+#define dbg_reg(fmt, arg...)					\
+	do {							\
+		if (debug & DBG_REG)				\
+			lg_debug(fmt, ## arg);			\
+	} while (0)
+
+#define lg_chkerr(ret)							\
+({									\
+	int __ret;							\
+	__ret = (ret < 0);						\
+	if (__ret)							\
+		pr_err("error %d on line %d\n",	ret, __LINE__);		\
+	__ret;								\
+})
+
+struct lgdt3306a_state {
+	struct i2c_adapter *i2c_adap;
+	const struct lgdt3306a_config *cfg;
+
+	struct dvb_frontend frontend;
+
+	fe_modulation_t current_modulation;
+	u32 current_frequency;
+	u32 snr;
+};
+
+/*
+ * LG3306A Register Usage
+ *  (LG does not really name the registers, so this code does not either)
+ *
+ * 0000 -> 00FF Common control and status
+ * 1000 -> 10FF Synchronizer control and status
+ * 1F00 -> 1FFF Smart Antenna control and status
+ * 2100 -> 21FF VSB Equalizer control and status
+ * 2800 -> 28FF QAM Equalizer control and status
+ * 3000 -> 30FF FEC control and status
+ */
+
+enum lgdt3306a_lock_status {
+	LG3306_UNLOCK       = 0x00,
+	LG3306_LOCK         = 0x01,
+	LG3306_UNKNOWN_LOCK = 0xff
+};
+
+enum lgdt3306a_neverlock_status {
+	LG3306_NL_INIT    = 0x00,
+	LG3306_NL_PROCESS = 0x01,
+	LG3306_NL_LOCK    = 0x02,
+	LG3306_NL_FAIL    = 0x03,
+	LG3306_NL_UNKNOWN = 0xff
+};
+
+enum lgdt3306a_modulation {
+	LG3306_VSB          = 0x00,
+	LG3306_QAM64        = 0x01,
+	LG3306_QAM256       = 0x02,
+	LG3306_UNKNOWN_MODE = 0xff
+};
+
+enum lgdt3306a_lock_check {
+	LG3306_SYNC_LOCK,
+	LG3306_FEC_LOCK,
+	LG3306_TR_LOCK,
+	LG3306_AGC_LOCK,
+};
+
+
+#ifdef DBG_DUMP
+static void lgdt3306a_DumpAllRegs(struct lgdt3306a_state *state);
+static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state);
+#endif
+
+
+static int lgdt3306a_write_reg(struct lgdt3306a_state *state, u16 reg, u8 val)
+{
+	int ret;
+	u8 buf[] = { reg >> 8, reg & 0xff, val };
+	struct i2c_msg msg = {
+		.addr = state->cfg->i2c_addr, .flags = 0,
+		.buf = buf, .len = 3,
+	};
+
+	dbg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
+
+	ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+	if (ret != 1) {
+		pr_err("error (addr %02x %02x <- %02x, err = %i)\n",
+		       msg.buf[0], msg.buf[1], msg.buf[2], ret);
+		if (ret < 0)
+			return ret;
+		else
+			return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int lgdt3306a_read_reg(struct lgdt3306a_state *state, u16 reg, u8 *val)
+{
+	int ret;
+	u8 reg_buf[] = { reg >> 8, reg & 0xff };
+	struct i2c_msg msg[] = {
+		{ .addr = state->cfg->i2c_addr,
+		  .flags = 0, .buf = reg_buf, .len = 2 },
+		{ .addr = state->cfg->i2c_addr,
+		  .flags = I2C_M_RD, .buf = val, .len = 1 },
+	};
+
+	ret = i2c_transfer(state->i2c_adap, msg, 2);
+
+	if (ret != 2) {
+		pr_err("error (addr %02x reg %04x error (ret == %i)\n",
+		       state->cfg->i2c_addr, reg, ret);
+		if (ret < 0)
+			return ret;
+		else
+			return -EREMOTEIO;
+	}
+	dbg_reg("reg: 0x%04x, val: 0x%02x\n", reg, *val);
+
+	return 0;
+}
+
+#define read_reg(state, reg)						\
+({									\
+	u8 __val;							\
+	int ret = lgdt3306a_read_reg(state, reg, &__val);		\
+	if (lg_chkerr(ret))						\
+		__val = 0;						\
+	__val;								\
+})
+
+static int lgdt3306a_set_reg_bit(struct lgdt3306a_state *state,
+				u16 reg, int bit, int onoff)
+{
+	u8 val;
+	int ret;
+
+	dbg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
+
+	ret = lgdt3306a_read_reg(state, reg, &val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	val &= ~(1 << bit);
+	val |= (onoff & 1) << bit;
+
+	ret = lgdt3306a_write_reg(state, reg, val);
+	lg_chkerr(ret);
+fail:
+	return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3306a_soft_reset(struct lgdt3306a_state *state)
+{
+	int ret;
+
+	dbg_info("\n");
+
+	ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 0);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	msleep(20);
+	ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 1);
+	lg_chkerr(ret);
+
+fail:
+	return ret;
+}
+
+static int lgdt3306a_mpeg_mode(struct lgdt3306a_state *state,
+				     enum lgdt3306a_mpeg_mode mode)
+{
+	u8 val;
+	int ret;
+
+	dbg_info("(%d)\n", mode);
+	/* transport packet format - TPSENB=0x80 */
+	ret = lgdt3306a_set_reg_bit(state, 0x0071, 7,
+				     mode == LGDT3306A_MPEG_PARALLEL ? 1 : 0);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/*
+	 * start of packet signal duration
+	 * TPSSOPBITEN=0x40; 0=byte duration, 1=bit duration
+	 */
+	ret = lgdt3306a_set_reg_bit(state, 0x0071, 6, 0);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_read_reg(state, 0x0070, &val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	val |= 0x10; /* TPCLKSUPB=0x10 */
+
+	if (mode == LGDT3306A_MPEG_PARALLEL)
+		val &= ~0x10;
+
+	ret = lgdt3306a_write_reg(state, 0x0070, val);
+	lg_chkerr(ret);
+
+fail:
+	return ret;
+}
+
+static int lgdt3306a_mpeg_mode_polarity(struct lgdt3306a_state *state,
+				       enum lgdt3306a_tp_clock_edge edge,
+				       enum lgdt3306a_tp_valid_polarity valid)
+{
+	u8 val;
+	int ret;
+
+	dbg_info("edge=%d, valid=%d\n", edge, valid);
+
+	ret = lgdt3306a_read_reg(state, 0x0070, &val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	val &= ~0x06; /* TPCLKPOL=0x04, TPVALPOL=0x02 */
+
+	if (edge == LGDT3306A_TPCLK_RISING_EDGE)
+		val |= 0x04;
+	if (valid == LGDT3306A_TP_VALID_HIGH)
+		val |= 0x02;
+
+	ret = lgdt3306a_write_reg(state, 0x0070, val);
+	lg_chkerr(ret);
+
+fail:
+	return ret;
+}
+
+static int lgdt3306a_mpeg_tristate(struct lgdt3306a_state *state,
+				     int mode)
+{
+	u8 val;
+	int ret;
+
+	dbg_info("(%d)\n", mode);
+
+	if (mode) {
+		ret = lgdt3306a_read_reg(state, 0x0070, &val);
+		if (lg_chkerr(ret))
+			goto fail;
+		/*
+		 * Tristate bus; TPOUTEN=0x80, TPCLKOUTEN=0x20,
+		 * TPDATAOUTEN=0x08
+		 */
+		val &= ~0xa8;
+		ret = lgdt3306a_write_reg(state, 0x0070, val);
+		if (lg_chkerr(ret))
+			goto fail;
+
+		/* AGCIFOUTENB=0x40; 1=Disable IFAGC pin */
+		ret = lgdt3306a_set_reg_bit(state, 0x0003, 6, 1);
+		if (lg_chkerr(ret))
+			goto fail;
+
+	} else {
+		/* enable IFAGC pin */
+		ret = lgdt3306a_set_reg_bit(state, 0x0003, 6, 0);
+		if (lg_chkerr(ret))
+			goto fail;
+
+		ret = lgdt3306a_read_reg(state, 0x0070, &val);
+		if (lg_chkerr(ret))
+			goto fail;
+
+		val |= 0xa8; /* enable bus */
+		ret = lgdt3306a_write_reg(state, 0x0070, val);
+		if (lg_chkerr(ret))
+			goto fail;
+	}
+
+fail:
+	return ret;
+}
+
+static int lgdt3306a_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+
+	dbg_info("acquire=%d\n", acquire);
+
+	return lgdt3306a_mpeg_tristate(state, acquire ? 0 : 1);
+
+}
+
+static int lgdt3306a_power(struct lgdt3306a_state *state,
+				     int mode)
+{
+	int ret;
+
+	dbg_info("(%d)\n", mode);
+
+	if (mode == 0) {
+		/* into reset */
+		ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 0);
+		if (lg_chkerr(ret))
+			goto fail;
+
+		/* power down */
+		ret = lgdt3306a_set_reg_bit(state, 0x0000, 0, 0);
+		if (lg_chkerr(ret))
+			goto fail;
+
+	} else {
+		/* out of reset */
+		ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 1);
+		if (lg_chkerr(ret))
+			goto fail;
+
+		/* power up */
+		ret = lgdt3306a_set_reg_bit(state, 0x0000, 0, 1);
+		if (lg_chkerr(ret))
+			goto fail;
+	}
+
+#ifdef DBG_DUMP
+	lgdt3306a_DumpAllRegs(state);
+#endif
+fail:
+	return ret;
+}
+
+
+static int lgdt3306a_set_vsb(struct lgdt3306a_state *state)
+{
+	u8 val;
+	int ret;
+
+	dbg_info("\n");
+
+	/* 0. Spectrum inversion detection manual; spectrum inverted */
+	ret = lgdt3306a_read_reg(state, 0x0002, &val);
+	val &= 0xf7; /* SPECINVAUTO Off */
+	val |= 0x04; /* SPECINV On */
+	ret = lgdt3306a_write_reg(state, 0x0002, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 1. Selection of standard mode(0x08=QAM, 0x80=VSB) */
+	ret = lgdt3306a_write_reg(state, 0x0008, 0x80);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 2. Bandwidth mode for VSB(6MHz) */
+	ret = lgdt3306a_read_reg(state, 0x0009, &val);
+	val &= 0xe3;
+	val |= 0x0c; /* STDOPDETTMODE[2:0]=3 */
+	ret = lgdt3306a_write_reg(state, 0x0009, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 3. QAM mode detection mode(None) */
+	ret = lgdt3306a_read_reg(state, 0x0009, &val);
+	val &= 0xfc; /* STDOPDETCMODE[1:0]=0 */
+	ret = lgdt3306a_write_reg(state, 0x0009, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 4. ADC sampling frequency rate(2x sampling) */
+	ret = lgdt3306a_read_reg(state, 0x000d, &val);
+	val &= 0xbf; /* SAMPLING4XFEN=0 */
+	ret = lgdt3306a_write_reg(state, 0x000d, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+#if 0
+	/* FGR - disable any AICC filtering, testing only */
+
+	ret = lgdt3306a_write_reg(state, 0x0024, 0x00);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* AICCFIXFREQ0 NT N-1(Video rejection) */
+	ret = lgdt3306a_write_reg(state, 0x002e, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x002f, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x0030, 0x00);
+
+	/* AICCFIXFREQ1 NT N-1(Audio rejection) */
+	ret = lgdt3306a_write_reg(state, 0x002b, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x002c, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x002d, 0x00);
+
+	/* AICCFIXFREQ2 NT Co-Channel(Video rejection) */
+	ret = lgdt3306a_write_reg(state, 0x0028, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x0029, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x002a, 0x00);
+
+	/* AICCFIXFREQ3 NT Co-Channel(Audio rejection) */
+	ret = lgdt3306a_write_reg(state, 0x0025, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x0026, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x0027, 0x00);
+
+#else
+	/* FGR - this works well for HVR-1955,1975 */
+
+	/* 5. AICCOPMODE  NT N-1 Adj. */
+	ret = lgdt3306a_write_reg(state, 0x0024, 0x5A);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* AICCFIXFREQ0 NT N-1(Video rejection) */
+	ret = lgdt3306a_write_reg(state, 0x002e, 0x5A);
+	ret = lgdt3306a_write_reg(state, 0x002f, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x0030, 0x00);
+
+	/* AICCFIXFREQ1 NT N-1(Audio rejection) */
+	ret = lgdt3306a_write_reg(state, 0x002b, 0x36);
+	ret = lgdt3306a_write_reg(state, 0x002c, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x002d, 0x00);
+
+	/* AICCFIXFREQ2 NT Co-Channel(Video rejection) */
+	ret = lgdt3306a_write_reg(state, 0x0028, 0x2A);
+	ret = lgdt3306a_write_reg(state, 0x0029, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x002a, 0x00);
+
+	/* AICCFIXFREQ3 NT Co-Channel(Audio rejection) */
+	ret = lgdt3306a_write_reg(state, 0x0025, 0x06);
+	ret = lgdt3306a_write_reg(state, 0x0026, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x0027, 0x00);
+#endif
+
+	ret = lgdt3306a_read_reg(state, 0x001e, &val);
+	val &= 0x0f;
+	val |= 0xa0;
+	ret = lgdt3306a_write_reg(state, 0x001e, val);
+
+	ret = lgdt3306a_write_reg(state, 0x0022, 0x08);
+
+	ret = lgdt3306a_write_reg(state, 0x0023, 0xFF);
+
+	ret = lgdt3306a_read_reg(state, 0x211f, &val);
+	val &= 0xef;
+	ret = lgdt3306a_write_reg(state, 0x211f, val);
+
+	ret = lgdt3306a_write_reg(state, 0x2173, 0x01);
+
+	ret = lgdt3306a_read_reg(state, 0x1061, &val);
+	val &= 0xf8;
+	val |= 0x04;
+	ret = lgdt3306a_write_reg(state, 0x1061, val);
+
+	ret = lgdt3306a_read_reg(state, 0x103d, &val);
+	val &= 0xcf;
+	ret = lgdt3306a_write_reg(state, 0x103d, val);
+
+	ret = lgdt3306a_write_reg(state, 0x2122, 0x40);
+
+	ret = lgdt3306a_read_reg(state, 0x2141, &val);
+	val &= 0x3f;
+	ret = lgdt3306a_write_reg(state, 0x2141, val);
+
+	ret = lgdt3306a_read_reg(state, 0x2135, &val);
+	val &= 0x0f;
+	val |= 0x70;
+	ret = lgdt3306a_write_reg(state, 0x2135, val);
+
+	ret = lgdt3306a_read_reg(state, 0x0003, &val);
+	val &= 0xf7;
+	ret = lgdt3306a_write_reg(state, 0x0003, val);
+
+	ret = lgdt3306a_read_reg(state, 0x001c, &val);
+	val &= 0x7f;
+	ret = lgdt3306a_write_reg(state, 0x001c, val);
+
+	/* 6. EQ step size */
+	ret = lgdt3306a_read_reg(state, 0x2179, &val);
+	val &= 0xf8;
+	ret = lgdt3306a_write_reg(state, 0x2179, val);
+
+	ret = lgdt3306a_read_reg(state, 0x217a, &val);
+	val &= 0xf8;
+	ret = lgdt3306a_write_reg(state, 0x217a, val);
+
+	/* 7. Reset */
+	ret = lgdt3306a_soft_reset(state);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	dbg_info("complete\n");
+fail:
+	return ret;
+}
+
+static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
+{
+	u8 val;
+	int ret;
+
+	dbg_info("modulation=%d\n", modulation);
+
+	/* 1. Selection of standard mode(0x08=QAM, 0x80=VSB) */
+	ret = lgdt3306a_write_reg(state, 0x0008, 0x08);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 1a. Spectrum inversion detection to Auto */
+	ret = lgdt3306a_read_reg(state, 0x0002, &val);
+	val &= 0xfb; /* SPECINV Off */
+	val |= 0x08; /* SPECINVAUTO On */
+	ret = lgdt3306a_write_reg(state, 0x0002, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 2. Bandwidth mode for QAM */
+	ret = lgdt3306a_read_reg(state, 0x0009, &val);
+	val &= 0xe3; /* STDOPDETTMODE[2:0]=0 VSB Off */
+	ret = lgdt3306a_write_reg(state, 0x0009, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 3. : 64QAM/256QAM detection(manual, auto) */
+	ret = lgdt3306a_read_reg(state, 0x0009, &val);
+	val &= 0xfc;
+	val |= 0x02; /* STDOPDETCMODE[1:0]=1=Manual 2=Auto */
+	ret = lgdt3306a_write_reg(state, 0x0009, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 3a. : 64QAM/256QAM selection for manual */
+	ret = lgdt3306a_read_reg(state, 0x101a, &val);
+	val &= 0xf8;
+	if (modulation == QAM_64)
+		val |= 0x02; /* QMDQMODE[2:0]=2=QAM64 */
+	else
+		val |= 0x04; /* QMDQMODE[2:0]=4=QAM256 */
+
+	ret = lgdt3306a_write_reg(state, 0x101a, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 4. ADC sampling frequency rate(4x sampling) */
+	ret = lgdt3306a_read_reg(state, 0x000d, &val);
+	val &= 0xbf;
+	val |= 0x40; /* SAMPLING4XFEN=1 */
+	ret = lgdt3306a_write_reg(state, 0x000d, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 5. No AICC operation in QAM mode */
+	ret = lgdt3306a_read_reg(state, 0x0024, &val);
+	val &= 0x00;
+	ret = lgdt3306a_write_reg(state, 0x0024, val);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 6. Reset */
+	ret = lgdt3306a_soft_reset(state);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	dbg_info("complete\n");
+fail:
+	return ret;
+}
+
+static int lgdt3306a_set_modulation(struct lgdt3306a_state *state,
+				   struct dtv_frontend_properties *p)
+{
+	int ret;
+
+	dbg_info("\n");
+
+	switch (p->modulation) {
+	case VSB_8:
+		ret = lgdt3306a_set_vsb(state);
+		break;
+	case QAM_64:
+		ret = lgdt3306a_set_qam(state, QAM_64);
+		break;
+	case QAM_256:
+		ret = lgdt3306a_set_qam(state, QAM_256);
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (lg_chkerr(ret))
+		goto fail;
+
+	state->current_modulation = p->modulation;
+
+fail:
+	return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3306a_agc_setup(struct lgdt3306a_state *state,
+			      struct dtv_frontend_properties *p)
+{
+	/* TODO: anything we want to do here??? */
+	dbg_info("\n");
+
+	switch (p->modulation) {
+	case VSB_8:
+		break;
+	case QAM_64:
+	case QAM_256:
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3306a_set_inversion(struct lgdt3306a_state *state,
+				       int inversion)
+{
+	int ret;
+
+	dbg_info("(%d)\n", inversion);
+
+	ret = lgdt3306a_set_reg_bit(state, 0x0002, 2, inversion ? 1 : 0);
+	return ret;
+}
+
+static int lgdt3306a_set_inversion_auto(struct lgdt3306a_state *state,
+				       int enabled)
+{
+	int ret;
+
+	dbg_info("(%d)\n", enabled);
+
+	/* 0=Manual 1=Auto(QAM only) - SPECINVAUTO=0x04 */
+	ret = lgdt3306a_set_reg_bit(state, 0x0002, 3, enabled);
+	return ret;
+}
+
+static int lgdt3306a_spectral_inversion(struct lgdt3306a_state *state,
+				       struct dtv_frontend_properties *p,
+				       int inversion)
+{
+	int ret = 0;
+
+	dbg_info("(%d)\n", inversion);
+#if 0
+	/*
+	 * FGR - spectral_inversion defaults already set for VSB and QAM;
+	 * can enable later if desired
+	 */
+
+	ret = lgdt3306a_set_inversion(state, inversion);
+
+	switch (p->modulation) {
+	case VSB_8:
+		/* Manual only for VSB */
+		ret = lgdt3306a_set_inversion_auto(state, 0);
+		break;
+	case QAM_64:
+	case QAM_256:
+		/* Auto ok for QAM */
+		ret = lgdt3306a_set_inversion_auto(state, 1);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+#endif
+	return ret;
+}
+
+static int lgdt3306a_set_if(struct lgdt3306a_state *state,
+			   struct dtv_frontend_properties *p)
+{
+	int ret;
+	u16 if_freq_khz;
+	u8 nco1, nco2;
+
+	switch (p->modulation) {
+	case VSB_8:
+		if_freq_khz = state->cfg->vsb_if_khz;
+		break;
+	case QAM_64:
+	case QAM_256:
+		if_freq_khz = state->cfg->qam_if_khz;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (if_freq_khz) {
+	default:
+		pr_warn("IF=%d KHz is not supportted, 3250 assumed\n",
+			if_freq_khz);
+		/* fallthrough */
+	case 3250: /* 3.25Mhz */
+		nco1 = 0x34;
+		nco2 = 0x00;
+		break;
+	case 3500: /* 3.50Mhz */
+		nco1 = 0x38;
+		nco2 = 0x00;
+		break;
+	case 4000: /* 4.00Mhz */
+		nco1 = 0x40;
+		nco2 = 0x00;
+		break;
+	case 5000: /* 5.00Mhz */
+		nco1 = 0x50;
+		nco2 = 0x00;
+		break;
+	case 5380: /* 5.38Mhz */
+		nco1 = 0x56;
+		nco2 = 0x14;
+		break;
+	}
+	ret = lgdt3306a_write_reg(state, 0x0010, nco1);
+	if (ret)
+		return ret;
+	ret = lgdt3306a_write_reg(state, 0x0011, nco2);
+	if (ret)
+		return ret;
+
+	dbg_info("if_freq=%d KHz->[%04x]\n", if_freq_khz, nco1<<8 | nco2);
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3306a_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+
+	if (state->cfg->deny_i2c_rptr) {
+		dbg_info("deny_i2c_rptr=%d\n", state->cfg->deny_i2c_rptr);
+		return 0;
+	}
+	dbg_info("(%d)\n", enable);
+
+	/* NI2CRPTEN=0x80 */
+	return lgdt3306a_set_reg_bit(state, 0x0002, 7, enable ? 0 : 1);
+}
+
+static int lgdt3306a_sleep(struct lgdt3306a_state *state)
+{
+	int ret;
+
+	dbg_info("\n");
+	state->current_frequency = -1; /* force re-tune, when we wake */
+
+	ret = lgdt3306a_mpeg_tristate(state, 1); /* disable data bus */
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_power(state, 0); /* power down */
+	lg_chkerr(ret);
+
+fail:
+	return 0;
+}
+
+static int lgdt3306a_fe_sleep(struct dvb_frontend *fe)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+
+	return lgdt3306a_sleep(state);
+}
+
+static int lgdt3306a_init(struct dvb_frontend *fe)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+	u8 val;
+	int ret;
+
+	dbg_info("\n");
+
+	/* 1. Normal operation mode */
+	ret = lgdt3306a_set_reg_bit(state, 0x0001, 0, 1); /* SIMFASTENB=0x01 */
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 2. Spectrum inversion auto detection (Not valid for VSB) */
+	ret = lgdt3306a_set_inversion_auto(state, 0);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 3. Spectrum inversion(According to the tuner configuration) */
+	ret = lgdt3306a_set_inversion(state, 1);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 4. Peak-to-peak voltage of ADC input signal */
+
+	/* ADCSEL1V=0x80=1Vpp; 0x00=2Vpp */
+	ret = lgdt3306a_set_reg_bit(state, 0x0004, 7, 1);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 5. ADC output data capture clock phase */
+
+	/* 0=same phase as ADC clock */
+	ret = lgdt3306a_set_reg_bit(state, 0x0004, 2, 0);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 5a. ADC sampling clock source */
+
+	/* ADCCLKPLLSEL=0x08; 0=use ext clock, not PLL */
+	ret = lgdt3306a_set_reg_bit(state, 0x0004, 3, 0);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	/* 6. Automatic PLL set */
+
+	/* PLLSETAUTO=0x40; 0=off */
+	ret = lgdt3306a_set_reg_bit(state, 0x0005, 6, 0);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	if (state->cfg->xtalMHz == 24) {	/* 24MHz */
+		/* 7. Frequency for PLL output(0x2564 for 192MHz for 24MHz) */
+		ret = lgdt3306a_read_reg(state, 0x0005, &val);
+		if (lg_chkerr(ret))
+			goto fail;
+		val &= 0xc0;
+		val |= 0x25;
+		ret = lgdt3306a_write_reg(state, 0x0005, val);
+		if (lg_chkerr(ret))
+			goto fail;
+		ret = lgdt3306a_write_reg(state, 0x0006, 0x64);
+		if (lg_chkerr(ret))
+			goto fail;
+
+		/* 8. ADC sampling frequency(0x180000 for 24MHz sampling) */
+		ret = lgdt3306a_read_reg(state, 0x000d, &val);
+		if (lg_chkerr(ret))
+			goto fail;
+		val &= 0xc0;
+		val |= 0x18;
+		ret = lgdt3306a_write_reg(state, 0x000d, val);
+		if (lg_chkerr(ret))
+			goto fail;
+
+	} else if (state->cfg->xtalMHz == 25) { /* 25MHz */
+		/* 7. Frequency for PLL output */
+		ret = lgdt3306a_read_reg(state, 0x0005, &val);
+		if (lg_chkerr(ret))
+			goto fail;
+		val &= 0xc0;
+		val |= 0x25;
+		ret = lgdt3306a_write_reg(state, 0x0005, val);
+		if (lg_chkerr(ret))
+			goto fail;
+		ret = lgdt3306a_write_reg(state, 0x0006, 0x64);
+		if (lg_chkerr(ret))
+			goto fail;
+
+		/* 8. ADC sampling frequency(0x190000 for 25MHz sampling) */
+		ret = lgdt3306a_read_reg(state, 0x000d, &val);
+		if (lg_chkerr(ret))
+			goto fail;
+		val &= 0xc0;
+		val |= 0x19;
+		ret = lgdt3306a_write_reg(state, 0x000d, val);
+		if (lg_chkerr(ret))
+			goto fail;
+	} else {
+		pr_err("Bad xtalMHz=%d\n", state->cfg->xtalMHz);
+	}
+#if 0
+	ret = lgdt3306a_write_reg(state, 0x000e, 0x00);
+	ret = lgdt3306a_write_reg(state, 0x000f, 0x00);
+#endif
+
+	/* 9. Center frequency of input signal of ADC */
+	ret = lgdt3306a_write_reg(state, 0x0010, 0x34); /* 3.25MHz */
+	ret = lgdt3306a_write_reg(state, 0x0011, 0x00);
+
+	/* 10. Fixed gain error value */
+	ret = lgdt3306a_write_reg(state, 0x0014, 0); /* gain error=0 */
+
+	/* 10a. VSB TR BW gear shift initial step */
+	ret = lgdt3306a_read_reg(state, 0x103c, &val);
+	val &= 0x0f;
+	val |= 0x20; /* SAMGSAUTOSTL_V[3:0] = 2 */
+	ret = lgdt3306a_write_reg(state, 0x103c, val);
+
+	/* 10b. Timing offset calibration in low temperature for VSB */
+	ret = lgdt3306a_read_reg(state, 0x103d, &val);
+	val &= 0xfc;
+	val |= 0x03;
+	ret = lgdt3306a_write_reg(state, 0x103d, val);
+
+	/* 10c. Timing offset calibration in low temperature for QAM */
+	ret = lgdt3306a_read_reg(state, 0x1036, &val);
+	val &= 0xf0;
+	val |= 0x0c;
+	ret = lgdt3306a_write_reg(state, 0x1036, val);
+
+	/* 11. Using the imaginary part of CIR in CIR loading */
+	ret = lgdt3306a_read_reg(state, 0x211f, &val);
+	val &= 0xef; /* do not use imaginary of CIR */
+	ret = lgdt3306a_write_reg(state, 0x211f, val);
+
+	/* 12. Control of no signal detector function */
+	ret = lgdt3306a_read_reg(state, 0x2849, &val);
+	val &= 0xef; /* NOUSENOSIGDET=0, enable no signal detector */
+	ret = lgdt3306a_write_reg(state, 0x2849, val);
+
+	/* FGR - put demod in some known mode */
+	ret = lgdt3306a_set_vsb(state);
+
+	/* 13. TP stream format */
+	ret = lgdt3306a_mpeg_mode(state, state->cfg->mpeg_mode);
+
+	/* 14. disable output buses */
+	ret = lgdt3306a_mpeg_tristate(state, 1);
+
+	/* 15. Sleep (in reset) */
+	ret = lgdt3306a_sleep(state);
+	lg_chkerr(ret);
+
+fail:
+	return ret;
+}
+
+static int lgdt3306a_set_parameters(struct dvb_frontend *fe)
+{
+	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+	int ret;
+
+	dbg_info("(%d, %d)\n", p->frequency, p->modulation);
+
+	if (state->current_frequency  == p->frequency &&
+	   state->current_modulation == p->modulation) {
+		dbg_info(" (already set, skipping ...)\n");
+		return 0;
+	}
+	state->current_frequency = -1;
+	state->current_modulation = -1;
+
+	ret = lgdt3306a_power(state, 1); /* power up */
+	if (lg_chkerr(ret))
+		goto fail;
+
+	if (fe->ops.tuner_ops.set_params) {
+		ret = fe->ops.tuner_ops.set_params(fe);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+#if 0
+		if (lg_chkerr(ret))
+			goto fail;
+		state->current_frequency = p->frequency;
+#endif
+	}
+
+	ret = lgdt3306a_set_modulation(state, p);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_agc_setup(state, p);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_set_if(state, p);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_spectral_inversion(state, p,
+					state->cfg->spectral_inversion ? 1 : 0);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_mpeg_mode(state, state->cfg->mpeg_mode);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_mpeg_mode_polarity(state,
+					  state->cfg->tpclk_edge,
+					  state->cfg->tpvalid_polarity);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_mpeg_tristate(state, 0); /* enable data bus */
+	if (lg_chkerr(ret))
+		goto fail;
+
+	ret = lgdt3306a_soft_reset(state);
+	if (lg_chkerr(ret))
+		goto fail;
+
+#ifdef DBG_DUMP
+	lgdt3306a_DumpAllRegs(state);
+#endif
+	state->current_frequency = p->frequency;
+fail:
+	return ret;
+}
+
+static int lgdt3306a_get_frontend(struct dvb_frontend *fe)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+
+	dbg_info("(%u, %d)\n",
+		 state->current_frequency, state->current_modulation);
+
+	p->modulation = state->current_modulation;
+	p->frequency = state->current_frequency;
+	return 0;
+}
+
+static enum dvbfe_algo lgdt3306a_get_frontend_algo(struct dvb_frontend *fe)
+{
+#if 1
+	return DVBFE_ALGO_CUSTOM;
+#else
+	return DVBFE_ALGO_HW;
+#endif
+}
+
+/* ------------------------------------------------------------------------ */
+static int lgdt3306a_monitor_vsb(struct lgdt3306a_state *state)
+{
+	u8 val;
+	int ret;
+	u8 snrRef, maxPowerMan, nCombDet;
+	u16 fbDlyCir;
+
+	ret = lgdt3306a_read_reg(state, 0x21a1, &val);
+	if (ret)
+		return ret;
+	snrRef = val & 0x3f;
+
+	ret = lgdt3306a_read_reg(state, 0x2185, &maxPowerMan);
+	if (ret)
+		return ret;
+
+	ret = lgdt3306a_read_reg(state, 0x2191, &val);
+	if (ret)
+		return ret;
+	nCombDet = (val & 0x80) >> 7;
+
+	ret = lgdt3306a_read_reg(state, 0x2180, &val);
+	if (ret)
+		return ret;
+	fbDlyCir = (val & 0x03) << 8;
+
+	ret = lgdt3306a_read_reg(state, 0x2181, &val);
+	if (ret)
+		return ret;
+	fbDlyCir |= val;
+
+	dbg_info("snrRef=%d maxPowerMan=0x%x nCombDet=%d fbDlyCir=0x%x\n",
+		snrRef, maxPowerMan, nCombDet, fbDlyCir);
+
+	/* Carrier offset sub loop bandwidth */
+	ret = lgdt3306a_read_reg(state, 0x1061, &val);
+	if (ret)
+		return ret;
+	val &= 0xf8;
+	if ((snrRef > 18) && (maxPowerMan > 0x68)
+	    && (nCombDet == 0x01)
+	    && ((fbDlyCir == 0x03FF) || (fbDlyCir < 0x6C))) {
+		/* SNR is over 18dB and no ghosting */
+		val |= 0x00; /* final bandwidth = 0 */
+	} else {
+		val |= 0x04; /* final bandwidth = 4 */
+	}
+	ret = lgdt3306a_write_reg(state, 0x1061, val);
+	if (ret)
+		return ret;
+
+	/* Adjust Notch Filter */
+	ret = lgdt3306a_read_reg(state, 0x0024, &val);
+	if (ret)
+		return ret;
+	val &= 0x0f;
+	if (nCombDet == 0) { /* Turn on the Notch Filter */
+		val |= 0x50;
+	}
+	ret = lgdt3306a_write_reg(state, 0x0024, val);
+	if (ret)
+		return ret;
+
+	/* VSB Timing Recovery output normalization */
+	ret = lgdt3306a_read_reg(state, 0x103d, &val);
+	if (ret)
+		return ret;
+	val &= 0xcf;
+	val |= 0x20;
+	ret = lgdt3306a_write_reg(state, 0x103d, val);
+
+	return ret;
+}
+
+static enum lgdt3306a_modulation
+lgdt3306a_check_oper_mode(struct lgdt3306a_state *state)
+{
+	u8 val = 0;
+	int ret;
+
+	ret = lgdt3306a_read_reg(state, 0x0081, &val);
+	if (ret)
+		goto err;
+
+	if (val & 0x80)	{
+		dbg_info("VSB\n");
+		return LG3306_VSB;
+	}
+	if (val & 0x08) {
+		ret = lgdt3306a_read_reg(state, 0x00a6, &val);
+		if (ret)
+			goto err;
+		val = val >> 2;
+		if (val & 0x01) {
+			dbg_info("QAM256\n");
+			return LG3306_QAM256;
+		}
+		dbg_info("QAM64\n");
+		return LG3306_QAM64;
+	}
+err:
+	pr_warn("UNKNOWN\n");
+	return LG3306_UNKNOWN_MODE;
+}
+
+static enum lgdt3306a_lock_status
+lgdt3306a_check_lock_status(struct lgdt3306a_state *state,
+			    enum lgdt3306a_lock_check whatLock)
+{
+	u8 val = 0;
+	int ret;
+	enum lgdt3306a_modulation	modeOper;
+	enum lgdt3306a_lock_status lockStatus;
+
+	modeOper = LG3306_UNKNOWN_MODE;
+
+	switch (whatLock) {
+	case LG3306_SYNC_LOCK:
+	{
+		ret = lgdt3306a_read_reg(state, 0x00a6, &val);
+		if (ret)
+			return ret;
+
+		if ((val & 0x80) == 0x80)
+			lockStatus = LG3306_LOCK;
+		else
+			lockStatus = LG3306_UNLOCK;
+
+		dbg_info("SYNC_LOCK=%x\n", lockStatus);
+		break;
+	}
+	case LG3306_AGC_LOCK:
+	{
+		ret = lgdt3306a_read_reg(state, 0x0080, &val);
+		if (ret)
+			return ret;
+
+		if ((val & 0x40) == 0x40)
+			lockStatus = LG3306_LOCK;
+		else
+			lockStatus = LG3306_UNLOCK;
+
+		dbg_info("AGC_LOCK=%x\n", lockStatus);
+		break;
+	}
+	case LG3306_TR_LOCK:
+	{
+		modeOper = lgdt3306a_check_oper_mode(state);
+		if ((modeOper == LG3306_QAM64) || (modeOper == LG3306_QAM256)) {
+			ret = lgdt3306a_read_reg(state, 0x1094, &val);
+			if (ret)
+				return ret;
+
+			if ((val & 0x80) == 0x80)
+				lockStatus = LG3306_LOCK;
+			else
+				lockStatus = LG3306_UNLOCK;
+		} else
+			lockStatus = LG3306_UNKNOWN_LOCK;
+
+		dbg_info("TR_LOCK=%x\n", lockStatus);
+		break;
+	}
+	case LG3306_FEC_LOCK:
+	{
+		modeOper = lgdt3306a_check_oper_mode(state);
+		if ((modeOper == LG3306_QAM64) || (modeOper == LG3306_QAM256)) {
+			ret = lgdt3306a_read_reg(state, 0x0080, &val);
+			if (ret)
+				return ret;
+
+			if ((val & 0x10) == 0x10)
+				lockStatus = LG3306_LOCK;
+			else
+				lockStatus = LG3306_UNLOCK;
+		} else
+			lockStatus = LG3306_UNKNOWN_LOCK;
+
+		dbg_info("FEC_LOCK=%x\n", lockStatus);
+		break;
+	}
+
+	default:
+		lockStatus = LG3306_UNKNOWN_LOCK;
+		pr_warn("UNKNOWN whatLock=%d\n", whatLock);
+		break;
+	}
+
+	return lockStatus;
+}
+
+static enum lgdt3306a_neverlock_status
+lgdt3306a_check_neverlock_status(struct lgdt3306a_state *state)
+{
+	u8 val = 0;
+	int ret;
+	enum lgdt3306a_neverlock_status lockStatus;
+
+	ret = lgdt3306a_read_reg(state, 0x0080, &val);
+	if (ret)
+		return ret;
+	lockStatus = (enum lgdt3306a_neverlock_status)(val & 0x03);
+
+	dbg_info("NeverLock=%d", lockStatus);
+
+	return lockStatus;
+}
+
+static int lgdt3306a_pre_monitoring(struct lgdt3306a_state *state)
+{
+	u8 val = 0;
+	int ret;
+	u8 currChDiffACQ, snrRef, mainStrong, aiccrejStatus;
+
+	/* Channel variation */
+	ret = lgdt3306a_read_reg(state, 0x21bc, &currChDiffACQ);
+	if (ret)
+		return ret;
+
+	/* SNR of Frame sync */
+	ret = lgdt3306a_read_reg(state, 0x21a1, &val);
+	if (ret)
+		return ret;
+	snrRef = val & 0x3f;
+
+	/* Strong Main CIR */
+	ret = lgdt3306a_read_reg(state, 0x2199, &val);
+	if (ret)
+		return ret;
+	mainStrong = (val & 0x40) >> 6;
+
+	ret = lgdt3306a_read_reg(state, 0x0090, &val);
+	if (ret)
+		return ret;
+	aiccrejStatus = (val & 0xf0) >> 4;
+
+	dbg_info("snrRef=%d mainStrong=%d aiccrejStatus=%d currChDiffACQ=0x%x\n",
+		snrRef, mainStrong, aiccrejStatus, currChDiffACQ);
+
+#if 0
+	/* Dynamic ghost exists */
+	if ((mainStrong == 0) && (currChDiffACQ > 0x70))
+#endif
+	if (mainStrong == 0) {
+		ret = lgdt3306a_read_reg(state, 0x2135, &val);
+		if (ret)
+			return ret;
+		val &= 0x0f;
+		val |= 0xa0;
+		ret = lgdt3306a_write_reg(state, 0x2135, val);
+		if (ret)
+			return ret;
+
+		ret = lgdt3306a_read_reg(state, 0x2141, &val);
+		if (ret)
+			return ret;
+		val &= 0x3f;
+		val |= 0x80;
+		ret = lgdt3306a_write_reg(state, 0x2141, val);
+		if (ret)
+			return ret;
+
+		ret = lgdt3306a_write_reg(state, 0x2122, 0x70);
+		if (ret)
+			return ret;
+	} else { /* Weak ghost or static channel */
+		ret = lgdt3306a_read_reg(state, 0x2135, &val);
+		if (ret)
+			return ret;
+		val &= 0x0f;
+		val |= 0x70;
+		ret = lgdt3306a_write_reg(state, 0x2135, val);
+		if (ret)
+			return ret;
+
+		ret = lgdt3306a_read_reg(state, 0x2141, &val);
+		if (ret)
+			return ret;
+		val &= 0x3f;
+		val |= 0x40;
+		ret = lgdt3306a_write_reg(state, 0x2141, val);
+		if (ret)
+			return ret;
+
+		ret = lgdt3306a_write_reg(state, 0x2122, 0x40);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static enum lgdt3306a_lock_status
+lgdt3306a_sync_lock_poll(struct lgdt3306a_state *state)
+{
+	enum lgdt3306a_lock_status syncLockStatus = LG3306_UNLOCK;
+	int	i;
+
+	for (i = 0; i < 2; i++)	{
+		msleep(30);
+
+		syncLockStatus = lgdt3306a_check_lock_status(state,
+							     LG3306_SYNC_LOCK);
+
+		if (syncLockStatus == LG3306_LOCK) {
+			dbg_info("locked(%d)\n", i);
+			return LG3306_LOCK;
+		}
+	}
+	dbg_info("not locked\n");
+	return LG3306_UNLOCK;
+}
+
+static enum lgdt3306a_lock_status
+lgdt3306a_fec_lock_poll(struct lgdt3306a_state *state)
+{
+	enum lgdt3306a_lock_status FECLockStatus = LG3306_UNLOCK;
+	int	i;
+
+	for (i = 0; i < 2; i++)	{
+		msleep(30);
+
+		FECLockStatus = lgdt3306a_check_lock_status(state,
+							    LG3306_FEC_LOCK);
+
+		if (FECLockStatus == LG3306_LOCK) {
+			dbg_info("locked(%d)\n", i);
+			return FECLockStatus;
+		}
+	}
+	dbg_info("not locked\n");
+	return FECLockStatus;
+}
+
+static enum lgdt3306a_neverlock_status
+lgdt3306a_neverlock_poll(struct lgdt3306a_state *state)
+{
+	enum lgdt3306a_neverlock_status NLLockStatus = LG3306_NL_FAIL;
+	int	i;
+
+	for (i = 0; i < 5; i++) {
+		msleep(30);
+
+		NLLockStatus = lgdt3306a_check_neverlock_status(state);
+
+		if (NLLockStatus == LG3306_NL_LOCK) {
+			dbg_info("NL_LOCK(%d)\n", i);
+			return NLLockStatus;
+		}
+	}
+	dbg_info("NLLockStatus=%d\n", NLLockStatus);
+	return NLLockStatus;
+}
+
+static u8 lgdt3306a_get_packet_error(struct lgdt3306a_state *state)
+{
+	u8 val;
+	int ret;
+
+	ret = lgdt3306a_read_reg(state, 0x00fa, &val);
+	if (ret)
+		return ret;
+
+	return val;
+}
+
+static const u32 valx_x10[] = {
+	10,  11,  13,  15,  17,  20,  25,  33,  41,  50,  59,  73,  87,  100
+};
+static const u32 log10x_x1000[] = {
+	0,   41, 114, 176, 230, 301, 398, 518, 613, 699, 771, 863, 939, 1000
+};
+
+static u32 log10_x1000(u32 x)
+{
+	u32 diff_val, step_val, step_log10;
+	u32 log_val = 0;
+	u32 i;
+
+	if (x <= 0)
+		return -1000000; /* signal error */
+
+	if (x == 10)
+		return 0; /* log(1)=0 */
+
+	if (x < 10) {
+		while (x < 10) {
+			x = x * 10;
+			log_val--;
+		}
+	} else {	/* x > 10 */
+		while (x >= 100) {
+			x = x / 10;
+			log_val++;
+		}
+	}
+	log_val *= 1000;
+
+	if (x == 10) /* was our input an exact multiple of 10 */
+		return log_val;	/* don't need to interpolate */
+
+	/* find our place on the log curve */
+	for (i = 1; i < ARRAY_SIZE(valx_x10); i++) {
+		if (valx_x10[i] >= x)
+			break;
+	}
+	if (i == ARRAY_SIZE(valx_x10))
+		return log_val + log10x_x1000[i - 1];
+
+	diff_val   = x - valx_x10[i-1];
+	step_val   = valx_x10[i] - valx_x10[i - 1];
+	step_log10 = log10x_x1000[i] - log10x_x1000[i - 1];
+
+	/* do a linear interpolation to get in-between values */
+	return log_val + log10x_x1000[i - 1] +
+		((diff_val*step_log10) / step_val);
+}
+
+static u32 lgdt3306a_calculate_snr_x100(struct lgdt3306a_state *state)
+{
+	u32 mse; /* Mean-Square Error */
+	u32 pwr; /* Constelation power */
+	u32 snr_x100;
+
+	mse = (read_reg(state, 0x00ec) << 8) |
+	      (read_reg(state, 0x00ed));
+	pwr = (read_reg(state, 0x00e8) << 8) |
+	      (read_reg(state, 0x00e9));
+
+	if (mse == 0) /* no signal */
+		return 0;
+
+	snr_x100 = log10_x1000((pwr * 10000) / mse) - 3000;
+	dbg_info("mse=%u, pwr=%u, snr_x100=%d\n", mse, pwr, snr_x100);
+
+	return snr_x100;
+}
+
+static enum lgdt3306a_lock_status
+lgdt3306a_vsb_lock_poll(struct lgdt3306a_state *state)
+{
+	int ret;
+	u8 cnt = 0;
+	u8 packet_error;
+	u32 snr;
+
+	for (cnt = 0; cnt < 10; cnt++) {
+		if (lgdt3306a_sync_lock_poll(state) == LG3306_UNLOCK) {
+			dbg_info("no sync lock!\n");
+			return LG3306_UNLOCK;
+		}
+
+		msleep(20);
+		ret = lgdt3306a_pre_monitoring(state);
+		if (ret)
+			break;
+
+		packet_error = lgdt3306a_get_packet_error(state);
+		snr = lgdt3306a_calculate_snr_x100(state);
+		dbg_info("cnt=%d errors=%d snr=%d\n", cnt, packet_error, snr);
+
+		if ((snr >= 1500) && (packet_error < 0xff))
+			return LG3306_LOCK;
+	}
+
+	dbg_info("not locked!\n");
+	return LG3306_UNLOCK;
+}
+
+static enum lgdt3306a_lock_status
+lgdt3306a_qam_lock_poll(struct lgdt3306a_state *state)
+{
+	u8 cnt;
+	u8 packet_error;
+	u32	snr;
+
+	for (cnt = 0; cnt < 10; cnt++) {
+		if (lgdt3306a_fec_lock_poll(state) == LG3306_UNLOCK) {
+			dbg_info("no fec lock!\n");
+			return LG3306_UNLOCK;
+		}
+
+		msleep(20);
+
+		packet_error = lgdt3306a_get_packet_error(state);
+		snr = lgdt3306a_calculate_snr_x100(state);
+		dbg_info("cnt=%d errors=%d snr=%d\n", cnt, packet_error, snr);
+
+		if ((snr >= 1500) && (packet_error < 0xff))
+			return LG3306_LOCK;
+	}
+
+	dbg_info("not locked!\n");
+	return LG3306_UNLOCK;
+}
+
+static int lgdt3306a_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+	u16 strength = 0;
+	int ret = 0;
+
+	if (fe->ops.tuner_ops.get_rf_strength) {
+		ret = fe->ops.tuner_ops.get_rf_strength(fe, &strength);
+		if (ret == 0)
+			dbg_info("strength=%d\n", strength);
+		else
+			dbg_info("fe->ops.tuner_ops.get_rf_strength() failed\n");
+	}
+
+	*status = 0;
+	if (lgdt3306a_neverlock_poll(state) == LG3306_NL_LOCK) {
+		*status |= FE_HAS_SIGNAL;
+		*status |= FE_HAS_CARRIER;
+
+		switch (state->current_modulation) {
+		case QAM_256:
+		case QAM_64:
+			if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) {
+				*status |= FE_HAS_VITERBI;
+				*status |= FE_HAS_SYNC;
+
+				*status |= FE_HAS_LOCK;
+			}
+			break;
+		case VSB_8:
+			if (lgdt3306a_vsb_lock_poll(state) == LG3306_LOCK) {
+				*status |= FE_HAS_VITERBI;
+				*status |= FE_HAS_SYNC;
+
+				*status |= FE_HAS_LOCK;
+
+				ret = lgdt3306a_monitor_vsb(state);
+			}
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	}
+	return ret;
+}
+
+
+static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+
+	state->snr = lgdt3306a_calculate_snr_x100(state);
+	/* report SNR in dB * 10 */
+	*snr = state->snr/10;
+
+	return 0;
+}
+
+static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe,
+					 u16 *strength)
+{
+	/*
+	 * Calculate some sort of "strength" from SNR
+	 */
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+	u16 snr; /* snr_x10 */
+	int ret;
+	u32 ref_snr; /* snr*100 */
+	u32 str;
+
+	*strength = 0;
+
+	switch (state->current_modulation) {
+	case VSB_8:
+		 ref_snr = 1600; /* 16dB */
+		 break;
+	case QAM_64:
+		 ref_snr = 2200; /* 22dB */
+		 break;
+	case QAM_256:
+		 ref_snr = 2800; /* 28dB */
+		 break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = fe->ops.read_snr(fe, &snr);
+	if (lg_chkerr(ret))
+		goto fail;
+
+	if (state->snr <= (ref_snr - 100))
+		str = 0;
+	else if (state->snr <= ref_snr)
+		str = (0xffff * 65) / 100; /* 65% */
+	else {
+		str = state->snr - ref_snr;
+		str /= 50;
+		str += 78; /* 78%-100% */
+		if (str > 100)
+			str = 100;
+		str = (0xffff * str) / 100;
+	}
+	*strength = (u16)str;
+	dbg_info("strength=%u\n", *strength);
+
+fail:
+	return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3306a_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+	u32 tmp;
+
+	*ber = 0;
+#if 1
+	/* FGR - FIXME - I don't know what value is expected by dvb_core
+	 * what is the scale of the value?? */
+	tmp =              read_reg(state, 0x00fc); /* NBERVALUE[24-31] */
+	tmp = (tmp << 8) | read_reg(state, 0x00fd); /* NBERVALUE[16-23] */
+	tmp = (tmp << 8) | read_reg(state, 0x00fe); /* NBERVALUE[8-15] */
+	tmp = (tmp << 8) | read_reg(state, 0x00ff); /* NBERVALUE[0-7] */
+	*ber = tmp;
+	dbg_info("ber=%u\n", tmp);
+#endif
+	return 0;
+}
+
+static int lgdt3306a_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+
+	*ucblocks = 0;
+#if 1
+	/* FGR - FIXME - I don't know what value is expected by dvb_core
+	 * what happens when value wraps? */
+	*ucblocks = read_reg(state, 0x00f4); /* TPIFTPERRCNT[0-7] */
+	dbg_info("ucblocks=%u\n", *ucblocks);
+#endif
+
+	return 0;
+}
+
+static int lgdt3306a_tune(struct dvb_frontend *fe, bool re_tune,
+			  unsigned int mode_flags, unsigned int *delay,
+			  fe_status_t *status)
+{
+	int ret = 0;
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+
+	dbg_info("re_tune=%u\n", re_tune);
+
+	if (re_tune) {
+		state->current_frequency = -1; /* force re-tune */
+		ret = lgdt3306a_set_parameters(fe);
+		if (ret != 0)
+			return ret;
+	}
+	*delay = 125;
+	ret = lgdt3306a_read_status(fe, status);
+
+	return ret;
+}
+
+static int lgdt3306a_get_tune_settings(struct dvb_frontend *fe,
+				       struct dvb_frontend_tune_settings
+				       *fe_tune_settings)
+{
+	fe_tune_settings->min_delay_ms = 100;
+	dbg_info("\n");
+	return 0;
+}
+
+static int lgdt3306a_search(struct dvb_frontend *fe)
+{
+	fe_status_t status = 0;
+	int i, ret;
+
+	/* set frontend */
+	ret = lgdt3306a_set_parameters(fe);
+	if (ret)
+		goto error;
+
+	/* wait frontend lock */
+	for (i = 20; i > 0; i--) {
+		dbg_info(": loop=%d\n", i);
+		msleep(50);
+		ret = lgdt3306a_read_status(fe, &status);
+		if (ret)
+			goto error;
+
+		if (status & FE_HAS_LOCK)
+			break;
+	}
+
+	/* check if we have a valid signal */
+	if (status & FE_HAS_LOCK)
+		return DVBFE_ALGO_SEARCH_SUCCESS;
+	else
+		return DVBFE_ALGO_SEARCH_AGAIN;
+
+error:
+	dbg_info("failed (%d)\n", ret);
+	return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static void lgdt3306a_release(struct dvb_frontend *fe)
+{
+	struct lgdt3306a_state *state = fe->demodulator_priv;
+
+	dbg_info("\n");
+	kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3306a_ops;
+
+struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config,
+				      struct i2c_adapter *i2c_adap)
+{
+	struct lgdt3306a_state *state = NULL;
+	int ret;
+	u8 val;
+
+	dbg_info("(%d-%04x)\n",
+	       i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
+	       config ? config->i2c_addr : 0);
+
+	state = kzalloc(sizeof(struct lgdt3306a_state), GFP_KERNEL);
+	if (state == NULL)
+		goto fail;
+
+	state->cfg = config;
+	state->i2c_adap = i2c_adap;
+
+	memcpy(&state->frontend.ops, &lgdt3306a_ops,
+	       sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+
+	/* verify that we're talking to a lg3306a */
+	/* FGR - NOTE - there is no obvious ChipId to check; we check
+	 * some "known" bits after reset, but it's still just a guess */
+	ret = lgdt3306a_read_reg(state, 0x0000, &val);
+	if (lg_chkerr(ret))
+		goto fail;
+	if ((val & 0x74) != 0x74) {
+		pr_warn("expected 0x74, got 0x%x\n", (val & 0x74));
+#if 0
+		/* FIXME - re-enable when we know this is right */
+		goto fail;
+#endif
+	}
+	ret = lgdt3306a_read_reg(state, 0x0001, &val);
+	if (lg_chkerr(ret))
+		goto fail;
+	if ((val & 0xf6) != 0xc6) {
+		pr_warn("expected 0xc6, got 0x%x\n", (val & 0xf6));
+#if 0
+		/* FIXME - re-enable when we know this is right */
+		goto fail;
+#endif
+	}
+	ret = lgdt3306a_read_reg(state, 0x0002, &val);
+	if (lg_chkerr(ret))
+		goto fail;
+	if ((val & 0x73) != 0x03) {
+		pr_warn("expected 0x03, got 0x%x\n", (val & 0x73));
+#if 0
+		/* FIXME - re-enable when we know this is right */
+		goto fail;
+#endif
+	}
+
+	state->current_frequency = -1;
+	state->current_modulation = -1;
+
+	lgdt3306a_sleep(state);
+
+	return &state->frontend;
+
+fail:
+	pr_warn("unable to detect LGDT3306A hardware\n");
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(lgdt3306a_attach);
+
+#ifdef DBG_DUMP
+
+static const short regtab[] = {
+	0x0000, /* SOFTRSTB 1'b1 1'b1 1'b1 ADCPDB 1'b1 PLLPDB GBBPDB 11111111 */
+	0x0001, /* 1'b1 1'b1 1'b0 1'b0 AUTORPTRS */
+	0x0002, /* NI2CRPTEN 1'b0 1'b0 1'b0 SPECINVAUT */
+	0x0003, /* AGCRFOUT */
+	0x0004, /* ADCSEL1V ADCCNT ADCCNF ADCCNS ADCCLKPLL */
+	0x0005, /* PLLINDIVSE */
+	0x0006, /* PLLCTRL[7:0] 11100001 */
+	0x0007, /* SYSINITWAITTIME[7:0] (msec) 00001000 */
+	0x0008, /* STDOPMODE[7:0] 10000000 */
+	0x0009, /* 1'b0 1'b0 1'b0 STDOPDETTMODE[2:0] STDOPDETCMODE[1:0] 00011110 */
+	0x000a, /* DAFTEN 1'b1 x x SCSYSLOCK */
+	0x000b, /* SCSYSLOCKCHKTIME[7:0] (10msec) 01100100 */
+	0x000d, /* x SAMPLING4 */
+	0x000e, /* SAMFREQ[15:8] 00000000 */
+	0x000f, /* SAMFREQ[7:0] 00000000 */
+	0x0010, /* IFFREQ[15:8] 01100000 */
+	0x0011, /* IFFREQ[7:0] 00000000 */
+	0x0012, /* AGCEN AGCREFMO */
+	0x0013, /* AGCRFFIXB AGCIFFIXB AGCLOCKDETRNGSEL[1:0] 1'b1 1'b0 1'b0 1'b0 11101000 */
+	0x0014, /* AGCFIXVALUE[7:0] 01111111 */
+	0x0015, /* AGCREF[15:8] 00001010 */
+	0x0016, /* AGCREF[7:0] 11100100 */
+	0x0017, /* AGCDELAY[7:0] 00100000 */
+	0x0018, /* AGCRFBW[3:0] AGCIFBW[3:0] 10001000 */
+	0x0019, /* AGCUDOUTMODE[1:0] AGCUDCTRLLEN[1:0] AGCUDCTRL */
+	0x001c, /* 1'b1 PFEN MFEN AICCVSYNC */
+	0x001d, /* 1'b0 1'b1 1'b0 1'b1 AICCVSYNC */
+	0x001e, /* AICCALPHA[3:0] 1'b1 1'b0 1'b1 1'b0 01111010 */
+	0x001f, /* AICCDETTH[19:16] AICCOFFTH[19:16] 00000000 */
+	0x0020, /* AICCDETTH[15:8] 01111100 */
+	0x0021, /* AICCDETTH[7:0] 00000000 */
+	0x0022, /* AICCOFFTH[15:8] 00000101 */
+	0x0023, /* AICCOFFTH[7:0] 11100000 */
+	0x0024, /* AICCOPMODE3[1:0] AICCOPMODE2[1:0] AICCOPMODE1[1:0] AICCOPMODE0[1:0] 00000000 */
+	0x0025, /* AICCFIXFREQ3[23:16] 00000000 */
+	0x0026, /* AICCFIXFREQ3[15:8] 00000000 */
+	0x0027, /* AICCFIXFREQ3[7:0] 00000000 */
+	0x0028, /* AICCFIXFREQ2[23:16] 00000000 */
+	0x0029, /* AICCFIXFREQ2[15:8] 00000000 */
+	0x002a, /* AICCFIXFREQ2[7:0] 00000000 */
+	0x002b, /* AICCFIXFREQ1[23:16] 00000000 */
+	0x002c, /* AICCFIXFREQ1[15:8] 00000000 */
+	0x002d, /* AICCFIXFREQ1[7:0] 00000000 */
+	0x002e, /* AICCFIXFREQ0[23:16] 00000000 */
+	0x002f, /* AICCFIXFREQ0[15:8] 00000000 */
+	0x0030, /* AICCFIXFREQ0[7:0] 00000000 */
+	0x0031, /* 1'b0 1'b1 1'b0 1'b0 x DAGC1STER */
+	0x0032, /* DAGC1STEN DAGC1STER */
+	0x0033, /* DAGC1STREF[15:8] 00001010 */
+	0x0034, /* DAGC1STREF[7:0] 11100100 */
+	0x0035, /* DAGC2NDE */
+	0x0036, /* DAGC2NDREF[15:8] 00001010 */
+	0x0037, /* DAGC2NDREF[7:0] 10000000 */
+	0x0038, /* DAGC2NDLOCKDETRNGSEL[1:0] */
+	0x003d, /* 1'b1 SAMGEARS */
+	0x0040, /* SAMLFGMA */
+	0x0041, /* SAMLFBWM */
+	0x0044, /* 1'b1 CRGEARSHE */
+	0x0045, /* CRLFGMAN */
+	0x0046, /* CFLFBWMA */
+	0x0047, /* CRLFGMAN */
+	0x0048, /* x x x x CRLFGSTEP_VS[3:0] xxxx1001 */
+	0x0049, /* CRLFBWMA */
+	0x004a, /* CRLFBWMA */
+	0x0050, /* 1'b0 1'b1 1'b1 1'b0 MSECALCDA */
+	0x0070, /* TPOUTEN TPIFEN TPCLKOUTE */
+	0x0071, /* TPSENB TPSSOPBITE */
+	0x0073, /* TP47HINS x x CHBERINT PERMODE[1:0] PERINT[1:0] 1xx11100 */
+	0x0075, /* x x x x x IQSWAPCTRL[2:0] xxxxx000 */
+	0x0076, /* NBERCON NBERST NBERPOL NBERWSYN */
+	0x0077, /* x NBERLOSTTH[2:0] NBERACQTH[3:0] x0000000 */
+	0x0078, /* NBERPOLY[31:24] 00000000 */
+	0x0079, /* NBERPOLY[23:16] 00000000 */
+	0x007a, /* NBERPOLY[15:8] 00000000 */
+	0x007b, /* NBERPOLY[7:0] 00000000 */
+	0x007c, /* NBERPED[31:24] 00000000 */
+	0x007d, /* NBERPED[23:16] 00000000 */
+	0x007e, /* NBERPED[15:8] 00000000 */
+	0x007f, /* NBERPED[7:0] 00000000 */
+	0x0080, /* x AGCLOCK DAGCLOCK SYSLOCK x x NEVERLOCK[1:0] */
+	0x0085, /* SPECINVST */
+	0x0088, /* SYSLOCKTIME[15:8] */
+	0x0089, /* SYSLOCKTIME[7:0] */
+	0x008c, /* FECLOCKTIME[15:8] */
+	0x008d, /* FECLOCKTIME[7:0] */
+	0x008e, /* AGCACCOUT[15:8] */
+	0x008f, /* AGCACCOUT[7:0] */
+	0x0090, /* AICCREJSTATUS[3:0] AICCREJBUSY[3:0] */
+	0x0091, /* AICCVSYNC */
+	0x009c, /* CARRFREQOFFSET[15:8] */
+	0x009d, /* CARRFREQOFFSET[7:0] */
+	0x00a1, /* SAMFREQOFFSET[23:16] */
+	0x00a2, /* SAMFREQOFFSET[15:8] */
+	0x00a3, /* SAMFREQOFFSET[7:0] */
+	0x00a6, /* SYNCLOCK SYNCLOCKH */
+#if 0 /* covered elsewhere */
+	0x00e8, /* CONSTPWR[15:8] */
+	0x00e9, /* CONSTPWR[7:0] */
+	0x00ea, /* BMSE[15:8] */
+	0x00eb, /* BMSE[7:0] */
+	0x00ec, /* MSE[15:8] */
+	0x00ed, /* MSE[7:0] */
+	0x00ee, /* CONSTI[7:0] */
+	0x00ef, /* CONSTQ[7:0] */
+#endif
+	0x00f4, /* TPIFTPERRCNT[7:0] */
+	0x00f5, /* TPCORREC */
+	0x00f6, /* VBBER[15:8] */
+	0x00f7, /* VBBER[7:0] */
+	0x00f8, /* VABER[15:8] */
+	0x00f9, /* VABER[7:0] */
+	0x00fa, /* TPERRCNT[7:0] */
+	0x00fb, /* NBERLOCK x x x x x x x */
+	0x00fc, /* NBERVALUE[31:24] */
+	0x00fd, /* NBERVALUE[23:16] */
+	0x00fe, /* NBERVALUE[15:8] */
+	0x00ff, /* NBERVALUE[7:0] */
+	0x1000, /* 1'b0 WODAGCOU */
+	0x1005, /* x x 1'b1 1'b1 x SRD_Q_QM */
+	0x1009, /* SRDWAITTIME[7:0] (10msec) 00100011 */
+	0x100a, /* SRDWAITTIME_CQS[7:0] (msec) 01100100 */
+	0x101a, /* x 1'b1 1'b0 1'b0 x QMDQAMMODE[2:0] x100x010 */
+	0x1036, /* 1'b0 1'b1 1'b0 1'b0 SAMGSEND_CQS[3:0] 01001110 */
+	0x103c, /* SAMGSAUTOSTL_V[3:0] SAMGSAUTOEDL_V[3:0] 01000110 */
+	0x103d, /* 1'b1 1'b1 SAMCNORMBP_V[1:0] 1'b0 1'b0 SAMMODESEL_V[1:0] 11100001 */
+	0x103f, /* SAMZTEDSE */
+	0x105d, /* EQSTATUSE */
+	0x105f, /* x PMAPG2_V[2:0] x DMAPG2_V[2:0] x001x011 */
+	0x1060, /* 1'b1 EQSTATUSE */
+	0x1061, /* CRMAPBWSTL_V[3:0] CRMAPBWEDL_V[3:0] 00000100 */
+	0x1065, /* 1'b0 x CRMODE_V[1:0] 1'b1 x 1'b1 x 0x111x1x */
+	0x1066, /* 1'b0 1'b0 1'b1 1'b0 1'b1 PNBOOSTSE */
+	0x1068, /* CREPHNGAIN2_V[3:0] CREPHNPBW_V[3:0] 10010001 */
+	0x106e, /* x x x x x CREPHNEN_ */
+	0x106f, /* CREPHNTH_V[7:0] 00010101 */
+	0x1072, /* CRSWEEPN */
+	0x1073, /* CRPGAIN_V[3:0] x x 1'b1 1'b1 1001xx11 */
+	0x1074, /* CRPBW_V[3:0] x x 1'b1 1'b1 0001xx11 */
+	0x1080, /* DAFTSTATUS[1:0] x x x x x x */
+	0x1081, /* SRDSTATUS[1:0] x x x x x SRDLOCK */
+	0x10a9, /* EQSTATUS_CQS[1:0] x x x x x x */
+	0x10b7, /* EQSTATUS_V[1:0] x x x x x x */
+#if 0 /* SMART_ANT */
+	0x1f00, /* MODEDETE */
+	0x1f01, /* x x x x x x x SFNRST xxxxxxx0 */
+	0x1f03, /* NUMOFANT[7:0] 10000000 */
+	0x1f04, /* x SELMASK[6:0] x0000000 */
+	0x1f05, /* x SETMASK[6:0] x0000000 */
+	0x1f06, /* x TXDATA[6:0] x0000000 */
+	0x1f07, /* x CHNUMBER[6:0] x0000000 */
+	0x1f09, /* AGCTIME[23:16] 10011000 */
+	0x1f0a, /* AGCTIME[15:8] 10010110 */
+	0x1f0b, /* AGCTIME[7:0] 10000000 */
+	0x1f0c, /* ANTTIME[31:24] 00000000 */
+	0x1f0d, /* ANTTIME[23:16] 00000011 */
+	0x1f0e, /* ANTTIME[15:8] 10010000 */
+	0x1f0f, /* ANTTIME[7:0] 10010000 */
+	0x1f11, /* SYNCTIME[23:16] 10011000 */
+	0x1f12, /* SYNCTIME[15:8] 10010110 */
+	0x1f13, /* SYNCTIME[7:0] 10000000 */
+	0x1f14, /* SNRTIME[31:24] 00000001 */
+	0x1f15, /* SNRTIME[23:16] 01111101 */
+	0x1f16, /* SNRTIME[15:8] 01111000 */
+	0x1f17, /* SNRTIME[7:0] 01000000 */
+	0x1f19, /* FECTIME[23:16] 00000000 */
+	0x1f1a, /* FECTIME[15:8] 01110010 */
+	0x1f1b, /* FECTIME[7:0] 01110000 */
+	0x1f1d, /* FECTHD[7:0] 00000011 */
+	0x1f1f, /* SNRTHD[23:16] 00001000 */
+	0x1f20, /* SNRTHD[15:8] 01111111 */
+	0x1f21, /* SNRTHD[7:0] 10000101 */
+	0x1f80, /* IRQFLG x x SFSDRFLG MODEBFLG SAVEFLG SCANFLG TRACKFLG */
+	0x1f81, /* x SYNCCON SNRCON FECCON x STDBUSY SYNCRST AGCFZCO */
+	0x1f82, /* x x x SCANOPCD[4:0] */
+	0x1f83, /* x x x x MAINOPCD[3:0] */
+	0x1f84, /* x x RXDATA[13:8] */
+	0x1f85, /* RXDATA[7:0] */
+	0x1f86, /* x x SDTDATA[13:8] */
+	0x1f87, /* SDTDATA[7:0] */
+	0x1f89, /* ANTSNR[23:16] */
+	0x1f8a, /* ANTSNR[15:8] */
+	0x1f8b, /* ANTSNR[7:0] */
+	0x1f8c, /* x x x x ANTFEC[13:8] */
+	0x1f8d, /* ANTFEC[7:0] */
+	0x1f8e, /* MAXCNT[7:0] */
+	0x1f8f, /* SCANCNT[7:0] */
+	0x1f91, /* MAXPW[23:16] */
+	0x1f92, /* MAXPW[15:8] */
+	0x1f93, /* MAXPW[7:0] */
+	0x1f95, /* CURPWMSE[23:16] */
+	0x1f96, /* CURPWMSE[15:8] */
+	0x1f97, /* CURPWMSE[7:0] */
+#endif /* SMART_ANT */
+	0x211f, /* 1'b1 1'b1 1'b1 CIRQEN x x 1'b0 1'b0 1111xx00 */
+	0x212a, /* EQAUTOST */
+	0x2122, /* CHFAST[7:0] 01100000 */
+	0x212b, /* FFFSTEP_V[3:0] x FBFSTEP_V[2:0] 0001x001 */
+	0x212c, /* PHDEROTBWSEL[3:0] 1'b1 1'b1 1'b1 1'b0 10001110 */
+	0x212d, /* 1'b1 1'b1 1'b1 1'b1 x x TPIFLOCKS */
+	0x2135, /* DYNTRACKFDEQ[3:0] x 1'b0 1'b0 1'b0 1010x000 */
+	0x2141, /* TRMODE[1:0] 1'b1 1'b1 1'b0 1'b1 1'b1 1'b1 01110111 */
+	0x2162, /* AICCCTRLE */
+	0x2173, /* PHNCNFCNT[7:0] 00000100 */
+	0x2179, /* 1'b0 1'b0 1'b0 1'b1 x BADSINGLEDYNTRACKFBF[2:0] 0001x001 */
+	0x217a, /* 1'b0 1'b0 1'b0 1'b1 x BADSLOWSINGLEDYNTRACKFBF[2:0] 0001x001 */
+	0x217e, /* CNFCNTTPIF[7:0] 00001000 */
+	0x217f, /* TPERRCNTTPIF[7:0] 00000001 */
+	0x2180, /* x x x x x x FBDLYCIR[9:8] */
+	0x2181, /* FBDLYCIR[7:0] */
+	0x2185, /* MAXPWRMAIN[7:0] */
+	0x2191, /* NCOMBDET x x x x x x x */
+	0x2199, /* x MAINSTRON */
+	0x219a, /* FFFEQSTEPOUT_V[3:0] FBFSTEPOUT_V[2:0] */
+	0x21a1, /* x x SNRREF[5:0] */
+	0x2845, /* 1'b0 1'b1 x x FFFSTEP_CQS[1:0] FFFCENTERTAP[1:0] 01xx1110 */
+	0x2846, /* 1'b0 x 1'b0 1'b1 FBFSTEP_CQS[1:0] 1'b1 1'b0 0x011110 */
+	0x2847, /* ENNOSIGDE */
+	0x2849, /* 1'b1 1'b1 NOUSENOSI */
+	0x284a, /* EQINITWAITTIME[7:0] 01100100 */
+	0x3000, /* 1'b1 1'b1 1'b1 x x x 1'b0 RPTRSTM */
+	0x3001, /* RPTRSTWAITTIME[7:0] (100msec) 00110010 */
+	0x3031, /* FRAMELOC */
+	0x3032, /* 1'b1 1'b0 1'b0 1'b0 x x FRAMELOCKMODE_CQS[1:0] 1000xx11 */
+	0x30a9, /* VDLOCK_Q FRAMELOCK */
+	0x30aa, /* MPEGLOCK */
+};
+
+#define numDumpRegs (sizeof(regtab)/sizeof(regtab[0]))
+static u8 regval1[numDumpRegs] = {0, };
+static u8 regval2[numDumpRegs] = {0, };
+
+static void lgdt3306a_DumpAllRegs(struct lgdt3306a_state *state)
+{
+		memset(regval2, 0xff, sizeof(regval2));
+		lgdt3306a_DumpRegs(state);
+}
+
+static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state)
+{
+	int i;
+	int sav_debug = debug;
+
+	if ((debug & DBG_DUMP) == 0)
+		return;
+	debug &= ~DBG_REG; /* suppress DBG_REG during reg dump */
+
+	lg_debug("\n");
+
+	for (i = 0; i < numDumpRegs; i++) {
+		lgdt3306a_read_reg(state, regtab[i], &regval1[i]);
+		if (regval1[i] != regval2[i]) {
+			lg_debug(" %04X = %02X\n", regtab[i], regval1[i]);
+				 regval2[i] = regval1[i];
+		}
+	}
+	debug = sav_debug;
+}
+#endif /* DBG_DUMP */
+
+
+
+static struct dvb_frontend_ops lgdt3306a_ops = {
+	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
+	.info = {
+		.name = "LG Electronics LGDT3306A VSB/QAM Frontend",
+		.frequency_min      = 54000000,
+		.frequency_max      = 858000000,
+		.frequency_stepsize = 62500,
+		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+	},
+	.i2c_gate_ctrl        = lgdt3306a_i2c_gate_ctrl,
+	.init                 = lgdt3306a_init,
+	.sleep                = lgdt3306a_fe_sleep,
+	/* if this is set, it overrides the default swzigzag */
+	.tune                 = lgdt3306a_tune,
+	.set_frontend         = lgdt3306a_set_parameters,
+	.get_frontend         = lgdt3306a_get_frontend,
+	.get_frontend_algo    = lgdt3306a_get_frontend_algo,
+	.get_tune_settings    = lgdt3306a_get_tune_settings,
+	.read_status          = lgdt3306a_read_status,
+	.read_ber             = lgdt3306a_read_ber,
+	.read_signal_strength = lgdt3306a_read_signal_strength,
+	.read_snr             = lgdt3306a_read_snr,
+	.read_ucblocks        = lgdt3306a_read_ucblocks,
+	.release              = lgdt3306a_release,
+	.ts_bus_ctrl          = lgdt3306a_ts_bus_ctrl,
+	.search               = lgdt3306a_search,
+};
+
+MODULE_DESCRIPTION("LG Electronics LGDT3306A ATSC/QAM-B Demodulator Driver");
+MODULE_AUTHOR("Fred Richter <frichter@hauppauge.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.2");

+ 74 - 0
drivers/media/dvb-frontends/lgdt3306a.h

@@ -0,0 +1,74 @@
+/*
+ *    Support for LGDT3306A - 8VSB/QAM-B
+ *
+ *    Copyright (C) 2013,2014 Fred Richter <frichter@hauppauge.com>
+ *      based on lgdt3305.[ch] by Michael Krufky
+ *
+ *    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 _LGDT3306A_H_
+#define _LGDT3306A_H_
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+
+enum lgdt3306a_mpeg_mode {
+	LGDT3306A_MPEG_PARALLEL = 0,
+	LGDT3306A_MPEG_SERIAL = 1,
+};
+
+enum lgdt3306a_tp_clock_edge {
+	LGDT3306A_TPCLK_RISING_EDGE = 0,
+	LGDT3306A_TPCLK_FALLING_EDGE = 1,
+};
+
+enum lgdt3306a_tp_valid_polarity {
+	LGDT3306A_TP_VALID_LOW = 0,
+	LGDT3306A_TP_VALID_HIGH = 1,
+};
+
+struct lgdt3306a_config {
+	u8 i2c_addr;
+
+	/* user defined IF frequency in KHz */
+	u16 qam_if_khz;
+	u16 vsb_if_khz;
+
+	/* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
+	unsigned int deny_i2c_rptr:1;
+
+	/* spectral inversion - 0:disabled 1:enabled */
+	unsigned int spectral_inversion:1;
+
+	enum lgdt3306a_mpeg_mode mpeg_mode;
+	enum lgdt3306a_tp_clock_edge tpclk_edge;
+	enum lgdt3306a_tp_valid_polarity tpvalid_polarity;
+
+	/* demod clock freq in MHz; 24 or 25 supported */
+	int  xtalMHz;
+};
+
+#if IS_REACHABLE(CONFIG_DVB_LGDT3306A)
+struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config,
+				      struct i2c_adapter *i2c_adap);
+#else
+static inline
+struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config,
+				      struct i2c_adapter *i2c_adap)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_LGDT3306A */
+
+#endif /* _LGDT3306A_H_ */

+ 1 - 1
drivers/media/dvb-frontends/lgdt330x.h

@@ -52,7 +52,7 @@ struct lgdt330x_config
 	int clock_polarity_flip;
 	int clock_polarity_flip;
 };
 };
 
 
-#if IS_ENABLED(CONFIG_DVB_LGDT330X)
+#if IS_REACHABLE(CONFIG_DVB_LGDT330X)
 extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
 extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
 					    struct i2c_adapter* i2c);
 					    struct i2c_adapter* i2c);
 #else
 #else

Some files were not shown because too many files changed in this diff