Răsfoiți Sursa

Merge branch 'patchwork' into v4l_for_linus

* patchwork: (544 commits)
  [media] ir-hix5hd2: fix build on c6x arch
  [media] pt3: fix DTV FE I2C driver load error paths
  Revert "[media] media: em28xx - remove reset_resume interface"
  [media] exynos4-is: fix some warnings when compiling on arm64
  [media] usb drivers: use %zu instead of %zd
  [media] pci drivers: use %zu instead of %zd
  [media] dvb-frontends: use %zu instead of %zd
  [media] s5p-mfc: Fix several printk warnings
  [media] s5p_mfc_opr: Fix warnings
  [media] ti-vpe: Fix typecast
  [media] s3c-camif: fix dma_addr_t printks
  [media] s5p_mfc_opr_v6: get rid of warnings when compiled with 64 bits
  [media] s5p_mfc_opr_v5: Fix lots of warnings on x86_64
  [media] em28xx: Fix identation
  [media] drxd: remove a dead code
  [media] saa7146: remove return after BUG()
  [media] cx88: remove return after BUG()
  [media] cx88: fix cards table CodingStyle
  [media] radio-sf16fmr2: declare some structs as static
  [media] radio-sf16fmi: declare pnp_attached as static
  ...

Conflicts:
	Documentation/DocBook/media/v4l/compat.xml
Mauro Carvalho Chehab 10 ani în urmă
părinte
comite
a66d05d504
100 a modificat fișierele cu 4573 adăugiri și 1209 ștergeri
  1. 6 0
      Documentation/DocBook/media/v4l/compat.xml
  2. 55 0
      Documentation/DocBook/media/v4l/controls.xml
  3. 48 4
      Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
  4. 4 3
      Documentation/DocBook/media/v4l/vidioc-dqevent.xml
  5. 7 7
      Documentation/DocBook/media/v4l/vidioc-g-edid.xml
  6. 1 1
      Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml
  7. 25 0
      Documentation/devicetree/bindings/media/hix5hd2-ir.txt
  8. 13 11
      Documentation/dvb/get_dvb_firmware
  9. 1111 0
      Documentation/video4linux/vivid.txt
  10. 27 1
      MAINTAINERS
  11. 1 1
      drivers/media/common/b2c2/flexcop.h
  12. 0 3
      drivers/media/common/saa7146/saa7146_fops.c
  13. 6 0
      drivers/media/common/siano/sms-cards.c
  14. 1 0
      drivers/media/common/siano/sms-cards.h
  15. 1 3
      drivers/media/common/siano/smscoreapi.c
  16. 5 2
      drivers/media/dvb-core/dmxdev.c
  17. 2 0
      drivers/media/dvb-core/dvb-usb-ids.h
  18. 32 13
      drivers/media/dvb-core/dvb_frontend.c
  19. 2 0
      drivers/media/dvb-core/dvb_frontend.h
  20. 26 0
      drivers/media/dvb-core/dvb_ringbuffer.c
  21. 2 0
      drivers/media/dvb-core/dvb_ringbuffer.h
  22. 20 0
      drivers/media/dvb-frontends/Kconfig
  23. 3 1
      drivers/media/dvb-frontends/Makefile
  24. 12 12
      drivers/media/dvb-frontends/af9013.c
  25. 425 332
      drivers/media/dvb-frontends/af9033.c
  26. 20 38
      drivers/media/dvb-frontends/af9033.h
  27. 1 0
      drivers/media/dvb-frontends/af9033_priv.h
  28. 480 0
      drivers/media/dvb-frontends/as102_fe.c
  29. 29 0
      drivers/media/dvb-frontends/as102_fe.h
  30. 0 6
      drivers/media/dvb-frontends/as102_fe_types.h
  31. 3 3
      drivers/media/dvb-frontends/bcm3510.c
  32. 2 2
      drivers/media/dvb-frontends/cxd2820r_c.c
  33. 2 2
      drivers/media/dvb-frontends/cxd2820r_core.c
  34. 2 2
      drivers/media/dvb-frontends/cxd2820r_t.c
  35. 1 1
      drivers/media/dvb-frontends/dib7000p.c
  36. 19 19
      drivers/media/dvb-frontends/drx39xyj/drxj.c
  37. 2 7
      drivers/media/dvb-frontends/drxd_hard.c
  38. 19 18
      drivers/media/dvb-frontends/drxk_hard.c
  39. 74 27
      drivers/media/dvb-frontends/m88ds3103.c
  40. 30 5
      drivers/media/dvb-frontends/m88ds3103.h
  41. 4 2
      drivers/media/dvb-frontends/mb86a16.c
  42. 7 7
      drivers/media/dvb-frontends/mb86a20s.c
  43. 1 1
      drivers/media/dvb-frontends/mt312.c
  44. 1 1
      drivers/media/dvb-frontends/or51211.c
  45. 1 1
      drivers/media/dvb-frontends/rtl2832.c
  46. 56 62
      drivers/media/dvb-frontends/rtl2832_sdr.c
  47. 43 20
      drivers/media/dvb-frontends/si2165.c
  48. 1 1
      drivers/media/dvb-frontends/si2165_priv.h
  49. 83 46
      drivers/media/dvb-frontends/si2168.c
  50. 6 0
      drivers/media/dvb-frontends/si2168.h
  51. 2 0
      drivers/media/dvb-frontends/si2168_priv.h
  52. 3 0
      drivers/media/dvb-frontends/si21xx.c
  53. 441 0
      drivers/media/dvb-frontends/sp2.c
  54. 53 0
      drivers/media/dvb-frontends/sp2.h
  55. 50 0
      drivers/media/dvb-frontends/sp2_priv.h
  56. 1 2
      drivers/media/dvb-frontends/sp8870.c
  57. 4 8
      drivers/media/dvb-frontends/stv0367.c
  58. 2 5
      drivers/media/dvb-frontends/stv0900_core.c
  59. 2 1
      drivers/media/dvb-frontends/stv0900_sw.c
  60. 840 0
      drivers/media/dvb-frontends/tc90522.c
  61. 42 0
      drivers/media/dvb-frontends/tc90522.h
  62. 1 1
      drivers/media/dvb-frontends/tda10071.c
  63. 1 1
      drivers/media/dvb-frontends/zl10039.c
  64. 10 0
      drivers/media/firewire/firedtv-avc.c
  65. 1 1
      drivers/media/i2c/adv7343_regs.h
  66. 1 1
      drivers/media/i2c/adv7604.c
  67. 3 1
      drivers/media/i2c/adv7842.c
  68. 1 1
      drivers/media/i2c/cx25840/cx25840-ir.c
  69. 2 2
      drivers/media/i2c/lm3560.c
  70. 1 13
      drivers/media/i2c/ov7670.c
  71. 1 1
      drivers/media/i2c/s5k5baf.c
  72. 3 3
      drivers/media/i2c/saa6752hs.c
  73. 100 43
      drivers/media/i2c/smiapp/smiapp-core.c
  74. 4 0
      drivers/media/i2c/smiapp/smiapp.h
  75. 1 3
      drivers/media/i2c/soc_camera/mt9t112.c
  76. 1 4
      drivers/media/i2c/soc_camera/ov772x.c
  77. 2 2
      drivers/media/i2c/soc_camera/ov9740.c
  78. 1 1
      drivers/media/i2c/tda7432.c
  79. 8 13
      drivers/media/i2c/tvp7002.c
  80. 1 13
      drivers/media/i2c/vs6624.c
  81. 2 4
      drivers/media/media-device.c
  82. 1 2
      drivers/media/media-devnode.c
  83. 6 1
      drivers/media/parport/pms.c
  84. 2 0
      drivers/media/pci/Kconfig
  85. 2 1
      drivers/media/pci/Makefile
  86. 2 3
      drivers/media/pci/bt8xx/bttv-driver.c
  87. 1 3
      drivers/media/pci/bt8xx/dst_ca.c
  88. 1 1
      drivers/media/pci/cx18/cx18-alsa-pcm.c
  89. 3 3
      drivers/media/pci/cx18/cx18-firmware.c
  90. 1 1
      drivers/media/pci/cx18/cx18-queue.c
  91. 6 3
      drivers/media/pci/cx23885/Kconfig
  92. 0 1
      drivers/media/pci/cx23885/Makefile
  93. 2 6
      drivers/media/pci/cx23885/altera-ci.c
  94. 0 4
      drivers/media/pci/cx23885/altera-ci.h
  95. 0 4
      drivers/media/pci/cx23885/cimax2.c
  96. 0 4
      drivers/media/pci/cx23885/cimax2.h
  97. 149 354
      drivers/media/pci/cx23885/cx23885-417.c
  98. 90 19
      drivers/media/pci/cx23885/cx23885-alsa.c
  99. 0 5
      drivers/media/pci/cx23885/cx23885-av.c
  100. 0 5
      drivers/media/pci/cx23885/cx23885-av.h

+ 6 - 0
Documentation/DocBook/media/v4l/compat.xml

@@ -2566,6 +2566,12 @@ fields changed from _s32 to _u32.
 	  <para>Added compound control types and &VIDIOC-QUERY-EXT-CTRL;.
 	  </para>
         </listitem>
+      <title>V4L2 in Linux 3.18</title>
+      <orderedlist>
+	<listitem>
+	  <para>Added <constant>V4L2_CID_PAN_SPEED</constant> and
+ <constant>V4L2_CID_TILT_SPEED</constant> camera controls.</para>
+	</listitem>
       </orderedlist>
     </section>
 

+ 55 - 0
Documentation/DocBook/media/v4l/controls.xml

@@ -3965,6 +3965,27 @@ by exposure, white balance or focus controls.</entry>
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PAN_SPEED</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">This control turns the
+camera horizontally at the specific speed. The unit is undefined. A
+positive value moves the camera to the right (clockwise when viewed
+from above), a negative value to the left. A value of zero stops the motion
+if one is in progress and has no effect otherwise.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TILT_SPEED</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">This control turns the
+camera vertically at the specified speed. The unit is undefined. A
+positive value moves the camera up, a negative value down. A value of zero
+stops the motion if one is in progress and has no effect otherwise.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
 	</tbody>
       </tgroup>
     </table>
@@ -4790,6 +4811,40 @@ interface and may change in the future.</para>
 	    conversion.
 	    </entry>
 	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TEST_PATTERN_RED</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Test pattern red colour component.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TEST_PATTERN_GREENR</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Test pattern green (next to red)
+	    colour component.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TEST_PATTERN_BLUE</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Test pattern blue colour component.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TEST_PATTERN_GREENB</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Test pattern green (next to blue)
+	    colour component.
+	    </entry>
+	  </row>
 	  <row><entry></entry></row>
 	</tbody>
       </tgroup>

+ 48 - 4
Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml

@@ -237,9 +237,9 @@ for a pixel lie next to each other in memory.</para>
 	    <entry>g<subscript>4</subscript></entry>
 	    <entry>g<subscript>3</subscript></entry>
 	  </row>
-	  <row id="V4L2-PIX-FMT-RGB555X">
-	    <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
-	    <entry>'RGBQ'</entry>
+	  <row id="V4L2-PIX-FMT-ARGB555X">
+	    <entry><constant>V4L2_PIX_FMT_ARGB555X</constant></entry>
+	    <entry>'AR15' | (1 &lt;&lt; 31)</entry>
 	    <entry></entry>
 	    <entry>a</entry>
 	    <entry>r<subscript>4</subscript></entry>
@@ -259,6 +259,28 @@ for a pixel lie next to each other in memory.</para>
 	    <entry>b<subscript>1</subscript></entry>
 	    <entry>b<subscript>0</subscript></entry>
 	  </row>
+	  <row id="V4L2-PIX-FMT-XRGB555X">
+	    <entry><constant>V4L2_PIX_FMT_XRGB555X</constant></entry>
+	    <entry>'XR15' | (1 &lt;&lt; 31)</entry>
+	    <entry></entry>
+	    <entry>-</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>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</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>
 	  <row id="V4L2-PIX-FMT-RGB565X">
 	    <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
 	    <entry>'RGBR'</entry>
@@ -464,7 +486,7 @@ for a pixel lie next to each other in memory.</para>
 	  </row>
 	  <row id="V4L2-PIX-FMT-ARGB32">
 	    <entry><constant>V4L2_PIX_FMT_ARGB32</constant></entry>
-	    <entry>'AX24'</entry>
+	    <entry>'BA24'</entry>
 	    <entry></entry>
 	    <entry>a<subscript>7</subscript></entry>
 	    <entry>a<subscript>6</subscript></entry>
@@ -800,6 +822,28 @@ image</title>
 	    <entry>g<subscript>4</subscript></entry>
 	    <entry>g<subscript>3</subscript></entry>
 	  </row>
+	  <row id="V4L2-PIX-FMT-RGB555X">
+	    <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
+	    <entry>'RGBQ'</entry>
+	    <entry></entry>
+	    <entry>a</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>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</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>
 	  <row id="V4L2-PIX-FMT-BGR32">
 	    <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
 	    <entry>'BGR4'</entry>

+ 4 - 3
Documentation/DocBook/media/v4l/vidioc-dqevent.xml

@@ -76,21 +76,22 @@
 	    <entry></entry>
 	    <entry>&v4l2-event-vsync;</entry>
             <entry><structfield>vsync</structfield></entry>
-	    <entry>Event data for event V4L2_EVENT_VSYNC.
+	    <entry>Event data for event <constant>V4L2_EVENT_VSYNC</constant>.
             </entry>
 	  </row>
 	  <row>
 	    <entry></entry>
 	    <entry>&v4l2-event-ctrl;</entry>
             <entry><structfield>ctrl</structfield></entry>
-	    <entry>Event data for event V4L2_EVENT_CTRL.
+	    <entry>Event data for event <constant>V4L2_EVENT_CTRL</constant>.
             </entry>
 	  </row>
 	  <row>
 	    <entry></entry>
 	    <entry>&v4l2-event-frame-sync;</entry>
             <entry><structfield>frame_sync</structfield></entry>
-	    <entry>Event data for event V4L2_EVENT_FRAME_SYNC.</entry>
+	    <entry>Event data for event
+	    <constant>V4L2_EVENT_FRAME_SYNC</constant>.</entry>
 	  </row>
 	  <row>
 	    <entry></entry>

+ 7 - 7
Documentation/DocBook/media/v4l/vidioc-g-edid.xml

@@ -24,7 +24,7 @@
 	<funcdef>int <function>ioctl</function></funcdef>
 	<paramdef>int <parameter>fd</parameter></paramdef>
 	<paramdef>int <parameter>request</parameter></paramdef>
-	<paramdef>const struct v4l2_edid *<parameter>argp</parameter></paramdef>
+	<paramdef>struct v4l2_edid *<parameter>argp</parameter></paramdef>
       </funcprototype>
     </funcsynopsis>
   </refsynopsisdiv>
@@ -124,18 +124,18 @@
 	    maximum number of blocks as defined by the standard). When you set the EDID and
 	    <structfield>blocks</structfield> is 0, then the EDID is disabled or erased.</entry>
 	  </row>
-	  <row>
-	    <entry>__u8&nbsp;*</entry>
-	    <entry><structfield>edid</structfield></entry>
-	    <entry>Pointer to memory that contains the EDID. The minimum size is
-	    <structfield>blocks</structfield>&nbsp;*&nbsp;128.</entry>
-	  </row>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry><structfield>reserved</structfield>[5]</entry>
 	    <entry>Reserved for future extensions. Applications and drivers must
 	    set the array to zero.</entry>
 	  </row>
+	  <row>
+	    <entry>__u8&nbsp;*</entry>
+	    <entry><structfield>edid</structfield></entry>
+	    <entry>Pointer to memory that contains the EDID. The minimum size is
+	    <structfield>blocks</structfield>&nbsp;*&nbsp;128.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>

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

@@ -176,7 +176,7 @@
 	  </row>
 	  <row>
 	    <entry><constant>V4L2_EVENT_MOTION_DET</constant></entry>
-	    <entry>5</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>

+ 25 - 0
Documentation/devicetree/bindings/media/hix5hd2-ir.txt

@@ -0,0 +1,25 @@
+Device-Tree bindings for hix5hd2 ir IP
+
+Required properties:
+	- compatible: Should contain "hisilicon,hix5hd2-ir".
+	- reg: Base physical address of the controller and length of memory
+	  mapped region.
+	- interrupts: interrupt-specifier for the sole interrupt generated by
+	  the device. The interrupt specifier format depends on the interrupt
+	  controller parent.
+	- clocks: clock phandle and specifier pair.
+	- hisilicon,power-syscon: phandle of syscon used to control power.
+
+Optional properties:
+	- linux,rc-map-name : Remote control map name.
+
+Example node:
+
+	ir: ir@f8001000 {
+		compatible = "hisilicon,hix5hd2-ir";
+		reg = <0xf8001000 0x1000>;
+		interrupts = <0 47 4>;
+		clocks = <&clock HIX5HD2_FIXED_24M>;
+		hisilicon,power-syscon = <&sysctrl>;
+		linux,rc-map-name = "rc-tivo";
+	};

+ 13 - 11
Documentation/dvb/get_dvb_firmware

@@ -708,23 +708,25 @@ sub drxk_terratec_htc_stick {
 }
 
 sub it9135 {
-	my $sourcefile = "dvb-usb-it9135.zip";
-	my $url = "http://www.ite.com.tw/uploads/firmware/v3.6.0.0/$sourcefile";
-	my $hash = "1e55f6c8833f1d0ae067c2bb2953e6a9";
-	my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0);
-	my $outfile = "dvb-usb-it9135.fw";
+	my $url = "http://www.ite.com.tw/uploads/firmware/v3.25.0.0/";
+	my $file1 = "dvb-usb-it9135-01.zip";
 	my $fwfile1 = "dvb-usb-it9135-01.fw";
+	my $hash1 = "02fcf11174eda84745dae7e61c5ff9ba";
+	my $file2 = "dvb-usb-it9135-02.zip";
 	my $fwfile2 = "dvb-usb-it9135-02.fw";
+	my $hash2 = "d5e1437dc24358578e07999475d4cac9";
 
 	checkstandard();
 
-	wgetfile($sourcefile, $url);
-	unzip($sourcefile, $tmpdir);
-	verify("$tmpdir/$outfile", $hash);
-	extract("$tmpdir/$outfile", 64, 8128, "$fwfile1");
-	extract("$tmpdir/$outfile", 12866, 5817, "$fwfile2");
+	wgetfile($file1, $url . $file1);
+	unzip($file1, "");
+	verify("$fwfile1", $hash1);
+
+	wgetfile($file2, $url . $file2);
+	unzip($file2, "");
+	verify("$fwfile2", $hash2);
 
-	"$fwfile1 $fwfile2"
+	"$file1 $file2"
 }
 
 sub tda10071 {

+ 1111 - 0
Documentation/video4linux/vivid.txt

@@ -0,0 +1,1111 @@
+vivid: Virtual Video Test Driver
+================================
+
+This driver emulates video4linux hardware of various types: video capture, video
+output, vbi capture and output, radio receivers and transmitters and a software
+defined radio receiver. In addition a simple framebuffer device is available for
+testing capture and output overlays.
+
+Up to 64 vivid instances can be created, each with up to 16 inputs and 16 outputs.
+
+Each input can be a webcam, TV capture device, S-Video capture device or an HDMI
+capture device. Each output can be an S-Video output device or an HDMI output
+device.
+
+These inputs and outputs act exactly as a real hardware device would behave. This
+allows you to use this driver as a test input for application development, since
+you can test the various features without requiring special hardware.
+
+This document describes the features implemented by this driver:
+
+- Support for read()/write(), MMAP, USERPTR and DMABUF streaming I/O.
+- A large list of test patterns and variations thereof
+- Working brightness, contrast, saturation and hue controls
+- Support for the alpha color component
+- Full colorspace support, including limited/full RGB range
+- All possible control types are present
+- Support for various pixel aspect ratios and video aspect ratios
+- Error injection to test what happens if errors occur
+- Supports crop/compose/scale in any combination for both input and output
+- Can emulate up to 4K resolutions
+- All Field settings are supported for testing interlaced capturing
+- Supports all standard YUV and RGB formats, including two multiplanar YUV formats
+- Raw and Sliced VBI capture and output support
+- Radio receiver and transmitter support, including RDS support
+- Software defined radio (SDR) support
+- Capture and output overlay support
+
+These features will be described in more detail below.
+
+
+Table of Contents
+-----------------
+
+Section 1: Configuring the driver
+Section 2: Video Capture
+Section 2.1: Webcam Input
+Section 2.2: TV and S-Video Inputs
+Section 2.3: HDMI Input
+Section 3: Video Output
+Section 3.1: S-Video Output
+Section 3.2: HDMI Output
+Section 4: VBI Capture
+Section 5: VBI Output
+Section 6: Radio Receiver
+Section 7: Radio Transmitter
+Section 8: Software Defined Radio Receiver
+Section 9: Controls
+Section 9.1: User Controls - Test Controls
+Section 9.2: User Controls - Video Capture
+Section 9.3: User Controls - Audio
+Section 9.4: Vivid Controls
+Section 9.4.1: Test Pattern Controls
+Section 9.4.2: Capture Feature Selection Controls
+Section 9.4.3: Output Feature Selection Controls
+Section 9.4.4: Error Injection Controls
+Section 9.4.5: VBI Raw Capture Controls
+Section 9.5: Digital Video Controls
+Section 9.6: FM Radio Receiver Controls
+Section 9.7: FM Radio Modulator
+Section 10: Video, VBI and RDS Looping
+Section 10.1: Video and Sliced VBI looping
+Section 10.2: Radio & RDS Looping
+Section 11: Cropping, Composing, Scaling
+Section 12: Formats
+Section 13: Capture Overlay
+Section 14: Output Overlay
+Section 15: Some Future Improvements
+
+
+Section 1: Configuring the driver
+---------------------------------
+
+By default the driver will create a single instance that has a video capture
+device with webcam, TV, S-Video and HDMI inputs, a video output device with
+S-Video and HDMI outputs, one vbi capture device, one vbi output device, one
+radio receiver device, one radio transmitter device and one SDR device.
+
+The number of instances, devices, video inputs and outputs and their types are
+all configurable using the following module options:
+
+n_devs: number of driver instances to create. By default set to 1. Up to 64
+	instances can be created.
+
+node_types: which devices should each driver instance create. An array of
+	hexadecimal values, one for each instance. The default is 0x1d3d.
+	Each value is a bitmask with the following meaning:
+		bit 0: Video Capture node
+		bit 2-3: VBI Capture node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both
+		bit 4: Radio Receiver node
+		bit 5: Software Defined Radio Receiver node
+		bit 8: Video Output node
+		bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both
+		bit 12: Radio Transmitter node
+		bit 16: Framebuffer for testing overlays
+
+	So to create four instances, the first two with just one video capture
+	device, the second two with just one video output device you would pass
+	these module options to vivid:
+
+		n_devs=4 node_types=0x1,0x1,0x100,0x100
+
+num_inputs: the number of inputs, one for each instance. By default 4 inputs
+	are created for each video capture device. At most 16 inputs can be created,
+	and there must be at least one.
+
+input_types: the input types for each instance, the default is 0xe4. This defines
+	what the type of each input is when the inputs are created for each driver
+	instance. This is a hexadecimal value with up to 16 pairs of bits, each
+	pair gives the type and bits 0-1 map to input 0, bits 2-3 map to input 1,
+	30-31 map to input 15. Each pair of bits has the following meaning:
+
+		00: this is a webcam input
+		01: this is a TV tuner input
+		10: this is an S-Video input
+		11: this is an HDMI input
+
+	So to create a video capture device with 8 inputs where input 0 is a TV
+	tuner, inputs 1-3 are S-Video inputs and inputs 4-7 are HDMI inputs you
+	would use the following module options:
+
+		num_inputs=8 input_types=0xffa9
+
+num_outputs: the number of outputs, one for each instance. By default 2 outputs
+	are created for each video output device. At most 16 outputs can be
+	created, and there must be at least one.
+
+output_types: the output types for each instance, the default is 0x02. This defines
+	what the type of each output is when the outputs are created for each
+	driver instance. This is a hexadecimal value with up to 16 bits, each bit
+	gives the type and bit 0 maps to output 0, bit 1 maps to output 1, bit
+	15 maps to output 15. The meaning of each bit is as follows:
+
+		0: this is an S-Video output
+		1: this is an HDMI output
+
+	So to create a video output device with 8 outputs where outputs 0-3 are
+	S-Video outputs and outputs 4-7 are HDMI outputs you would use the
+	following module options:
+
+		num_outputs=8 output_types=0xf0
+
+vid_cap_nr: give the desired videoX start number for each video capture device.
+	The default is -1 which will just take the first free number. This allows
+	you to map capture video nodes to specific videoX device nodes. Example:
+
+		n_devs=4 vid_cap_nr=2,4,6,8
+
+	This will attempt to assign /dev/video2 for the video capture device of
+	the first vivid instance, video4 for the next up to video8 for the last
+	instance. If it can't succeed, then it will just take the next free
+	number.
+
+vid_out_nr: give the desired videoX start number for each video output device.
+        The default is -1 which will just take the first free number.
+
+vbi_cap_nr: give the desired vbiX start number for each vbi capture device.
+        The default is -1 which will just take the first free number.
+
+vbi_out_nr: give the desired vbiX start number for each vbi output device.
+        The default is -1 which will just take the first free number.
+
+radio_rx_nr: give the desired radioX start number for each radio receiver device.
+        The default is -1 which will just take the first free number.
+
+radio_tx_nr: give the desired radioX start number for each radio transmitter
+	device. The default is -1 which will just take the first free number.
+
+sdr_cap_nr: give the desired swradioX start number for each SDR capture device.
+        The default is -1 which will just take the first free number.
+
+ccs_cap_mode: specify the allowed video capture crop/compose/scaling combination
+	for each driver instance. Video capture devices can have any combination
+	of cropping, composing and scaling capabilities and this will tell the
+	vivid driver which of those is should emulate. By default the user can
+	select this through controls.
+
+	The value is either -1 (controlled by the user) or a set of three bits,
+	each enabling (1) or disabling (0) one of the features:
+
+		bit 0: Enable crop support. Cropping will take only part of the
+		       incoming picture.
+		bit 1: Enable compose support. Composing will copy the incoming
+		       picture into a larger buffer.
+		bit 2: Enable scaling support. Scaling can scale the incoming
+		       picture. The scaler of the vivid driver can enlarge up
+		       or down to four times the original size. The scaler is
+		       very simple and low-quality. Simplicity and speed were
+		       key, not quality.
+
+	Note that this value is ignored by webcam inputs: those enumerate
+	discrete framesizes and that is incompatible with cropping, composing
+	or scaling.
+
+ccs_out_mode: specify the allowed video output crop/compose/scaling combination
+	for each driver instance. Video output devices can have any combination
+	of cropping, composing and scaling capabilities and this will tell the
+	vivid driver which of those is should emulate. By default the user can
+	select this through controls.
+
+	The value is either -1 (controlled by the user) or a set of three bits,
+	each enabling (1) or disabling (0) one of the features:
+
+		bit 0: Enable crop support. Cropping will take only part of the
+		       outgoing buffer.
+		bit 1: Enable compose support. Composing will copy the incoming
+		       buffer into a larger picture frame.
+		bit 2: Enable scaling support. Scaling can scale the incoming
+		       buffer. The scaler of the vivid driver can enlarge up
+		       or down to four times the original size. The scaler is
+		       very simple and low-quality. Simplicity and speed were
+		       key, not quality.
+
+multiplanar: select whether each device instance supports multi-planar formats,
+	and thus the V4L2 multi-planar API. By default the first device instance
+	is single-planar, the second multi-planar, and it keeps alternating.
+
+	This module option can override that for each instance. Values are:
+
+		0: use alternating single and multi-planar devices.
+		1: this is a single-planar instance.
+		2: this is a multi-planar instance.
+
+vivid_debug: enable driver debugging info
+
+no_error_inj: if set disable the error injecting controls. This option is
+	needed in order to run a tool like v4l2-compliance. Tools like that
+	exercise all controls including a control like 'Disconnect' which
+	emulates a USB disconnect, making the device inaccessible and so
+	all tests that v4l2-compliance is doing will fail afterwards.
+
+	There may be other situations as well where you want to disable the
+	error injection support of vivid. When this option is set, then the
+	controls that select crop, compose and scale behavior are also
+	removed. Unless overridden by ccs_cap_mode and/or ccs_out_mode the
+	will default to enabling crop, compose and scaling.
+
+Taken together, all these module options allow you to precisely customize
+the driver behavior and test your application with all sorts of permutations.
+It is also very suitable to emulate hardware that is not yet available, e.g.
+when developing software for a new upcoming device.
+
+
+Section 2: Video Capture
+------------------------
+
+This is probably the most frequently used feature. The video capture device
+can be configured by using the module options num_inputs, input_types and
+ccs_cap_mode (see section 1 for more detailed information), but by default
+four inputs are configured: a webcam, a TV tuner, an S-Video and an HDMI
+input, one input for each input type. Those are described in more detail
+below.
+
+Special attention has been given to the rate at which new frames become
+available. The jitter will be around 1 jiffie (that depends on the HZ
+configuration of your kernel, so usually 1/100, 1/250 or 1/1000 of a second),
+but the long-term behavior is exactly following the framerate. So a
+framerate of 59.94 Hz is really different from 60 Hz. If the framerate
+exceeds your kernel's HZ value, then you will get dropped frames, but the
+frame/field sequence counting will keep track of that so the sequence
+count will skip whenever frames are dropped.
+
+
+Section 2.1: Webcam Input
+-------------------------
+
+The webcam input supports three framesizes: 320x180, 640x360 and 1280x720. It
+supports frames per second settings of 10, 15, 25, 30, 50 and 60 fps. Which ones
+are available depends on the chosen framesize: the larger the framesize, the
+lower the maximum frames per second.
+
+The initially selected colorspace when you switch to the webcam input will be
+sRGB.
+
+
+Section 2.2: TV and S-Video Inputs
+----------------------------------
+
+The only difference between the TV and S-Video input is that the TV has a
+tuner. Otherwise they behave identically.
+
+These inputs support audio inputs as well: one TV and one Line-In. They
+both support all TV standards. If the standard is queried, then the Vivid
+controls 'Standard Signal Mode' and 'Standard' determine what
+the result will be.
+
+These inputs support all combinations of the field setting. Special care has
+been taken to faithfully reproduce how fields are handled for the different
+TV standards. This is particularly noticable when generating a horizontally
+moving image so the temporal effect of using interlaced formats becomes clearly
+visible. For 50 Hz standards the top field is the oldest and the bottom field
+is the newest in time. For 60 Hz standards that is reversed: the bottom field
+is the oldest and the top field is the newest in time.
+
+When you start capturing in V4L2_FIELD_ALTERNATE mode the first buffer will
+contain the top field for 50 Hz standards and the bottom field for 60 Hz
+standards. This is what capture hardware does as well.
+
+Finally, for PAL/SECAM standards the first half of the top line contains noise.
+This simulates the Wide Screen Signal that is commonly placed there.
+
+The initially selected colorspace when you switch to the TV or S-Video input
+will be SMPTE-170M.
+
+The pixel aspect ratio will depend on the TV standard. The video aspect ratio
+can be selected through the 'Standard Aspect Ratio' Vivid control.
+Choices are '4x3', '16x9' which will give letterboxed widescreen video and
+'16x9 Anomorphic' which will give full screen squashed anamorphic widescreen
+video that will need to be scaled accordingly.
+
+The TV 'tuner' supports a frequency range of 44-958 MHz. Channels are available
+every 6 MHz, starting from 49.25 MHz. For each channel the generated image
+will be in color for the +/- 0.25 MHz around it, and in grayscale for
++/- 1 MHz around the channel. Beyond that it is just noise. The VIDIOC_G_TUNER
+ioctl will return 100% signal strength for +/- 0.25 MHz and 50% for +/- 1 MHz.
+It will also return correct afc values to show whether the frequency is too
+low or too high.
+
+The audio subchannels that are returned are MONO for the +/- 1 MHz range around
+a valid channel frequency. When the frequency is within +/- 0.25 MHz of the
+channel it will return either MONO, STEREO, either MONO | SAP (for NTSC) or
+LANG1 | LANG2 (for others), or STEREO | SAP.
+
+Which one is returned depends on the chosen channel, each next valid channel
+will cycle through the possible audio subchannel combinations. This allows
+you to test the various combinations by just switching channels..
+
+Finally, for these inputs the v4l2_timecode struct is filled in in the
+dequeued v4l2_buffer struct.
+
+
+Section 2.3: HDMI Input
+-----------------------
+
+The HDMI inputs supports all CEA-861 and DMT timings, both progressive and
+interlaced, for pixelclock frequencies between 25 and 600 MHz. The field
+mode for interlaced formats is always V4L2_FIELD_ALTERNATE. For HDMI the
+field order is always top field first, and when you start capturing an
+interlaced format you will receive the top field first.
+
+The initially selected colorspace when you switch to the HDMI input or
+select an HDMI timing is based on the format resolution: for resolutions
+less than or equal to 720x576 the colorspace is set to SMPTE-170M, for
+others it is set to REC-709 (CEA-861 timings) or sRGB (VESA DMT timings).
+
+The pixel aspect ratio will depend on the HDMI timing: for 720x480 is it
+set as for the NTSC TV standard, for 720x576 it is set as for the PAL TV
+standard, and for all others a 1:1 pixel aspect ratio is returned.
+
+The video aspect ratio can be selected through the 'DV Timings Aspect Ratio'
+Vivid control. Choices are 'Source Width x Height' (just use the
+same ratio as the chosen format), '4x3' or '16x9', either of which can
+result in pillarboxed or letterboxed video.
+
+For HDMI inputs it is possible to set the EDID. By default a simple EDID
+is provided. You can only set the EDID for HDMI inputs. Internally, however,
+the EDID is shared between all HDMI inputs.
+
+No interpretation is done of the EDID data.
+
+
+Section 3: Video Output
+-----------------------
+
+The video output device can be configured by using the module options
+num_outputs, output_types and ccs_out_mode (see section 1 for more detailed
+information), but by default two outputs are configured: an S-Video and an
+HDMI input, one output for each output type. Those are described in more detail
+below.
+
+Like with video capture the framerate is also exact in the long term.
+
+
+Section 3.1: S-Video Output
+---------------------------
+
+This output supports audio outputs as well: "Line-Out 1" and "Line-Out 2".
+The S-Video output supports all TV standards.
+
+This output supports all combinations of the field setting.
+
+The initially selected colorspace when you switch to the TV or S-Video input
+will be SMPTE-170M.
+
+
+Section 3.2: HDMI Output
+------------------------
+
+The HDMI output supports all CEA-861 and DMT timings, both progressive and
+interlaced, for pixelclock frequencies between 25 and 600 MHz. The field
+mode for interlaced formats is always V4L2_FIELD_ALTERNATE.
+
+The initially selected colorspace when you switch to the HDMI output or
+select an HDMI timing is based on the format resolution: for resolutions
+less than or equal to 720x576 the colorspace is set to SMPTE-170M, for
+others it is set to REC-709 (CEA-861 timings) or sRGB (VESA DMT timings).
+
+The pixel aspect ratio will depend on the HDMI timing: for 720x480 is it
+set as for the NTSC TV standard, for 720x576 it is set as for the PAL TV
+standard, and for all others a 1:1 pixel aspect ratio is returned.
+
+An HDMI output has a valid EDID which can be obtained through VIDIOC_G_EDID.
+
+
+Section 4: VBI Capture
+----------------------
+
+There are three types of VBI capture devices: those that only support raw
+(undecoded) VBI, those that only support sliced (decoded) VBI and those that
+support both. This is determined by the node_types module option. In all
+cases the driver will generate valid VBI data: for 60 Hz standards it will
+generate Closed Caption and XDS data. The closed caption stream will
+alternate between "Hello world!" and "Closed captions test" every second.
+The XDS stream will give the current time once a minute. For 50 Hz standards
+it will generate the Wide Screen Signal which is based on the actual Video
+Aspect Ratio control setting and teletext pages 100-159, one page per frame.
+
+The VBI device will only work for the S-Video and TV inputs, it will give
+back an error if the current input is a webcam or HDMI.
+
+
+Section 5: VBI Output
+---------------------
+
+There are three types of VBI output devices: those that only support raw
+(undecoded) VBI, those that only support sliced (decoded) VBI and those that
+support both. This is determined by the node_types module option.
+
+The sliced VBI output supports the Wide Screen Signal and the teletext signal
+for 50 Hz standards and Closed Captioning + XDS for 60 Hz standards.
+
+The VBI device will only work for the S-Video output, it will give
+back an error if the current output is HDMI.
+
+
+Section 6: Radio Receiver
+-------------------------
+
+The radio receiver emulates an FM/AM/SW receiver. The FM band also supports RDS.
+The frequency ranges are:
+
+	FM: 64 MHz - 108 MHz
+	AM: 520 kHz - 1710 kHz
+	SW: 2300 kHz - 26.1 MHz
+
+Valid channels are emulated every 1 MHz for FM and every 100 kHz for AM and SW.
+The signal strength decreases the further the frequency is from the valid
+frequency until it becomes 0% at +/- 50 kHz (FM) or 5 kHz (AM/SW) from the
+ideal frequency. The initial frequency when the driver is loaded is set to
+95 MHz.
+
+The FM receiver supports RDS as well, both using 'Block I/O' and 'Controls'
+modes. In the 'Controls' mode the RDS information is stored in read-only
+controls. These controls are updated every time the frequency is changed,
+or when the tuner status is requested. The Block I/O method uses the read()
+interface to pass the RDS blocks on to the application for decoding.
+
+The RDS signal is 'detected' for +/- 12.5 kHz around the channel frequency,
+and the further the frequency is away from the valid frequency the more RDS
+errors are randomly introduced into the block I/O stream, up to 50% of all
+blocks if you are +/- 12.5 kHz from the channel frequency. All four errors
+can occur in equal proportions: blocks marked 'CORRECTED', blocks marked
+'ERROR', blocks marked 'INVALID' and dropped blocks.
+
+The generated RDS stream contains all the standard fields contained in a
+0B group, and also radio text and the current time.
+
+The receiver supports HW frequency seek, either in Bounded mode, Wrap Around
+mode or both, which is configurable with the "Radio HW Seek Mode" control.
+
+
+Section 7: Radio Transmitter
+----------------------------
+
+The radio transmitter emulates an FM/AM/SW transmitter. The FM band also supports RDS.
+The frequency ranges are:
+
+	FM: 64 MHz - 108 MHz
+	AM: 520 kHz - 1710 kHz
+	SW: 2300 kHz - 26.1 MHz
+
+The initial frequency when the driver is loaded is 95.5 MHz.
+
+The FM transmitter supports RDS as well, both using 'Block I/O' and 'Controls'
+modes. In the 'Controls' mode the transmitted RDS information is configured
+using controls, and in 'Block I/O' mode the blocks are passed to the driver
+using write().
+
+
+Section 8: Software Defined Radio Receiver
+------------------------------------------
+
+The SDR receiver has three frequency bands for the ADC tuner:
+
+	- 300 kHz
+	- 900 kHz - 2800 kHz
+	- 3200 kHz
+
+The RF tuner supports 50 MHz - 2000 MHz.
+
+The generated data contains the In-phase and Quadrature components of a
+1 kHz tone that has an amplitude of sqrt(2).
+
+
+Section 9: Controls
+-------------------
+
+Different devices support different controls. The sections below will describe
+each control and which devices support them.
+
+
+Section 9.1: User Controls - Test Controls
+------------------------------------------
+
+The Button, Boolean, Integer 32 Bits, Integer 64 Bits, Menu, String, Bitmask and
+Integer Menu are controls that represent all possible control types. The Menu
+control and the Integer Menu control both have 'holes' in their menu list,
+meaning that one or more menu items return EINVAL when VIDIOC_QUERYMENU is called.
+Both menu controls also have a non-zero minimum control value.  These features
+allow you to check if your application can handle such things correctly.
+These controls are supported for every device type.
+
+
+Section 9.2: User Controls - Video Capture
+------------------------------------------
+
+The following controls are specific to video capture.
+
+The Brightness, Contrast, Saturation and Hue controls actually work and are
+standard. There is one special feature with the Brightness control: each
+video input has its own brightness value, so changing input will restore
+the brightness for that input. In addition, each video input uses a different
+brightness range (minimum and maximum control values). Switching inputs will
+cause a control event to be sent with the V4L2_EVENT_CTRL_CH_RANGE flag set.
+This allows you to test controls that can change their range.
+
+The 'Gain, Automatic' and Gain controls can be used to test volatile controls:
+if 'Gain, Automatic' is set, then the Gain control is volatile and changes
+constantly. If 'Gain, Automatic' is cleared, then the Gain control is a normal
+control.
+
+The 'Horizontal Flip' and 'Vertical Flip' controls can be used to flip the
+image. These combine with the 'Sensor Flipped Horizontally/Vertically' Vivid
+controls.
+
+The 'Alpha Component' control can be used to set the alpha component for
+formats containing an alpha channel.
+
+
+Section 9.3: User Controls - Audio
+----------------------------------
+
+The following controls are specific to video capture and output and radio
+receivers and transmitters.
+
+The 'Volume' and 'Mute' audio controls are typical for such devices to
+control the volume and mute the audio. They don't actually do anything in
+the vivid driver.
+
+
+Section 9.4: Vivid Controls
+---------------------------
+
+These vivid custom controls control the image generation, error injection, etc.
+
+
+Section 9.4.1: Test Pattern Controls
+------------------------------------
+
+The Test Pattern Controls are all specific to video capture.
+
+Test Pattern: selects which test pattern to use. Use the CSC Colorbar for
+	testing colorspace conversions: the colors used in that test pattern
+	map to valid colors in all colorspaces. The colorspace conversion
+	is disabled for the other test patterns.
+
+OSD Text Mode: selects whether the text superimposed on the
+	test pattern should be shown, and if so, whether only counters should
+	be displayed or the full text.
+
+Horizontal Movement: selects whether the test pattern should
+	move to the left or right and at what speed.
+
+Vertical Movement: does the same for the vertical direction.
+
+Show Border: show a two-pixel wide border at the edge of the actual image,
+	excluding letter or pillarboxing.
+
+Show Square: show a square in the middle of the image. If the image is
+	displayed with the correct pixel and image aspect ratio corrections,
+	then the width and height of the square on the monitor should be
+	the same.
+
+Insert SAV Code in Image: adds a SAV (Start of Active Video) code to the image.
+	This can be used to check if such codes in the image are inadvertently
+	interpreted instead of being ignored.
+
+Insert EAV Code in Image: does the same for the EAV (End of Active Video) code.
+
+
+Section 9.4.2: Capture Feature Selection Controls
+-------------------------------------------------
+
+These controls are all specific to video capture.
+
+Sensor Flipped Horizontally: the image is flipped horizontally and the
+	V4L2_IN_ST_HFLIP input status flag is set. This emulates the case where
+	a sensor is for example mounted upside down.
+
+Sensor Flipped Vertically: the image is flipped vertically and the
+	V4L2_IN_ST_VFLIP input status flag is set. This emulates the case where
+        a sensor is for example mounted upside down.
+
+Standard Aspect Ratio: selects if the image aspect ratio as used for the TV or
+	S-Video input should be 4x3, 16x9 or anamorphic widescreen. This may
+	introduce letterboxing.
+
+DV Timings Aspect Ratio: selects if the image aspect ratio as used for the HDMI
+	input should be the same as the source width and height ratio, or if
+	it should be 4x3 or 16x9. This may introduce letter or pillarboxing.
+
+Timestamp Source: selects when the timestamp for each buffer is taken.
+
+Colorspace: selects which colorspace should be used when generating the image.
+	This only applies if the CSC Colorbar test pattern is selected,
+	otherwise the test pattern will go through unconverted (except for
+	the so-called 'Transfer Function' corrections and the R'G'B' to Y'CbCr
+	conversion). This behavior is also what you want, since a 75% Colorbar
+	should really have 75% signal intensity and should not be affected
+	by colorspace conversions.
+
+	Changing the colorspace will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a detected colorspace change.
+
+Limited RGB Range (16-235): selects if the RGB range of the HDMI source should
+	be limited or full range. This combines with the Digital Video 'Rx RGB
+	Quantization Range' control and can be used to test what happens if
+	a source provides you with the wrong quantization range information.
+	See the description of that control for more details.
+
+Apply Alpha To Red Only: apply the alpha channel as set by the 'Alpha Component'
+	user control to the red color of the test pattern only.
+
+Enable Capture Cropping: enables crop support. This control is only present if
+	the ccs_cap_mode module option is set to the default value of -1 and if
+	the no_error_inj module option is set to 0 (the default).
+
+Enable Capture Composing: enables composing support. This control is only
+	present if the ccs_cap_mode module option is set to the default value of
+	-1 and if the no_error_inj module option is set to 0 (the default).
+
+Enable Capture Scaler: enables support for a scaler (maximum 4 times upscaling
+	and downscaling). This control is only present if the ccs_cap_mode
+	module option is set to the default value of -1 and if the no_error_inj
+	module option is set to 0 (the default).
+
+Maximum EDID Blocks: determines how many EDID blocks the driver supports.
+	Note that the vivid driver does not actually interpret new EDID
+	data, it just stores it. It allows for up to 256 EDID blocks
+	which is the maximum supported by the standard.
+
+Fill Percentage of Frame: can be used to draw only the top X percent
+	of the image. Since each frame has to be drawn by the driver, this
+	demands a lot of the CPU. For large resolutions this becomes
+	problematic. By drawing only part of the image this CPU load can
+	be reduced.
+
+
+Section 9.4.3: Output Feature Selection Controls
+------------------------------------------------
+
+These controls are all specific to video output.
+
+Enable Output Cropping: enables crop support. This control is only present if
+	the ccs_out_mode module option is set to the default value of -1 and if
+	the no_error_inj module option is set to 0 (the default).
+
+Enable Output Composing: enables composing support. This control is only
+	present if the ccs_out_mode module option is set to the default value of
+	-1 and if the no_error_inj module option is set to 0 (the default).
+
+Enable Output Scaler: enables support for a scaler (maximum 4 times upscaling
+	and downscaling). This control is only present if the ccs_out_mode
+	module option is set to the default value of -1 and if the no_error_inj
+	module option is set to 0 (the default).
+
+
+Section 9.4.4: Error Injection Controls
+---------------------------------------
+
+The following two controls are only valid for video and vbi capture.
+
+Standard Signal Mode: selects the behavior of VIDIOC_QUERYSTD: what should
+	it return?
+
+	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a changed input condition (e.g. a cable
+	was plugged in or out).
+
+Standard: selects the standard that VIDIOC_QUERYSTD should return if the
+	previous control is set to "Selected Standard".
+
+	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a changed input standard.
+
+
+The following two controls are only valid for video capture.
+
+DV Timings Signal Mode: selects the behavior of VIDIOC_QUERY_DV_TIMINGS: what
+	should it return?
+
+	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates a changed input condition (e.g. a cable
+	was plugged in or out).
+
+DV Timings: selects the timings the VIDIOC_QUERY_DV_TIMINGS should return
+	if the previous control is set to "Selected DV Timings".
+
+	Changing this control will result in the V4L2_EVENT_SOURCE_CHANGE
+	to be sent since it emulates changed input timings.
+
+
+The following controls are only present if the no_error_inj module option
+is set to 0 (the default). These controls are valid for video and vbi
+capture and output streams and for the SDR capture device except for the
+Disconnect control which is valid for all devices.
+
+Wrap Sequence Number: test what happens when you wrap the sequence number in
+	struct v4l2_buffer around.
+
+Wrap Timestamp: test what happens when you wrap the timestamp in struct
+	v4l2_buffer around.
+
+Percentage of Dropped Buffers: sets the percentage of buffers that
+	are never returned by the driver (i.e., they are dropped).
+
+Disconnect: emulates a USB disconnect. The device will act as if it has
+	been disconnected. Only after all open filehandles to the device
+	node have been closed will the device become 'connected' again.
+
+Inject V4L2_BUF_FLAG_ERROR: when pressed, the next frame returned by
+	the driver will have the error flag set (i.e. the frame is marked
+	corrupt).
+
+Inject VIDIOC_REQBUFS Error: when pressed, the next REQBUFS or CREATE_BUFS
+	ioctl call will fail with an error. To be precise: the videobuf2
+	queue_setup() op will return -EINVAL.
+
+Inject VIDIOC_QBUF Error: when pressed, the next VIDIOC_QBUF or
+	VIDIOC_PREPARE_BUFFER ioctl call will fail with an error. To be
+	precise: the videobuf2 buf_prepare() op will return -EINVAL.
+
+Inject VIDIOC_STREAMON Error: when pressed, the next VIDIOC_STREAMON ioctl
+	call will fail with an error. To be precise: the videobuf2
+	start_streaming() op will return -EINVAL.
+
+Inject Fatal Streaming Error: when pressed, the streaming core will be
+	marked as having suffered a fatal error, the only way to recover
+	from that is to stop streaming. To be precise: the videobuf2
+	vb2_queue_error() function is called.
+
+
+Section 9.4.5: VBI Raw Capture Controls
+---------------------------------------
+
+Interlaced VBI Format: if set, then the raw VBI data will be interlaced instead
+	of providing it grouped by field.
+
+
+Section 9.5: Digital Video Controls
+-----------------------------------
+
+Rx RGB Quantization Range: sets the RGB quantization detection of the HDMI
+	input. This combines with the Vivid 'Limited RGB Range (16-235)'
+	control and can be used to test what happens if a source provides
+	you with the wrong quantization range information. This can be tested
+	by selecting an HDMI input, setting this control to Full or Limited
+	range and selecting the opposite in the 'Limited RGB Range (16-235)'
+	control. The effect is easy to see if the 'Gray Ramp' test pattern
+	is selected.
+
+Tx RGB Quantization Range: sets the RGB quantization detection of the HDMI
+	output. It is currently not used for anything in vivid, but most HDMI
+	transmitters would typically have this control.
+
+Transmit Mode: sets the transmit mode of the HDMI output to HDMI or DVI-D. This
+	affects the reported colorspace since DVI_D outputs will always use
+	sRGB.
+
+
+Section 9.6: FM Radio Receiver Controls
+---------------------------------------
+
+RDS Reception: set if the RDS receiver should be enabled.
+
+RDS Program Type:
+RDS PS Name:
+RDS Radio Text:
+RDS Traffic Announcement:
+RDS Traffic Program:
+RDS Music: these are all read-only controls. If RDS Rx I/O Mode is set to
+	"Block I/O", then they are inactive as well. If RDS Rx I/O Mode is set
+	to "Controls", then these controls report the received RDS data. Note
+	that the vivid implementation of this is pretty basic: they are only
+	updated when you set a new frequency or when you get the tuner status
+	(VIDIOC_G_TUNER).
+
+Radio HW Seek Mode: can be one of "Bounded", "Wrap Around" or "Both". This
+	determines if VIDIOC_S_HW_FREQ_SEEK will be bounded by the frequency
+	range or wrap-around or if it is selectable by the user.
+
+Radio Programmable HW Seek: if set, then the user can provide the lower and
+	upper bound of the HW Seek. Otherwise the frequency range boundaries
+	will be used.
+
+Generate RBDS Instead of RDS: if set, then generate RBDS (the US variant of
+	RDS) data instead of RDS (European-style RDS). This affects only the
+	PICODE and PTY codes.
+
+RDS Rx I/O Mode: this can be "Block I/O" where the RDS blocks have to be read()
+	by the application, or "Controls" where the RDS data is provided by
+	the RDS controls mentioned above.
+
+
+Section 9.7: FM Radio Modulator Controls
+----------------------------------------
+
+RDS Program ID:
+RDS Program Type:
+RDS PS Name:
+RDS Radio Text:
+RDS Stereo:
+RDS Artificial Head:
+RDS Compressed:
+RDS Dymanic PTY:
+RDS Traffic Announcement:
+RDS Traffic Program:
+RDS Music: these are all controls that set the RDS data that is transmitted by
+	the FM modulator.
+
+RDS Tx I/O Mode: this can be "Block I/O" where the application has to use write()
+	to pass the RDS blocks to the driver, or "Controls" where the RDS data is
+	provided by the RDS controls mentioned above.
+
+
+Section 10: Video, VBI and RDS Looping
+--------------------------------------
+
+The vivid driver supports looping of video output to video input, VBI output
+to VBI input and RDS output to RDS input. For video/VBI looping this emulates
+as if a cable was hooked up between the output and input connector. So video
+and VBI looping is only supported between S-Video and HDMI inputs and outputs.
+VBI is only valid for S-Video as it makes no sense for HDMI.
+
+Since radio is wireless this looping always happens if the radio receiver
+frequency is close to the radio transmitter frequency. In that case the radio
+transmitter will 'override' the emulated radio stations.
+
+Looping is currently supported only between devices created by the same
+vivid driver instance.
+
+
+Section 10.1: Video and Sliced VBI looping
+------------------------------------------
+
+The way to enable video/VBI looping is currently fairly crude. A 'Loop Video'
+control is available in the "Vivid" control class of the video
+output and VBI output devices. When checked the video looping will be enabled.
+Once enabled any video S-Video or HDMI input will show a static test pattern
+until the video output has started. At that time the video output will be
+looped to the video input provided that:
+
+- the input type matches the output type. So the HDMI input cannot receive
+  video from the S-Video output.
+
+- the video resolution of the video input must match that of the video output.
+  So it is not possible to loop a 50 Hz (720x576) S-Video output to a 60 Hz
+  (720x480) S-Video input, or a 720p60 HDMI output to a 1080p30 input.
+
+- the pixel formats must be identical on both sides. Otherwise the driver would
+  have to do pixel format conversion as well, and that's taking things too far.
+
+- the field settings must be identical on both sides. Same reason as above:
+  requiring the driver to convert from one field format to another complicated
+  matters too much. This also prohibits capturing with 'Field Top' or 'Field
+  Bottom' when the output video is set to 'Field Alternate'. This combination,
+  while legal, became too complicated to support. Both sides have to be 'Field
+  Alternate' for this to work. Also note that for this specific case the
+  sequence and field counting in struct v4l2_buffer on the capture side may not
+  be 100% accurate.
+
+- 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
+  valid signal is passed to the video input.
+
+The framerates do not have to match, although this might change in the future.
+
+By default you will see the OSD text superimposed on top of the looped video.
+This can be turned off by changing the "OSD Text Mode" control of the video
+capture device.
+
+For VBI looping to work all of the above must be valid and in addition the vbi
+output must be configured for sliced VBI. The VBI capture side can be configured
+for either raw or sliced VBI. Note that at the moment only CC/XDS (60 Hz formats)
+and WSS (50 Hz formats) VBI data is looped. Teletext VBI data is not looped.
+
+
+Section 10.2: Radio & RDS Looping
+---------------------------------
+
+As mentioned in section 6 the radio receiver emulates stations are regular
+frequency intervals. Depending on the frequency of the radio receiver a
+signal strength value is calculated (this is returned by VIDIOC_G_TUNER).
+However, it will also look at the frequency set by the radio transmitter and
+if that results in a higher signal strength than the settings of the radio
+transmitter will be used as if it was a valid station. This also includes
+the RDS data (if any) that the transmitter 'transmits'. This is received
+faithfully on the receiver side. Note that when the driver is loaded the
+frequencies of the radio receiver and transmitter are not identical, so
+initially no looping takes place.
+
+
+Section 11: Cropping, Composing, Scaling
+----------------------------------------
+
+This driver supports cropping, composing and scaling in any combination. Normally
+which features are supported can be selected through the Vivid controls,
+but it is also possible to hardcode it when the module is loaded through the
+ccs_cap_mode and ccs_out_mode module options. See section 1 on the details of
+these module options.
+
+This allows you to test your application for all these variations.
+
+Note that the webcam input never supports cropping, composing or scaling. That
+only applies to the TV/S-Video/HDMI inputs and outputs. The reason is that
+webcams, including this virtual implementation, normally use
+VIDIOC_ENUM_FRAMESIZES to list a set of discrete framesizes that it supports.
+And that does not combine with cropping, composing or scaling. This is
+primarily a limitation of the V4L2 API which is carefully reproduced here.
+
+The minimum and maximum resolutions that the scaler can achieve are 16x16 and
+(4096 * 4) x (2160 x 4), but it can only scale up or down by a factor of 4 or
+less. So for a source resolution of 1280x720 the minimum the scaler can do is
+320x180 and the maximum is 5120x2880. You can play around with this using the
+qv4l2 test tool and you will see these dependencies.
+
+This driver also supports larger 'bytesperline' settings, something that
+VIDIOC_S_FMT allows but that few drivers implement.
+
+The scaler is a simple scaler that uses the Coarse Bresenham algorithm. It's
+designed for speed and simplicity, not quality.
+
+If the combination of crop, compose and scaling allows it, then it is possible
+to change crop and compose rectangles on the fly.
+
+
+Section 12: Formats
+-------------------
+
+The driver supports all the regular packed YUYV formats, 16, 24 and 32 RGB
+packed formats and two multiplanar formats (one luma and one chroma plane).
+
+The alpha component can be set through the 'Alpha Component' User control
+for those formats that support it. If the 'Apply Alpha To Red Only' control
+is set, then the alpha component is only used for the color red and set to
+0 otherwise.
+
+The driver has to be configured to support the multiplanar formats. By default
+the first driver instance is single-planar, the second is multi-planar, and it
+keeps alternating. This can be changed by setting the multiplanar module option,
+see section 1 for more details on that option.
+
+If the driver instance is using the multiplanar formats/API, then the first
+single planar format (YUYV) and the multiplanar NV16M and NV61M formats the
+will have a plane that has a non-zero data_offset of 128 bytes. It is rare for
+data_offset to be non-zero, so this is a useful feature for testing applications.
+
+Video output will also honor any data_offset that the application set.
+
+
+Section 13: Capture Overlay
+---------------------------
+
+Note: capture overlay support is implemented primarily to test the existing
+V4L2 capture overlay API. In practice few if any GPUs support such overlays
+anymore, and neither are they generally needed anymore since modern hardware
+is so much more capable. By setting flag 0x10000 in the node_types module
+option the vivid driver will create a simple framebuffer device that can be
+used for testing this API. Whether this API should be used for new drivers is
+questionable.
+
+This driver has support for a destructive capture overlay with bitmap clipping
+and list clipping (up to 16 rectangles) capabilities. Overlays are not
+supported for multiplanar formats. It also honors the struct v4l2_window field
+setting: if it is set to FIELD_TOP or FIELD_BOTTOM and the capture setting is
+FIELD_ALTERNATE, then only the top or bottom fields will be copied to the overlay.
+
+The overlay only works if you are also capturing at that same time. This is a
+vivid limitation since it copies from a buffer to the overlay instead of
+filling the overlay directly. And if you are not capturing, then no buffers
+are available to fill.
+
+In addition, the pixelformat of the capture format and that of the framebuffer
+must be the same for the overlay to work. Otherwise VIDIOC_OVERLAY will return
+an error.
+
+In order to really see what it going on you will need to create two vivid
+instances: the first with a framebuffer enabled. You configure the capture
+overlay of the second instance to use the framebuffer of the first, then
+you start capturing in the second instance. For the first instance you setup
+the output overlay for the video output, turn on video looping and capture
+to see the blended framebuffer overlay that's being written to by the second
+instance. This setup would require the following commands:
+
+	$ sudo modprobe vivid n_devs=2 node_types=0x10101,0x1 multiplanar=1,1
+	$ v4l2-ctl -d1 --find-fb
+	/dev/fb1 is the framebuffer associated with base address 0x12800000
+	$ sudo v4l2-ctl -d2 --set-fbuf fb=1
+	$ v4l2-ctl -d1 --set-fbuf fb=1
+	$ v4l2-ctl -d0 --set-fmt-video=pixelformat='AR15'
+	$ v4l2-ctl -d1 --set-fmt-video-out=pixelformat='AR15'
+	$ v4l2-ctl -d2 --set-fmt-video=pixelformat='AR15'
+	$ v4l2-ctl -d0 -i2
+	$ v4l2-ctl -d2 -i2
+	$ v4l2-ctl -d2 -c horizontal_movement=4
+	$ v4l2-ctl -d1 --overlay=1
+	$ v4l2-ctl -d1 -c loop_video=1
+	$ v4l2-ctl -d2 --stream-mmap --overlay=1
+
+And from another console:
+
+	$ v4l2-ctl -d1 --stream-out-mmap
+
+And yet another console:
+
+	$ qv4l2
+
+and start streaming.
+
+As you can see, this is not for the faint of heart...
+
+
+Section 14: Output Overlay
+--------------------------
+
+Note: output overlays are primarily implemented in order to test the existing
+V4L2 output overlay API. Whether this API should be used for new drivers is
+questionable.
+
+This driver has support for an output overlay and is capable of:
+
+	- bitmap clipping,
+	- list clipping (up to 16 rectangles)
+	- chromakey
+	- source chromakey
+	- global alpha
+	- local alpha
+	- local inverse alpha
+
+Output overlays are not supported for multiplanar formats. In addition, the
+pixelformat of the capture format and that of the framebuffer must be the
+same for the overlay to work. Otherwise VIDIOC_OVERLAY will return an error.
+
+Output overlays only work if the driver has been configured to create a
+framebuffer by setting flag 0x10000 in the node_types module option. The
+created framebuffer has a size of 720x576 and supports ARGB 1:5:5:5 and
+RGB 5:6:5.
+
+In order to see the effects of the various clipping, chromakeying or alpha
+processing capabilities you need to turn on video looping and see the results
+on the capture side. The use of the clipping, chromakeying or alpha processing
+capabilities will slow down the video loop considerably as a lot of checks have
+to be done per pixel.
+
+
+Section 15: Some Future Improvements
+------------------------------------
+
+Just as a reminder and in no particular order:
+
+- Add a virtual alsa driver to test audio
+- Add virtual sub-devices and media controller support
+- Some support for testing compressed video
+- Add support to loop raw VBI output to raw VBI input
+- Add support to loop teletext sliced VBI output to VBI input
+- Fix sequence/field numbering when looping of video with alternate fields
+- Add support for V4L2_CID_BG_COLOR for video outputs
+- Add ARGB888 overlay support: better testing of the alpha channel
+- Add custom DV timings support
+- Add support for V4L2_DV_FL_REDUCED_FPS
+- Improve pixel aspect support in the tpg code by passing a real v4l2_fract
+- Use per-queue locks and/or per-device locks to improve throughput
+- Add support to loop from a specific output to a specific input across
+  vivid instances
+- Add support for VIDIOC_EXPBUF once support for that has been added to vb2
+- The SDR radio should use the same 'frequencies' for stations as the normal
+  radio receiver, and give back noise if the frequency doesn't match up with
+  a station frequency
+- Improve the sine generation of the SDR radio.
+- Make a thread for the RDS generation, that would help in particular for the
+  "Controls" RDS Rx I/O Mode as the read-only RDS controls could be updated
+  in real-time.

+ 27 - 1
MAINTAINERS

@@ -4177,6 +4177,16 @@ L:	linuxppc-dev@lists.ozlabs.org
 S:	Odd Fixes
 F:	drivers/tty/hvc/
 
+HACKRF 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/usb/hackrf/
+
 HARDWARE MONITORING
 M:	Jean Delvare <jdelvare@suse.de>
 M:	Guenter Roeck <linux@roeck-us.net>
@@ -5070,7 +5080,7 @@ 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/tuner_it913x*
+F:	drivers/media/tuners/it913x*
 
 IVTV VIDEO4LINUX DRIVER
 M:	Andy Walls <awalls@md.metrocast.net>
@@ -8588,6 +8598,14 @@ F:	include/sound/dmaengine_pcm.h
 F:	sound/core/pcm_dmaengine.c
 F:	sound/soc/soc-generic-dmaengine-pcm.c
 
+SP2 MEDIA DRIVER
+M:	Olli Salonen <olli.salonen@iki.fi>
+L:	linux-media@vger.kernel.org
+W:	http://linuxtv.org/
+Q:	http://patchwork.linuxtv.org/project/linux-media/list/
+S:	Maintained
+F:	drivers/media/dvb-frontends/sp2*
+
 SPARC + UltraSPARC (sparc/sparc64)
 M:	"David S. Miller" <davem@davemloft.net>
 L:	sparclinux@vger.kernel.org
@@ -9293,6 +9311,14 @@ T:	git git://linuxtv.org/media_tree.git
 S:	Odd fixes
 F:	drivers/media/usb/tm6000/
 
+TW68 VIDEO4LINUX DRIVER
+M:	Hans Verkuil <hverkuil@xs4all.nl>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+W:	http://linuxtv.org
+S:	Odd Fixes
+F:	drivers/media/pci/tw68/
+
 TPM DEVICE DRIVER
 M:	Peter Huewe <peterhuewe@gmx.de>
 M:	Ashley Lai <ashley@ashleylai.com>

+ 1 - 1
drivers/media/common/b2c2/flexcop.h

@@ -4,7 +4,7 @@
  * see flexcop.c for copyright information
  */
 #ifndef __FLEXCOP_H__
-#define __FLEXCOP_H___
+#define __FLEXCOP_H__
 
 #define FC_LOG_PREFIX "b2c2-flexcop"
 #include "flexcop-common.h"

+ 0 - 3
drivers/media/common/saa7146/saa7146_fops.c

@@ -311,7 +311,6 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
 		}
 	default:
 		BUG();
-		return 0;
 	}
 
 	if (mutex_lock_interruptible(vdev->lock))
@@ -399,7 +398,6 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
 		return -EINVAL;
 	default:
 		BUG();
-		return 0;
 	}
 }
 
@@ -423,7 +421,6 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou
 		return -EINVAL;
 	default:
 		BUG();
-		return -EINVAL;
 	}
 }
 

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

@@ -157,6 +157,12 @@ static struct sms_board sms_boards[] = {
 		.type = SMS_DENVER_2160,
 		.default_mode = DEVICE_MODE_DAB_TDMB,
 	},
+	[SMS1XXX_BOARD_PCTV_77E] = {
+		.name	= "Hauppauge microStick 77e",
+		.type	= SMS_NOVA_B0,
+		.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_NOVA_12MHZ_B0,
+		.default_mode = DEVICE_MODE_DVBT_BDA,
+	},
 };
 
 struct sms_board *sms_get_board(unsigned id)

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

@@ -45,6 +45,7 @@
 #define SMS1XXX_BOARD_SIANO_RIO		18
 #define SMS1XXX_BOARD_SIANO_DENVER_1530	19
 #define SMS1XXX_BOARD_SIANO_DENVER_2160 20
+#define SMS1XXX_BOARD_PCTV_77E		21
 
 struct sms_board_gpio_cfg {
 	int lna_vhf_exist;

+ 1 - 3
drivers/media/common/siano/smscoreapi.c

@@ -2129,8 +2129,6 @@ int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 pin_num,
 
 static int __init smscore_module_init(void)
 {
-	int rc = 0;
-
 	INIT_LIST_HEAD(&g_smscore_notifyees);
 	INIT_LIST_HEAD(&g_smscore_devices);
 	kmutex_init(&g_smscore_deviceslock);
@@ -2138,7 +2136,7 @@ static int __init smscore_module_init(void)
 	INIT_LIST_HEAD(&g_smscore_registry);
 	kmutex_init(&g_smscore_registrylock);
 
-	return rc;
+	return 0;
 }
 
 static void __exit smscore_module_exit(void)

+ 5 - 2
drivers/media/dvb-core/dmxdev.c

@@ -1087,8 +1087,8 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
 	struct dmxdev_filter *dmxdevfilter = file->private_data;
 	unsigned int mask = 0;
 
-	if (!dmxdevfilter)
-		return -EINVAL;
+	if ((!dmxdevfilter) || dmxdevfilter->dev->exit)
+		return POLLERR;
 
 	poll_wait(file, &dmxdevfilter->buffer.queue, wait);
 
@@ -1181,6 +1181,9 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
 
 	dprintk("function : %s\n", __func__);
 
+	if (dmxdev->exit)
+		return POLLERR;
+
 	poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
 
 	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {

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

@@ -144,6 +144,7 @@
 #define USB_PID_ITETECH_IT9135				0x9135
 #define USB_PID_ITETECH_IT9135_9005			0x9005
 #define USB_PID_ITETECH_IT9135_9006			0x9006
+#define USB_PID_ITETECH_IT9303				0x9306
 #define USB_PID_KWORLD_399U				0xe399
 #define USB_PID_KWORLD_399U_2				0xe400
 #define USB_PID_KWORLD_395U				0xe396
@@ -244,6 +245,7 @@
 #define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM	0x3009
 #define USB_PID_TECHNOTREND_CONNECT_CT3650		0x300d
+#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI		0x3012
 #define USB_PID_TECHNOTREND_TVSTICK_CT2_4400		0x3014
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2	0x0081

+ 32 - 13
drivers/media/dvb-core/dvb_frontend.c

@@ -1934,15 +1934,13 @@ static int dvb_frontend_ioctl_properties(struct file *file,
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int err = 0;
 
-	struct dtv_properties *tvps = NULL;
+	struct dtv_properties *tvps = parg;
 	struct dtv_property *tvp = NULL;
 	int i;
 
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
-	if(cmd == FE_SET_PROPERTY) {
-		tvps = (struct dtv_properties __user *)parg;
-
+	if (cmd == FE_SET_PROPERTY) {
 		dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
 		dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
 
@@ -1957,7 +1955,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
 			goto out;
 		}
 
-		if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
+		if (copy_from_user(tvp, (void __user *)tvps->props,
+				   tvps->num * sizeof(struct dtv_property))) {
 			err = -EFAULT;
 			goto out;
 		}
@@ -1972,10 +1971,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
 		if (c->state == DTV_TUNE)
 			dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__);
 
-	} else
-	if(cmd == FE_GET_PROPERTY) {
-		tvps = (struct dtv_properties __user *)parg;
-
+	} else if (cmd == FE_GET_PROPERTY) {
 		dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
 		dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
 
@@ -1990,7 +1986,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
 			goto out;
 		}
 
-		if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
+		if (copy_from_user(tvp, (void __user *)tvps->props,
+				   tvps->num * sizeof(struct dtv_property))) {
 			err = -EFAULT;
 			goto out;
 		}
@@ -2012,7 +2009,8 @@ static int dvb_frontend_ioctl_properties(struct file *file,
 			(tvp + i)->result = err;
 		}
 
-		if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
+		if (copy_to_user((void __user *)tvps->props, tvp,
+				 tvps->num * sizeof(struct dtv_property))) {
 			err = -EFAULT;
 			goto out;
 		}
@@ -2072,6 +2070,23 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
 	case SYS_DVBC_ANNEX_C:
 		rolloff = 113;
 		break;
+	case SYS_DVBS:
+	case SYS_TURBO:
+		rolloff = 135;
+		break;
+	case SYS_DVBS2:
+		switch (c->rolloff) {
+		case ROLLOFF_20:
+			rolloff = 120;
+			break;
+		case ROLLOFF_25:
+			rolloff = 125;
+			break;
+		default:
+		case ROLLOFF_35:
+			rolloff = 135;
+		}
+		break;
 	default:
 		break;
 	}
@@ -2550,7 +2565,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
 	dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
 			fe->id);
 
-	if (fe->ops.tuner_ops.sleep)
+	if (fe->ops.tuner_ops.suspend)
+		ret = fe->ops.tuner_ops.suspend(fe);
+	else if (fe->ops.tuner_ops.sleep)
 		ret = fe->ops.tuner_ops.sleep(fe);
 
 	if (fe->ops.sleep)
@@ -2572,7 +2589,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
 	if (fe->ops.init)
 		ret = fe->ops.init(fe);
 
-	if (fe->ops.tuner_ops.init)
+	if (fe->ops.tuner_ops.resume)
+		ret = fe->ops.tuner_ops.resume(fe);
+	else if (fe->ops.tuner_ops.init)
 		ret = fe->ops.tuner_ops.init(fe);
 
 	fe->exit = DVB_FE_NO_EXIT;

+ 2 - 0
drivers/media/dvb-core/dvb_frontend.h

@@ -201,6 +201,8 @@ struct dvb_tuner_ops {
 	int (*release)(struct dvb_frontend *fe);
 	int (*init)(struct dvb_frontend *fe);
 	int (*sleep)(struct dvb_frontend *fe);
+	int (*suspend)(struct dvb_frontend *fe);
+	int (*resume)(struct dvb_frontend *fe);
 
 	/** This is for simple PLLs - set all parameters in one go. */
 	int (*set_params)(struct dvb_frontend *fe);

+ 26 - 0
drivers/media/dvb-core/dvb_ringbuffer.c

@@ -166,6 +166,31 @@ ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t
 	return len;
 }
 
+ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
+				  const u8 __user *buf, size_t len)
+{
+	int status;
+	size_t todo = len;
+	size_t split;
+
+	split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
+
+	if (split > 0) {
+		status = copy_from_user(rbuf->data+rbuf->pwrite, buf, split);
+		if (status)
+			return len - todo;
+		buf += split;
+		todo -= split;
+		rbuf->pwrite = 0;
+	}
+	status = copy_from_user(rbuf->data+rbuf->pwrite, buf, todo);
+	if (status)
+		return len - todo;
+	rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
+
+	return len;
+}
+
 ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
 {
 	int status;
@@ -297,3 +322,4 @@ EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
 EXPORT_SYMBOL(dvb_ringbuffer_read_user);
 EXPORT_SYMBOL(dvb_ringbuffer_read);
 EXPORT_SYMBOL(dvb_ringbuffer_write);
+EXPORT_SYMBOL(dvb_ringbuffer_write_user);

+ 2 - 0
drivers/media/dvb-core/dvb_ringbuffer.h

@@ -133,6 +133,8 @@ extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
 */
 extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
 				    size_t len);
+extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
+				         const u8 __user *buf, size_t len);
 
 
 /**

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

@@ -471,6 +471,11 @@ config DVB_SI2168
 	help
 	  Say Y when you want to support this frontend.
 
+config DVB_AS102_FE
+	tristate
+	depends on DVB_CORE
+	default DVB_AS102
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
@@ -643,6 +648,14 @@ config DVB_MB86A20S
 	  A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
 	  Say Y when you want to support this frontend.
 
+config DVB_TC90522
+	tristate "Toshiba TC90522"
+	depends on DVB_CORE && I2C
+	default m if !MEDIA_SUBDRV_AUTOSELECT
+	help
+	  A Toshiba TC90522 2xISDB-T + 2xISDB-S demodulator.
+	  Say Y when you want to support this frontend.
+
 comment "Digital terrestrial only tuners/PLL"
 	depends on DVB_CORE
 
@@ -720,6 +733,13 @@ config DVB_A8293
 	depends on DVB_CORE && I2C
 	default m if !MEDIA_SUBDRV_AUTOSELECT
 
+config DVB_SP2
+	tristate "CIMaX SP2"
+	depends on DVB_CORE && I2C
+	default m if !MEDIA_SUBDRV_AUTOSELECT
+	help
+	  CIMaX SP2/SP2HF Common Interface module.
+
 config DVB_LGS8GL5
 	tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
 	depends on DVB_CORE && I2C

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

@@ -107,10 +107,12 @@ obj-$(CONFIG_DVB_DRXK) += drxk.o
 obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
 obj-$(CONFIG_DVB_SI2165) += si2165.o
 obj-$(CONFIG_DVB_A8293) += a8293.o
+obj-$(CONFIG_DVB_SP2) += sp2.o
 obj-$(CONFIG_DVB_TDA10071) += tda10071.o
 obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
 obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
 obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
 obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
 obj-$(CONFIG_DVB_AF9033) += af9033.o
-
+obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
+obj-$(CONFIG_DVB_TC90522) += tc90522.o

+ 12 - 12
drivers/media/dvb-frontends/af9013.c

@@ -683,7 +683,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
 
 	switch (c->transmission_mode) {
 	case TRANSMISSION_MODE_AUTO:
-		auto_mode = 1;
+		auto_mode = true;
 		break;
 	case TRANSMISSION_MODE_2K:
 		break;
@@ -693,12 +693,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
 	default:
 		dev_dbg(&state->i2c->dev, "%s: invalid transmission_mode\n",
 				__func__);
-		auto_mode = 1;
+		auto_mode = true;
 	}
 
 	switch (c->guard_interval) {
 	case GUARD_INTERVAL_AUTO:
-		auto_mode = 1;
+		auto_mode = true;
 		break;
 	case GUARD_INTERVAL_1_32:
 		break;
@@ -714,12 +714,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
 	default:
 		dev_dbg(&state->i2c->dev, "%s: invalid guard_interval\n",
 				__func__);
-		auto_mode = 1;
+		auto_mode = true;
 	}
 
 	switch (c->hierarchy) {
 	case HIERARCHY_AUTO:
-		auto_mode = 1;
+		auto_mode = true;
 		break;
 	case HIERARCHY_NONE:
 		break;
@@ -734,12 +734,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
 		break;
 	default:
 		dev_dbg(&state->i2c->dev, "%s: invalid hierarchy\n", __func__);
-		auto_mode = 1;
+		auto_mode = true;
 	}
 
 	switch (c->modulation) {
 	case QAM_AUTO:
-		auto_mode = 1;
+		auto_mode = true;
 		break;
 	case QPSK:
 		break;
@@ -751,7 +751,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
 		break;
 	default:
 		dev_dbg(&state->i2c->dev, "%s: invalid modulation\n", __func__);
-		auto_mode = 1;
+		auto_mode = true;
 	}
 
 	/* Use HP. How and which case we can switch to LP? */
@@ -759,7 +759,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
 
 	switch (c->code_rate_HP) {
 	case FEC_AUTO:
-		auto_mode = 1;
+		auto_mode = true;
 		break;
 	case FEC_1_2:
 		break;
@@ -778,12 +778,12 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
 	default:
 		dev_dbg(&state->i2c->dev, "%s: invalid code_rate_HP\n",
 				__func__);
-		auto_mode = 1;
+		auto_mode = true;
 	}
 
 	switch (c->code_rate_LP) {
 	case FEC_AUTO:
-		auto_mode = 1;
+		auto_mode = true;
 		break;
 	case FEC_1_2:
 		break;
@@ -804,7 +804,7 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
 	default:
 		dev_dbg(&state->i2c->dev, "%s: invalid code_rate_LP\n",
 				__func__);
-		auto_mode = 1;
+		auto_mode = true;
 	}
 
 	switch (c->bandwidth_hz) {

+ 425 - 332
drivers/media/dvb-frontends/af9033.c

@@ -24,29 +24,35 @@
 /* Max transfer size done by I2C transfer functions */
 #define MAX_XFER_SIZE  64
 
-struct af9033_state {
-	struct i2c_adapter *i2c;
+struct af9033_dev {
+	struct i2c_client *client;
 	struct dvb_frontend fe;
 	struct af9033_config cfg;
+	bool is_af9035;
+	bool is_it9135;
 
 	u32 bandwidth_hz;
 	bool ts_mode_parallel;
 	bool ts_mode_serial;
 
-	u32 ber;
-	u32 ucb;
-	unsigned long last_stat_check;
+	fe_status_t fe_status;
+	u64 post_bit_error_prev; /* for old read_ber we return (curr - prev) */
+	u64 post_bit_error;
+	u64 post_bit_count;
+	u64 error_block_count;
+	u64 total_block_count;
+	struct delayed_work stat_work;
 };
 
 /* write multiple registers */
-static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
+static int af9033_wr_regs(struct af9033_dev *dev, u32 reg, const u8 *val,
 		int len)
 {
 	int ret;
 	u8 buf[MAX_XFER_SIZE];
 	struct i2c_msg msg[1] = {
 		{
-			.addr = state->cfg.i2c_addr,
+			.addr = dev->client->addr,
 			.flags = 0,
 			.len = 3 + len,
 			.buf = buf,
@@ -54,9 +60,9 @@ static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
 	};
 
 	if (3 + len > sizeof(buf)) {
-		dev_warn(&state->i2c->dev,
-			 "%s: i2c wr reg=%04x: len=%d is too big!\n",
-			 KBUILD_MODNAME, reg, len);
+		dev_warn(&dev->client->dev,
+				"i2c wr reg=%04x: len=%d is too big!\n",
+				reg, len);
 		return -EINVAL;
 	}
 
@@ -65,12 +71,12 @@ static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
 	buf[2] = (reg >>  0) & 0xff;
 	memcpy(&buf[3], val, len);
 
-	ret = i2c_transfer(state->i2c, msg, 1);
+	ret = i2c_transfer(dev->client->adapter, msg, 1);
 	if (ret == 1) {
 		ret = 0;
 	} else {
-		dev_warn(&state->i2c->dev, "%s: i2c wr failed=%d reg=%06x " \
-				"len=%d\n", KBUILD_MODNAME, ret, reg, len);
+		dev_warn(&dev->client->dev, "i2c wr failed=%d reg=%06x len=%d\n",
+				ret, reg, len);
 		ret = -EREMOTEIO;
 	}
 
@@ -78,31 +84,31 @@ static int af9033_wr_regs(struct af9033_state *state, u32 reg, const u8 *val,
 }
 
 /* read multiple registers */
-static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
+static int af9033_rd_regs(struct af9033_dev *dev, u32 reg, u8 *val, int len)
 {
 	int ret;
 	u8 buf[3] = { (reg >> 16) & 0xff, (reg >> 8) & 0xff,
 			(reg >> 0) & 0xff };
 	struct i2c_msg msg[2] = {
 		{
-			.addr = state->cfg.i2c_addr,
+			.addr = dev->client->addr,
 			.flags = 0,
 			.len = sizeof(buf),
 			.buf = buf
 		}, {
-			.addr = state->cfg.i2c_addr,
+			.addr = dev->client->addr,
 			.flags = I2C_M_RD,
 			.len = len,
 			.buf = val
 		}
 	};
 
-	ret = i2c_transfer(state->i2c, msg, 2);
+	ret = i2c_transfer(dev->client->adapter, msg, 2);
 	if (ret == 2) {
 		ret = 0;
 	} else {
-		dev_warn(&state->i2c->dev, "%s: i2c rd failed=%d reg=%06x " \
-				"len=%d\n", KBUILD_MODNAME, ret, reg, len);
+		dev_warn(&dev->client->dev, "i2c rd failed=%d reg=%06x len=%d\n",
+				ret, reg, len);
 		ret = -EREMOTEIO;
 	}
 
@@ -111,19 +117,19 @@ static int af9033_rd_regs(struct af9033_state *state, u32 reg, u8 *val, int len)
 
 
 /* write single register */
-static int af9033_wr_reg(struct af9033_state *state, u32 reg, u8 val)
+static int af9033_wr_reg(struct af9033_dev *dev, u32 reg, u8 val)
 {
-	return af9033_wr_regs(state, reg, &val, 1);
+	return af9033_wr_regs(dev, reg, &val, 1);
 }
 
 /* read single register */
-static int af9033_rd_reg(struct af9033_state *state, u32 reg, u8 *val)
+static int af9033_rd_reg(struct af9033_dev *dev, u32 reg, u8 *val)
 {
-	return af9033_rd_regs(state, reg, val, 1);
+	return af9033_rd_regs(dev, reg, val, 1);
 }
 
 /* write single register with mask */
-static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
+static int af9033_wr_reg_mask(struct af9033_dev *dev, u32 reg, u8 val,
 		u8 mask)
 {
 	int ret;
@@ -131,7 +137,7 @@ static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
 
 	/* no need for read if whole reg is written */
 	if (mask != 0xff) {
-		ret = af9033_rd_regs(state, reg, &tmp, 1);
+		ret = af9033_rd_regs(dev, reg, &tmp, 1);
 		if (ret)
 			return ret;
 
@@ -140,17 +146,17 @@ static int af9033_wr_reg_mask(struct af9033_state *state, u32 reg, u8 val,
 		val |= tmp;
 	}
 
-	return af9033_wr_regs(state, reg, &val, 1);
+	return af9033_wr_regs(dev, reg, &val, 1);
 }
 
 /* read single register with mask */
-static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
+static int af9033_rd_reg_mask(struct af9033_dev *dev, u32 reg, u8 *val,
 		u8 mask)
 {
 	int ret, i;
 	u8 tmp;
 
-	ret = af9033_rd_regs(state, reg, &tmp, 1);
+	ret = af9033_rd_regs(dev, reg, &tmp, 1);
 	if (ret)
 		return ret;
 
@@ -167,18 +173,17 @@ static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
 }
 
 /* write reg val table using reg addr auto increment */
-static int af9033_wr_reg_val_tab(struct af9033_state *state,
+static int af9033_wr_reg_val_tab(struct af9033_dev *dev,
 		const struct reg_val *tab, int tab_len)
 {
 #define MAX_TAB_LEN 212
 	int ret, i, j;
 	u8 buf[1 + MAX_TAB_LEN];
 
-	dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
+	dev_dbg(&dev->client->dev, "tab_len=%d\n", tab_len);
 
 	if (tab_len > sizeof(buf)) {
-		dev_warn(&state->i2c->dev, "%s: tab len %d is too big\n",
-				KBUILD_MODNAME, tab_len);
+		dev_warn(&dev->client->dev, "tab len %d is too big\n", tab_len);
 		return -EINVAL;
 	}
 
@@ -186,7 +191,7 @@ static int af9033_wr_reg_val_tab(struct af9033_state *state,
 		buf[j] = tab[i].val;
 
 		if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1) {
-			ret = af9033_wr_regs(state, tab[i].reg - j, buf, j + 1);
+			ret = af9033_wr_regs(dev, tab[i].reg - j, buf, j + 1);
 			if (ret < 0)
 				goto err;
 
@@ -199,16 +204,16 @@ static int af9033_wr_reg_val_tab(struct af9033_state *state,
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
-static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x)
+static u32 af9033_div(struct af9033_dev *dev, u32 a, u32 b, u32 x)
 {
 	u32 r = 0, c = 0, i;
 
-	dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d\n", __func__, a, b, x);
+	dev_dbg(&dev->client->dev, "a=%d b=%d x=%d\n", a, b, x);
 
 	if (a > b) {
 		c = a / b;
@@ -225,22 +230,15 @@ static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x)
 	}
 	r = (c << (u32)x) + r;
 
-	dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d r=%d r=%x\n",
-			__func__, a, b, x, r, r);
+	dev_dbg(&dev->client->dev, "a=%d b=%d x=%d r=%d r=%x\n", a, b, x, r, r);
 
 	return r;
 }
 
-static void af9033_release(struct dvb_frontend *fe)
-{
-	struct af9033_state *state = fe->demodulator_priv;
-
-	kfree(state);
-}
-
 static int af9033_init(struct dvb_frontend *fe)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int ret, i, len;
 	const struct reg_val *init;
 	u8 buf[4];
@@ -248,7 +246,7 @@ static int af9033_init(struct dvb_frontend *fe)
 	struct reg_val_mask tab[] = {
 		{ 0x80fb24, 0x00, 0x08 },
 		{ 0x80004c, 0x00, 0xff },
-		{ 0x00f641, state->cfg.tuner, 0xff },
+		{ 0x00f641, dev->cfg.tuner, 0xff },
 		{ 0x80f5ca, 0x01, 0x01 },
 		{ 0x80f715, 0x01, 0x01 },
 		{ 0x00f41f, 0x04, 0x04 },
@@ -267,88 +265,82 @@ static int af9033_init(struct dvb_frontend *fe)
 		{ 0x00d830, 0x01, 0xff },
 		{ 0x00d831, 0x00, 0xff },
 		{ 0x00d832, 0x00, 0xff },
-		{ 0x80f985, state->ts_mode_serial, 0x01 },
-		{ 0x80f986, state->ts_mode_parallel, 0x01 },
+		{ 0x80f985, dev->ts_mode_serial, 0x01 },
+		{ 0x80f986, dev->ts_mode_parallel, 0x01 },
 		{ 0x00d827, 0x00, 0xff },
 		{ 0x00d829, 0x00, 0xff },
-		{ 0x800045, state->cfg.adc_multiplier, 0xff },
+		{ 0x800045, dev->cfg.adc_multiplier, 0xff },
 	};
 
 	/* program clock control */
-	clock_cw = af9033_div(state, state->cfg.clock, 1000000ul, 19ul);
+	clock_cw = af9033_div(dev, dev->cfg.clock, 1000000ul, 19ul);
 	buf[0] = (clock_cw >>  0) & 0xff;
 	buf[1] = (clock_cw >>  8) & 0xff;
 	buf[2] = (clock_cw >> 16) & 0xff;
 	buf[3] = (clock_cw >> 24) & 0xff;
 
-	dev_dbg(&state->i2c->dev, "%s: clock=%d clock_cw=%08x\n",
-			__func__, state->cfg.clock, clock_cw);
+	dev_dbg(&dev->client->dev, "clock=%d clock_cw=%08x\n",
+			dev->cfg.clock, clock_cw);
 
-	ret = af9033_wr_regs(state, 0x800025, buf, 4);
+	ret = af9033_wr_regs(dev, 0x800025, buf, 4);
 	if (ret < 0)
 		goto err;
 
 	/* program ADC control */
 	for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
-		if (clock_adc_lut[i].clock == state->cfg.clock)
+		if (clock_adc_lut[i].clock == dev->cfg.clock)
 			break;
 	}
 
-	adc_cw = af9033_div(state, clock_adc_lut[i].adc, 1000000ul, 19ul);
+	adc_cw = af9033_div(dev, clock_adc_lut[i].adc, 1000000ul, 19ul);
 	buf[0] = (adc_cw >>  0) & 0xff;
 	buf[1] = (adc_cw >>  8) & 0xff;
 	buf[2] = (adc_cw >> 16) & 0xff;
 
-	dev_dbg(&state->i2c->dev, "%s: adc=%d adc_cw=%06x\n",
-			__func__, clock_adc_lut[i].adc, adc_cw);
+	dev_dbg(&dev->client->dev, "adc=%d adc_cw=%06x\n",
+			clock_adc_lut[i].adc, adc_cw);
 
-	ret = af9033_wr_regs(state, 0x80f1cd, buf, 3);
+	ret = af9033_wr_regs(dev, 0x80f1cd, buf, 3);
 	if (ret < 0)
 		goto err;
 
 	/* program register table */
 	for (i = 0; i < ARRAY_SIZE(tab); i++) {
-		ret = af9033_wr_reg_mask(state, tab[i].reg, tab[i].val,
+		ret = af9033_wr_reg_mask(dev, tab[i].reg, tab[i].val,
 				tab[i].mask);
 		if (ret < 0)
 			goto err;
 	}
 
-	/* feed clock to RF tuner */
-	switch (state->cfg.tuner) {
-	case AF9033_TUNER_IT9135_38:
-	case AF9033_TUNER_IT9135_51:
-	case AF9033_TUNER_IT9135_52:
-	case AF9033_TUNER_IT9135_60:
-	case AF9033_TUNER_IT9135_61:
-	case AF9033_TUNER_IT9135_62:
-		ret = af9033_wr_reg(state, 0x80fba8, 0x00);
+	/* clock output */
+	if (dev->cfg.dyn0_clk) {
+		ret = af9033_wr_reg(dev, 0x80fba8, 0x00);
 		if (ret < 0)
 			goto err;
 	}
 
 	/* settings for TS interface */
-	if (state->cfg.ts_mode == AF9033_TS_MODE_USB) {
-		ret = af9033_wr_reg_mask(state, 0x80f9a5, 0x00, 0x01);
+	if (dev->cfg.ts_mode == AF9033_TS_MODE_USB) {
+		ret = af9033_wr_reg_mask(dev, 0x80f9a5, 0x00, 0x01);
 		if (ret < 0)
 			goto err;
 
-		ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x01, 0x01);
+		ret = af9033_wr_reg_mask(dev, 0x80f9b5, 0x01, 0x01);
 		if (ret < 0)
 			goto err;
 	} else {
-		ret = af9033_wr_reg_mask(state, 0x80f990, 0x00, 0x01);
+		ret = af9033_wr_reg_mask(dev, 0x80f990, 0x00, 0x01);
 		if (ret < 0)
 			goto err;
 
-		ret = af9033_wr_reg_mask(state, 0x80f9b5, 0x00, 0x01);
+		ret = af9033_wr_reg_mask(dev, 0x80f9b5, 0x00, 0x01);
 		if (ret < 0)
 			goto err;
 	}
 
 	/* load OFSM settings */
-	dev_dbg(&state->i2c->dev, "%s: load ofsm settings\n", __func__);
-	switch (state->cfg.tuner) {
+	dev_dbg(&dev->client->dev, "load ofsm settings\n");
+	switch (dev->cfg.tuner) {
 	case AF9033_TUNER_IT9135_38:
 	case AF9033_TUNER_IT9135_51:
 	case AF9033_TUNER_IT9135_52:
@@ -367,14 +359,13 @@ static int af9033_init(struct dvb_frontend *fe)
 		break;
 	}
 
-	ret = af9033_wr_reg_val_tab(state, init, len);
+	ret = af9033_wr_reg_val_tab(dev, init, len);
 	if (ret < 0)
 		goto err;
 
 	/* load tuner specific settings */
-	dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n",
-			__func__);
-	switch (state->cfg.tuner) {
+	dev_dbg(&dev->client->dev, "load tuner specific settings\n");
+	switch (dev->cfg.tuner) {
 	case AF9033_TUNER_TUA9001:
 		len = ARRAY_SIZE(tuner_init_tua9001);
 		init = tuner_init_tua9001;
@@ -424,90 +415,108 @@ static int af9033_init(struct dvb_frontend *fe)
 		init = tuner_init_it9135_62;
 		break;
 	default:
-		dev_dbg(&state->i2c->dev, "%s: unsupported tuner ID=%d\n",
-				__func__, state->cfg.tuner);
+		dev_dbg(&dev->client->dev, "unsupported tuner ID=%d\n",
+				dev->cfg.tuner);
 		ret = -ENODEV;
 		goto err;
 	}
 
-	ret = af9033_wr_reg_val_tab(state, init, len);
+	ret = af9033_wr_reg_val_tab(dev, init, len);
 	if (ret < 0)
 		goto err;
 
-	if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
-		ret = af9033_wr_reg_mask(state, 0x00d91c, 0x01, 0x01);
+	if (dev->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
+		ret = af9033_wr_reg_mask(dev, 0x00d91c, 0x01, 0x01);
 		if (ret < 0)
 			goto err;
 
-		ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01);
+		ret = af9033_wr_reg_mask(dev, 0x00d917, 0x00, 0x01);
 		if (ret < 0)
 			goto err;
 
-		ret = af9033_wr_reg_mask(state, 0x00d916, 0x00, 0x01);
+		ret = af9033_wr_reg_mask(dev, 0x00d916, 0x00, 0x01);
 		if (ret < 0)
 			goto err;
 	}
 
-	switch (state->cfg.tuner) {
+	switch (dev->cfg.tuner) {
 	case AF9033_TUNER_IT9135_60:
 	case AF9033_TUNER_IT9135_61:
 	case AF9033_TUNER_IT9135_62:
-		ret = af9033_wr_reg(state, 0x800000, 0x01);
+		ret = af9033_wr_reg(dev, 0x800000, 0x01);
 		if (ret < 0)
 			goto err;
 	}
 
-	state->bandwidth_hz = 0; /* force to program all parameters */
+	dev->bandwidth_hz = 0; /* force to program all parameters */
+	/* init stats here in order signal app which stats are supported */
+	c->strength.len = 1;
+	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->cnr.len = 1;
+	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->block_count.len = 1;
+	c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->block_error.len = 1;
+	c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->post_bit_count.len = 1;
+	c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->post_bit_error.len = 1;
+	c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	/* start statistics polling */
+	schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
 
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
 static int af9033_sleep(struct dvb_frontend *fe)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
 	int ret, i;
 	u8 tmp;
 
-	ret = af9033_wr_reg(state, 0x80004c, 1);
+	/* stop statistics polling */
+	cancel_delayed_work_sync(&dev->stat_work);
+
+	ret = af9033_wr_reg(dev, 0x80004c, 1);
 	if (ret < 0)
 		goto err;
 
-	ret = af9033_wr_reg(state, 0x800000, 0);
+	ret = af9033_wr_reg(dev, 0x800000, 0);
 	if (ret < 0)
 		goto err;
 
 	for (i = 100, tmp = 1; i && tmp; i--) {
-		ret = af9033_rd_reg(state, 0x80004c, &tmp);
+		ret = af9033_rd_reg(dev, 0x80004c, &tmp);
 		if (ret < 0)
 			goto err;
 
 		usleep_range(200, 10000);
 	}
 
-	dev_dbg(&state->i2c->dev, "%s: loop=%d\n", __func__, i);
+	dev_dbg(&dev->client->dev, "loop=%d\n", i);
 
 	if (i == 0) {
 		ret = -ETIMEDOUT;
 		goto err;
 	}
 
-	ret = af9033_wr_reg_mask(state, 0x80fb24, 0x08, 0x08);
+	ret = af9033_wr_reg_mask(dev, 0x80fb24, 0x08, 0x08);
 	if (ret < 0)
 		goto err;
 
 	/* prevent current leak (?) */
-	if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
+	if (dev->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
 		/* enable parallel TS */
-		ret = af9033_wr_reg_mask(state, 0x00d917, 0x00, 0x01);
+		ret = af9033_wr_reg_mask(dev, 0x00d917, 0x00, 0x01);
 		if (ret < 0)
 			goto err;
 
-		ret = af9033_wr_reg_mask(state, 0x00d916, 0x01, 0x01);
+		ret = af9033_wr_reg_mask(dev, 0x00d916, 0x01, 0x01);
 		if (ret < 0)
 			goto err;
 	}
@@ -515,7 +524,7 @@ static int af9033_sleep(struct dvb_frontend *fe)
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
@@ -533,14 +542,14 @@ static int af9033_get_tune_settings(struct dvb_frontend *fe,
 
 static int af9033_set_frontend(struct dvb_frontend *fe)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int ret, i, spec_inv, sampling_freq;
 	u8 tmp, buf[3], bandwidth_reg_val;
 	u32 if_frequency, freq_cw, adc_freq;
 
-	dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n",
-			__func__, c->frequency, c->bandwidth_hz);
+	dev_dbg(&dev->client->dev, "frequency=%d bandwidth_hz=%d\n",
+			c->frequency, c->bandwidth_hz);
 
 	/* check bandwidth */
 	switch (c->bandwidth_hz) {
@@ -554,8 +563,7 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
 		bandwidth_reg_val = 0x02;
 		break;
 	default:
-		dev_dbg(&state->i2c->dev, "%s: invalid bandwidth_hz\n",
-				__func__);
+		dev_dbg(&dev->client->dev, "invalid bandwidth_hz\n");
 		ret = -EINVAL;
 		goto err;
 	}
@@ -565,23 +573,23 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
 		fe->ops.tuner_ops.set_params(fe);
 
 	/* program CFOE coefficients */
-	if (c->bandwidth_hz != state->bandwidth_hz) {
+	if (c->bandwidth_hz != dev->bandwidth_hz) {
 		for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) {
-			if (coeff_lut[i].clock == state->cfg.clock &&
+			if (coeff_lut[i].clock == dev->cfg.clock &&
 				coeff_lut[i].bandwidth_hz == c->bandwidth_hz) {
 				break;
 			}
 		}
-		ret =  af9033_wr_regs(state, 0x800001,
+		ret =  af9033_wr_regs(dev, 0x800001,
 				coeff_lut[i].val, sizeof(coeff_lut[i].val));
 	}
 
 	/* program frequency control */
-	if (c->bandwidth_hz != state->bandwidth_hz) {
-		spec_inv = state->cfg.spec_inv ? -1 : 1;
+	if (c->bandwidth_hz != dev->bandwidth_hz) {
+		spec_inv = dev->cfg.spec_inv ? -1 : 1;
 
 		for (i = 0; i < ARRAY_SIZE(clock_adc_lut); i++) {
-			if (clock_adc_lut[i].clock == state->cfg.clock)
+			if (clock_adc_lut[i].clock == dev->cfg.clock)
 				break;
 		}
 		adc_freq = clock_adc_lut[i].adc;
@@ -602,12 +610,12 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
 		else
 			sampling_freq *= -1;
 
-		freq_cw = af9033_div(state, sampling_freq, adc_freq, 23ul);
+		freq_cw = af9033_div(dev, sampling_freq, adc_freq, 23ul);
 
 		if (spec_inv == -1)
 			freq_cw = 0x800000 - freq_cw;
 
-		if (state->cfg.adc_multiplier == AF9033_ADC_MULTIPLIER_2X)
+		if (dev->cfg.adc_multiplier == AF9033_ADC_MULTIPLIER_2X)
 			freq_cw /= 2;
 
 		buf[0] = (freq_cw >>  0) & 0xff;
@@ -618,26 +626,26 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
 		if (if_frequency == 0)
 			buf[2] = 0;
 
-		ret = af9033_wr_regs(state, 0x800029, buf, 3);
+		ret = af9033_wr_regs(dev, 0x800029, buf, 3);
 		if (ret < 0)
 			goto err;
 
-		state->bandwidth_hz = c->bandwidth_hz;
+		dev->bandwidth_hz = c->bandwidth_hz;
 	}
 
-	ret = af9033_wr_reg_mask(state, 0x80f904, bandwidth_reg_val, 0x03);
+	ret = af9033_wr_reg_mask(dev, 0x80f904, bandwidth_reg_val, 0x03);
 	if (ret < 0)
 		goto err;
 
-	ret = af9033_wr_reg(state, 0x800040, 0x00);
+	ret = af9033_wr_reg(dev, 0x800040, 0x00);
 	if (ret < 0)
 		goto err;
 
-	ret = af9033_wr_reg(state, 0x800047, 0x00);
+	ret = af9033_wr_reg(dev, 0x800047, 0x00);
 	if (ret < 0)
 		goto err;
 
-	ret = af9033_wr_reg_mask(state, 0x80f999, 0x00, 0x01);
+	ret = af9033_wr_reg_mask(dev, 0x80f999, 0x00, 0x01);
 	if (ret < 0)
 		goto err;
 
@@ -646,33 +654,33 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
 	else
 		tmp = 0x01; /* UHF */
 
-	ret = af9033_wr_reg(state, 0x80004b, tmp);
+	ret = af9033_wr_reg(dev, 0x80004b, tmp);
 	if (ret < 0)
 		goto err;
 
-	ret = af9033_wr_reg(state, 0x800000, 0x00);
+	ret = af9033_wr_reg(dev, 0x800000, 0x00);
 	if (ret < 0)
 		goto err;
 
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
 static int af9033_get_frontend(struct dvb_frontend *fe)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int ret;
 	u8 buf[8];
 
-	dev_dbg(&state->i2c->dev, "%s:\n", __func__);
+	dev_dbg(&dev->client->dev, "\n");
 
 	/* read all needed registers */
-	ret = af9033_rd_regs(state, 0x80f900, buf, sizeof(buf));
+	ret = af9033_rd_regs(dev, 0x80f900, buf, sizeof(buf));
 	if (ret < 0)
 		goto err;
 
@@ -784,21 +792,21 @@ static int af9033_get_frontend(struct dvb_frontend *fe)
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
 static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
 	int ret;
 	u8 tmp;
 
 	*status = 0;
 
 	/* radio channel status, 0=no result, 1=has signal, 2=no signal */
-	ret = af9033_rd_reg(state, 0x800047, &tmp);
+	ret = af9033_rd_reg(dev, 0x800047, &tmp);
 	if (ret < 0)
 		goto err;
 
@@ -808,7 +816,7 @@ static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
 
 	if (tmp != 0x02) {
 		/* TPS lock */
-		ret = af9033_rd_reg_mask(state, 0x80f5a9, &tmp, 0x01);
+		ret = af9033_rd_reg_mask(dev, 0x80f5a9, &tmp, 0x01);
 		if (ret < 0)
 			goto err;
 
@@ -817,7 +825,7 @@ static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
 					FE_HAS_VITERBI;
 
 		/* full lock */
-		ret = af9033_rd_reg_mask(state, 0x80f999, &tmp, 0x01);
+		ret = af9033_rd_reg_mask(dev, 0x80f999, &tmp, 0x01);
 		if (ret < 0)
 			goto err;
 
@@ -827,76 +835,38 @@ static int af9033_read_status(struct dvb_frontend *fe, fe_status_t *status)
 					FE_HAS_LOCK;
 	}
 
+	dev->fe_status = *status;
+
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
 static int af9033_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
-	struct af9033_state *state = fe->demodulator_priv;
-	int ret, i, len;
-	u8 buf[3], tmp;
-	u32 snr_val;
-	const struct val_snr *uninitialized_var(snr_lut);
-
-	/* read value */
-	ret = af9033_rd_regs(state, 0x80002c, buf, 3);
-	if (ret < 0)
-		goto err;
+	struct af9033_dev *dev = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
 
-	snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0];
-
-	/* read current modulation */
-	ret = af9033_rd_reg(state, 0x80f903, &tmp);
-	if (ret < 0)
-		goto err;
-
-	switch ((tmp >> 0) & 3) {
-	case 0:
-		len = ARRAY_SIZE(qpsk_snr_lut);
-		snr_lut = qpsk_snr_lut;
-		break;
-	case 1:
-		len = ARRAY_SIZE(qam16_snr_lut);
-		snr_lut = qam16_snr_lut;
-		break;
-	case 2:
-		len = ARRAY_SIZE(qam64_snr_lut);
-		snr_lut = qam64_snr_lut;
-		break;
-	default:
-		goto err;
-	}
-
-	for (i = 0; i < len; i++) {
-		tmp = snr_lut[i].snr;
-
-		if (snr_val < snr_lut[i].val)
-			break;
-	}
-
-	*snr = tmp * 10; /* dB/10 */
+	/* use DVBv5 CNR */
+	if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
+		*snr = div_s64(c->cnr.stat[0].svalue, 100); /* 1000x => 10x */
+	else
+		*snr = 0;
 
 	return 0;
-
-err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
-
-	return ret;
 }
 
 static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
 	int ret;
 	u8 strength2;
 
 	/* read signal strength of 0-100 scale */
-	ret = af9033_rd_reg(state, 0x800048, &strength2);
+	ret = af9033_rd_reg(dev, 0x800048, &strength2);
 	if (ret < 0)
 		goto err;
 
@@ -906,244 +876,225 @@ static int af9033_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
-
-	return ret;
-}
-
-static int af9033_update_ch_stat(struct af9033_state *state)
-{
-	int ret = 0;
-	u32 err_cnt, bit_cnt;
-	u16 abort_cnt;
-	u8 buf[7];
-
-	/* only update data every half second */
-	if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) {
-		ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf));
-		if (ret < 0)
-			goto err;
-		/* in 8 byte packets? */
-		abort_cnt = (buf[1] << 8) + buf[0];
-		/* in bits */
-		err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2];
-		/* in 8 byte packets? always(?) 0x2710 = 10000 */
-		bit_cnt = (buf[6] << 8) + buf[5];
-
-		if (bit_cnt < abort_cnt) {
-			abort_cnt = 1000;
-			state->ber = 0xffffffff;
-		} else {
-			/* 8 byte packets, that have not been rejected already */
-			bit_cnt -= (u32)abort_cnt;
-			if (bit_cnt == 0) {
-				state->ber = 0xffffffff;
-			} else {
-				err_cnt -= (u32)abort_cnt * 8 * 8;
-				bit_cnt *= 8 * 8;
-				state->ber = err_cnt * (0xffffffff / bit_cnt);
-			}
-		}
-		state->ucb += abort_cnt;
-		state->last_stat_check = jiffies;
-	}
-
-	return 0;
-err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
 static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
-	struct af9033_state *state = fe->demodulator_priv;
-	int ret;
-
-	ret = af9033_update_ch_stat(state);
-	if (ret < 0)
-		return ret;
+	struct af9033_dev *dev = fe->demodulator_priv;
 
-	*ber = state->ber;
+	*ber = (dev->post_bit_error - dev->post_bit_error_prev);
+	dev->post_bit_error_prev = dev->post_bit_error;
 
 	return 0;
 }
 
 static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
-	struct af9033_state *state = fe->demodulator_priv;
-	int ret;
-
-	ret = af9033_update_ch_stat(state);
-	if (ret < 0)
-		return ret;
-
-	*ucblocks = state->ucb;
+	struct af9033_dev *dev = fe->demodulator_priv;
 
+	*ucblocks = dev->error_block_count;
 	return 0;
 }
 
 static int af9033_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
 	int ret;
 
-	dev_dbg(&state->i2c->dev, "%s: enable=%d\n", __func__, enable);
+	dev_dbg(&dev->client->dev, "enable=%d\n", enable);
 
-	ret = af9033_wr_reg_mask(state, 0x00fa04, enable, 0x01);
+	ret = af9033_wr_reg_mask(dev, 0x00fa04, enable, 0x01);
 	if (ret < 0)
 		goto err;
 
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
 static int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
 	int ret;
 
-	dev_dbg(&state->i2c->dev, "%s: onoff=%d\n", __func__, onoff);
+	dev_dbg(&dev->client->dev, "onoff=%d\n", onoff);
 
-	ret = af9033_wr_reg_mask(state, 0x80f993, onoff, 0x01);
+	ret = af9033_wr_reg_mask(dev, 0x80f993, onoff, 0x01);
 	if (ret < 0)
 		goto err;
 
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
-static int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid, int onoff)
+static int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
+		int onoff)
 {
-	struct af9033_state *state = fe->demodulator_priv;
+	struct af9033_dev *dev = fe->demodulator_priv;
 	int ret;
 	u8 wbuf[2] = {(pid >> 0) & 0xff, (pid >> 8) & 0xff};
 
-	dev_dbg(&state->i2c->dev, "%s: index=%d pid=%04x onoff=%d\n",
-			__func__, index, pid, onoff);
+	dev_dbg(&dev->client->dev, "index=%d pid=%04x onoff=%d\n",
+			index, pid, onoff);
 
 	if (pid > 0x1fff)
 		return 0;
 
-	ret = af9033_wr_regs(state, 0x80f996, wbuf, 2);
+	ret = af9033_wr_regs(dev, 0x80f996, wbuf, 2);
 	if (ret < 0)
 		goto err;
 
-	ret = af9033_wr_reg(state, 0x80f994, onoff);
+	ret = af9033_wr_reg(dev, 0x80f994, onoff);
 	if (ret < 0)
 		goto err;
 
-	ret = af9033_wr_reg(state, 0x80f995, index);
+	ret = af9033_wr_reg(dev, 0x80f995, index);
 	if (ret < 0)
 		goto err;
 
 	return 0;
 
 err:
-	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 
 	return ret;
 }
 
-static struct dvb_frontend_ops af9033_ops;
-
-struct dvb_frontend *af9033_attach(const struct af9033_config *config,
-				   struct i2c_adapter *i2c,
-				   struct af9033_ops *ops)
+static void af9033_stat_work(struct work_struct *work)
 {
-	int ret;
-	struct af9033_state *state;
-	u8 buf[8];
+	struct af9033_dev *dev = container_of(work, struct af9033_dev, stat_work.work);
+	struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
+	int ret, tmp, i, len;
+	u8 u8tmp, buf[7];
+
+	dev_dbg(&dev->client->dev, "\n");
+
+	/* signal strength */
+	if (dev->fe_status & FE_HAS_SIGNAL) {
+		if (dev->is_af9035) {
+			ret = af9033_rd_reg(dev, 0x80004a, &u8tmp);
+			tmp = -u8tmp * 1000;
+		} else {
+			ret = af9033_rd_reg(dev, 0x8000f7, &u8tmp);
+			tmp = (u8tmp - 100) * 1000;
+		}
+		if (ret)
+			goto err;
 
-	dev_dbg(&i2c->dev, "%s:\n", __func__);
+		c->strength.len = 1;
+		c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+		c->strength.stat[0].svalue = tmp;
+	} else {
+		c->strength.len = 1;
+		c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	}
 
-	/* allocate memory for the internal state */
-	state = kzalloc(sizeof(struct af9033_state), GFP_KERNEL);
-	if (state == NULL)
-		goto err;
+	/* CNR */
+	if (dev->fe_status & FE_HAS_VITERBI) {
+		u32 snr_val;
+		const struct val_snr *snr_lut;
 
-	/* setup the state */
-	state->i2c = i2c;
-	memcpy(&state->cfg, config, sizeof(struct af9033_config));
+		/* read value */
+		ret = af9033_rd_regs(dev, 0x80002c, buf, 3);
+		if (ret)
+			goto err;
 
-	if (state->cfg.clock != 12000000) {
-		dev_err(&state->i2c->dev, "%s: af9033: unsupported clock=%d, " \
-				"only 12000000 Hz is supported currently\n",
-				KBUILD_MODNAME, state->cfg.clock);
-		goto err;
-	}
+		snr_val = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);
 
-	/* firmware version */
-	ret = af9033_rd_regs(state, 0x0083e9, &buf[0], 4);
-	if (ret < 0)
-		goto err;
+		/* read current modulation */
+		ret = af9033_rd_reg(dev, 0x80f903, &u8tmp);
+		if (ret)
+			goto err;
 
-	ret = af9033_rd_regs(state, 0x804191, &buf[4], 4);
-	if (ret < 0)
-		goto err;
+		switch ((u8tmp >> 0) & 3) {
+		case 0:
+			len = ARRAY_SIZE(qpsk_snr_lut);
+			snr_lut = qpsk_snr_lut;
+			break;
+		case 1:
+			len = ARRAY_SIZE(qam16_snr_lut);
+			snr_lut = qam16_snr_lut;
+			break;
+		case 2:
+			len = ARRAY_SIZE(qam64_snr_lut);
+			snr_lut = qam64_snr_lut;
+			break;
+		default:
+			goto err_schedule_delayed_work;
+		}
 
-	dev_info(&state->i2c->dev, "%s: firmware version: LINK=%d.%d.%d.%d " \
-			"OFDM=%d.%d.%d.%d\n", KBUILD_MODNAME, buf[0], buf[1],
-			buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+		for (i = 0; i < len; i++) {
+			tmp = snr_lut[i].snr * 1000;
+			if (snr_val < snr_lut[i].val)
+				break;
+		}
 
-	/* sleep */
-	switch (state->cfg.tuner) {
-	case AF9033_TUNER_IT9135_38:
-	case AF9033_TUNER_IT9135_51:
-	case AF9033_TUNER_IT9135_52:
-	case AF9033_TUNER_IT9135_60:
-	case AF9033_TUNER_IT9135_61:
-	case AF9033_TUNER_IT9135_62:
-		/* IT9135 did not like to sleep at that early */
-		break;
-	default:
-		ret = af9033_wr_reg(state, 0x80004c, 1);
-		if (ret < 0)
-			goto err;
+		c->cnr.len = 1;
+		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+		c->cnr.stat[0].svalue = tmp;
+	} else {
+		c->cnr.len = 1;
+		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	}
 
-		ret = af9033_wr_reg(state, 0x800000, 0);
-		if (ret < 0)
+	/* UCB/PER/BER */
+	if (dev->fe_status & FE_HAS_LOCK) {
+		/* outer FEC, 204 byte packets */
+		u16 abort_packet_count, rsd_packet_count;
+		/* inner FEC, bits */
+		u32 rsd_bit_err_count;
+
+		/*
+		 * Packet count used for measurement is 10000
+		 * (rsd_packet_count). Maybe it should be increased?
+		 */
+
+		ret = af9033_rd_regs(dev, 0x800032, buf, 7);
+		if (ret)
 			goto err;
-	}
 
-	/* configure internal TS mode */
-	switch (state->cfg.ts_mode) {
-	case AF9033_TS_MODE_PARALLEL:
-		state->ts_mode_parallel = true;
-		break;
-	case AF9033_TS_MODE_SERIAL:
-		state->ts_mode_serial = true;
-		break;
-	case AF9033_TS_MODE_USB:
-		/* usb mode for AF9035 */
-	default:
-		break;
-	}
+		abort_packet_count = (buf[1] << 8) | (buf[0] << 0);
+		rsd_bit_err_count = (buf[4] << 16) | (buf[3] << 8) | buf[2];
+		rsd_packet_count = (buf[6] << 8) | (buf[5] << 0);
 
-	/* create dvb_frontend */
-	memcpy(&state->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
-	state->fe.demodulator_priv = state;
+		dev->error_block_count += abort_packet_count;
+		dev->total_block_count += rsd_packet_count;
+		dev->post_bit_error += rsd_bit_err_count;
+		dev->post_bit_count += rsd_packet_count * 204 * 8;
 
-	if (ops) {
-		ops->pid_filter = af9033_pid_filter;
-		ops->pid_filter_ctrl = af9033_pid_filter_ctrl;
-	}
+		c->block_count.len = 1;
+		c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+		c->block_count.stat[0].uvalue = dev->total_block_count;
+
+		c->block_error.len = 1;
+		c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+		c->block_error.stat[0].uvalue = dev->error_block_count;
+
+		c->post_bit_count.len = 1;
+		c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+		c->post_bit_count.stat[0].uvalue = dev->post_bit_count;
 
-	return &state->fe;
+		c->post_bit_error.len = 1;
+		c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+		c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
+	}
 
+err_schedule_delayed_work:
+	schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
+	return;
 err:
-	kfree(state);
-	return NULL;
+	dev_dbg(&dev->client->dev, "failed=%d\n", ret);
 }
-EXPORT_SYMBOL(af9033_attach);
 
 static struct dvb_frontend_ops af9033_ops = {
 	.delsys = { SYS_DVBT },
@@ -1170,8 +1121,6 @@ static struct dvb_frontend_ops af9033_ops = {
 			FE_CAN_MUTE_TS
 	},
 
-	.release = af9033_release,
-
 	.init = af9033_init,
 	.sleep = af9033_sleep,
 
@@ -1188,6 +1137,150 @@ static struct dvb_frontend_ops af9033_ops = {
 	.i2c_gate_ctrl = af9033_i2c_gate_ctrl,
 };
 
+static int af9033_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct af9033_config *cfg = client->dev.platform_data;
+	struct af9033_dev *dev;
+	int ret;
+	u8 buf[8];
+	u32 reg;
+
+	/* allocate memory for the internal state */
+	dev = kzalloc(sizeof(struct af9033_dev), GFP_KERNEL);
+	if (dev == NULL) {
+		ret = -ENOMEM;
+		dev_err(&client->dev, "Could not allocate memory for state\n");
+		goto err;
+	}
+
+	/* setup the state */
+	dev->client = client;
+	INIT_DELAYED_WORK(&dev->stat_work, af9033_stat_work);
+	memcpy(&dev->cfg, cfg, sizeof(struct af9033_config));
+
+	if (dev->cfg.clock != 12000000) {
+		ret = -ENODEV;
+		dev_err(&dev->client->dev,
+				"unsupported clock %d Hz, only 12000000 Hz is supported currently\n",
+				dev->cfg.clock);
+		goto err_kfree;
+	}
+
+	/* firmware version */
+	switch (dev->cfg.tuner) {
+	case AF9033_TUNER_IT9135_38:
+	case AF9033_TUNER_IT9135_51:
+	case AF9033_TUNER_IT9135_52:
+	case AF9033_TUNER_IT9135_60:
+	case AF9033_TUNER_IT9135_61:
+	case AF9033_TUNER_IT9135_62:
+		dev->is_it9135 = true;
+		reg = 0x004bfc;
+		break;
+	default:
+		dev->is_af9035 = true;
+		reg = 0x0083e9;
+		break;
+	}
+
+	ret = af9033_rd_regs(dev, reg, &buf[0], 4);
+	if (ret < 0)
+		goto err_kfree;
+
+	ret = af9033_rd_regs(dev, 0x804191, &buf[4], 4);
+	if (ret < 0)
+		goto err_kfree;
+
+	dev_info(&dev->client->dev,
+			"firmware version: LINK %d.%d.%d.%d - OFDM %d.%d.%d.%d\n",
+			buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
+			buf[7]);
+
+	/* sleep */
+	switch (dev->cfg.tuner) {
+	case AF9033_TUNER_IT9135_38:
+	case AF9033_TUNER_IT9135_51:
+	case AF9033_TUNER_IT9135_52:
+	case AF9033_TUNER_IT9135_60:
+	case AF9033_TUNER_IT9135_61:
+	case AF9033_TUNER_IT9135_62:
+		/* IT9135 did not like to sleep at that early */
+		break;
+	default:
+		ret = af9033_wr_reg(dev, 0x80004c, 1);
+		if (ret < 0)
+			goto err_kfree;
+
+		ret = af9033_wr_reg(dev, 0x800000, 0);
+		if (ret < 0)
+			goto err_kfree;
+	}
+
+	/* configure internal TS mode */
+	switch (dev->cfg.ts_mode) {
+	case AF9033_TS_MODE_PARALLEL:
+		dev->ts_mode_parallel = true;
+		break;
+	case AF9033_TS_MODE_SERIAL:
+		dev->ts_mode_serial = true;
+		break;
+	case AF9033_TS_MODE_USB:
+		/* usb mode for AF9035 */
+	default:
+		break;
+	}
+
+	/* create dvb_frontend */
+	memcpy(&dev->fe.ops, &af9033_ops, sizeof(struct dvb_frontend_ops));
+	dev->fe.demodulator_priv = dev;
+	*cfg->fe = &dev->fe;
+	if (cfg->ops) {
+		cfg->ops->pid_filter = af9033_pid_filter;
+		cfg->ops->pid_filter_ctrl = af9033_pid_filter_ctrl;
+	}
+	i2c_set_clientdata(client, dev);
+
+	dev_info(&dev->client->dev, "Afatech AF9033 successfully attached\n");
+	return 0;
+err_kfree:
+	kfree(dev);
+err:
+	dev_dbg(&client->dev, "failed=%d\n", ret);
+	return ret;
+}
+
+static int af9033_remove(struct i2c_client *client)
+{
+	struct af9033_dev *dev = i2c_get_clientdata(client);
+
+	dev_dbg(&dev->client->dev, "\n");
+
+	dev->fe.ops.release = NULL;
+	dev->fe.demodulator_priv = NULL;
+	kfree(dev);
+
+	return 0;
+}
+
+static const struct i2c_device_id af9033_id_table[] = {
+	{"af9033", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, af9033_id_table);
+
+static struct i2c_driver af9033_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "af9033",
+	},
+	.probe		= af9033_probe,
+	.remove		= af9033_remove,
+	.id_table	= af9033_id_table,
+};
+
+module_i2c_driver(af9033_driver);
+
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 MODULE_DESCRIPTION("Afatech AF9033 DVB-T demodulator driver");
 MODULE_LICENSE("GPL");

+ 20 - 38
drivers/media/dvb-frontends/af9033.h

@@ -24,12 +24,11 @@
 
 #include <linux/kconfig.h>
 
+/*
+ * I2C address (TODO: are these in 8-bit format?)
+ * 0x38, 0x3a, 0x3c, 0x3e
+ */
 struct af9033_config {
-	/*
-	 * I2C address
-	 */
-	u8 i2c_addr;
-
 	/*
 	 * clock Hz
 	 * 12000000, 22000000, 24000000, 34000000, 32000000, 28000000, 26000000,
@@ -75,8 +74,23 @@ struct af9033_config {
 	 * input spectrum inversion
 	 */
 	bool spec_inv;
-};
 
+	/*
+	 *
+	 */
+	bool dyn0_clk;
+
+	/*
+	 * PID filter ops
+	 */
+	struct af9033_ops *ops;
+
+	/*
+	 * frontend
+	 * returned by that driver
+	 */
+	struct dvb_frontend **fe;
+};
 
 struct af9033_ops {
 	int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff);
@@ -84,36 +98,4 @@ struct af9033_ops {
 			  int onoff);
 };
 
-
-#if IS_ENABLED(CONFIG_DVB_AF9033)
-extern
-struct dvb_frontend *af9033_attach(const struct af9033_config *config,
-				   struct i2c_adapter *i2c,
-				   struct af9033_ops *ops);
-
-#else
-static inline
-struct dvb_frontend *af9033_attach(const struct af9033_config *config,
-				   struct i2c_adapter *i2c,
-				   struct af9033_ops *ops)
-{
-	pr_warn("%s: driver disabled by Kconfig\n", __func__);
-	return NULL;
-}
-
-static inline int af9033_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
-{
-	pr_warn("%s: driver disabled by Kconfig\n", __func__);
-	return -ENODEV;
-}
-
-static inline int af9033_pid_filter(struct dvb_frontend *fe, int index, u16 pid,
-	int onoff)
-{
-	pr_warn("%s: driver disabled by Kconfig\n", __func__);
-	return -ENODEV;
-}
-
-#endif
-
 #endif /* AF9033_H */

+ 1 - 0
drivers/media/dvb-frontends/af9033_priv.h

@@ -24,6 +24,7 @@
 
 #include "dvb_frontend.h"
 #include "af9033.h"
+#include <linux/math64.h>
 
 struct reg_val {
 	u32 reg;

+ 480 - 0
drivers/media/dvb-frontends/as102_fe.c

@@ -0,0 +1,480 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <dvb_frontend.h>
+
+#include "as102_fe.h"
+
+struct as102_state {
+	struct dvb_frontend frontend;
+	struct as10x_demod_stats demod_stats;
+
+	const struct as102_fe_ops *ops;
+	void *priv;
+	uint8_t elna_cfg;
+
+	/* signal strength */
+	uint16_t signal_strength;
+	/* bit error rate */
+	uint32_t ber;
+};
+
+static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg)
+{
+	uint8_t c;
+
+	switch (arg) {
+	case FEC_1_2:
+		c = CODE_RATE_1_2;
+		break;
+	case FEC_2_3:
+		c = CODE_RATE_2_3;
+		break;
+	case FEC_3_4:
+		c = CODE_RATE_3_4;
+		break;
+	case FEC_5_6:
+		c = CODE_RATE_5_6;
+		break;
+	case FEC_7_8:
+		c = CODE_RATE_7_8;
+		break;
+	default:
+		c = CODE_RATE_UNKNOWN;
+		break;
+	}
+
+	return c;
+}
+
+static int as102_fe_set_frontend(struct dvb_frontend *fe)
+{
+	struct as102_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	struct as10x_tune_args tune_args = { 0 };
+
+	/* set frequency */
+	tune_args.freq = c->frequency / 1000;
+
+	/* fix interleaving_mode */
+	tune_args.interleaving_mode = INTLV_NATIVE;
+
+	switch (c->bandwidth_hz) {
+	case 8000000:
+		tune_args.bandwidth = BW_8_MHZ;
+		break;
+	case 7000000:
+		tune_args.bandwidth = BW_7_MHZ;
+		break;
+	case 6000000:
+		tune_args.bandwidth = BW_6_MHZ;
+		break;
+	default:
+		tune_args.bandwidth = BW_8_MHZ;
+	}
+
+	switch (c->guard_interval) {
+	case GUARD_INTERVAL_1_32:
+		tune_args.guard_interval = GUARD_INT_1_32;
+		break;
+	case GUARD_INTERVAL_1_16:
+		tune_args.guard_interval = GUARD_INT_1_16;
+		break;
+	case GUARD_INTERVAL_1_8:
+		tune_args.guard_interval = GUARD_INT_1_8;
+		break;
+	case GUARD_INTERVAL_1_4:
+		tune_args.guard_interval = GUARD_INT_1_4;
+		break;
+	case GUARD_INTERVAL_AUTO:
+	default:
+		tune_args.guard_interval = GUARD_UNKNOWN;
+		break;
+	}
+
+	switch (c->modulation) {
+	case QPSK:
+		tune_args.modulation = CONST_QPSK;
+		break;
+	case QAM_16:
+		tune_args.modulation = CONST_QAM16;
+		break;
+	case QAM_64:
+		tune_args.modulation = CONST_QAM64;
+		break;
+	default:
+		tune_args.modulation = CONST_UNKNOWN;
+		break;
+	}
+
+	switch (c->transmission_mode) {
+	case TRANSMISSION_MODE_2K:
+		tune_args.transmission_mode = TRANS_MODE_2K;
+		break;
+	case TRANSMISSION_MODE_8K:
+		tune_args.transmission_mode = TRANS_MODE_8K;
+		break;
+	default:
+		tune_args.transmission_mode = TRANS_MODE_UNKNOWN;
+	}
+
+	switch (c->hierarchy) {
+	case HIERARCHY_NONE:
+		tune_args.hierarchy = HIER_NONE;
+		break;
+	case HIERARCHY_1:
+		tune_args.hierarchy = HIER_ALPHA_1;
+		break;
+	case HIERARCHY_2:
+		tune_args.hierarchy = HIER_ALPHA_2;
+		break;
+	case HIERARCHY_4:
+		tune_args.hierarchy = HIER_ALPHA_4;
+		break;
+	case HIERARCHY_AUTO:
+		tune_args.hierarchy = HIER_UNKNOWN;
+		break;
+	}
+
+	pr_debug("as102: tuner parameters: freq: %d  bw: 0x%02x  gi: 0x%02x\n",
+			c->frequency,
+			tune_args.bandwidth,
+			tune_args.guard_interval);
+
+	/*
+	 * Detect a hierarchy selection
+	 * if HP/LP are both set to FEC_NONE, HP will be selected.
+	 */
+	if ((tune_args.hierarchy != HIER_NONE) &&
+		       ((c->code_rate_LP == FEC_NONE) ||
+			(c->code_rate_HP == FEC_NONE))) {
+
+		if (c->code_rate_LP == FEC_NONE) {
+			tune_args.hier_select = HIER_HIGH_PRIORITY;
+			tune_args.code_rate =
+			   as102_fe_get_code_rate(c->code_rate_HP);
+		}
+
+		if (c->code_rate_HP == FEC_NONE) {
+			tune_args.hier_select = HIER_LOW_PRIORITY;
+			tune_args.code_rate =
+			   as102_fe_get_code_rate(c->code_rate_LP);
+		}
+
+		pr_debug("as102: \thierarchy: 0x%02x  selected: %s  code_rate_%s: 0x%02x\n",
+			tune_args.hierarchy,
+			tune_args.hier_select == HIER_HIGH_PRIORITY ?
+			"HP" : "LP",
+			tune_args.hier_select == HIER_HIGH_PRIORITY ?
+			"HP" : "LP",
+			tune_args.code_rate);
+	} else {
+		tune_args.code_rate =
+			as102_fe_get_code_rate(c->code_rate_HP);
+	}
+
+	/* Set frontend arguments */
+	return state->ops->set_tune(state->priv, &tune_args);
+}
+
+static int as102_fe_get_frontend(struct dvb_frontend *fe)
+{
+	struct as102_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret = 0;
+	struct as10x_tps tps = { 0 };
+
+	/* send abilis command: GET_TPS */
+	ret = state->ops->get_tps(state->priv, &tps);
+	if (ret < 0)
+		return ret;
+
+	/* extract constellation */
+	switch (tps.modulation) {
+	case CONST_QPSK:
+		c->modulation = QPSK;
+		break;
+	case CONST_QAM16:
+		c->modulation = QAM_16;
+		break;
+	case CONST_QAM64:
+		c->modulation = QAM_64;
+		break;
+	}
+
+	/* extract hierarchy */
+	switch (tps.hierarchy) {
+	case HIER_NONE:
+		c->hierarchy = HIERARCHY_NONE;
+		break;
+	case HIER_ALPHA_1:
+		c->hierarchy = HIERARCHY_1;
+		break;
+	case HIER_ALPHA_2:
+		c->hierarchy = HIERARCHY_2;
+		break;
+	case HIER_ALPHA_4:
+		c->hierarchy = HIERARCHY_4;
+		break;
+	}
+
+	/* extract code rate HP */
+	switch (tps.code_rate_HP) {
+	case CODE_RATE_1_2:
+		c->code_rate_HP = FEC_1_2;
+		break;
+	case CODE_RATE_2_3:
+		c->code_rate_HP = FEC_2_3;
+		break;
+	case CODE_RATE_3_4:
+		c->code_rate_HP = FEC_3_4;
+		break;
+	case CODE_RATE_5_6:
+		c->code_rate_HP = FEC_5_6;
+		break;
+	case CODE_RATE_7_8:
+		c->code_rate_HP = FEC_7_8;
+		break;
+	}
+
+	/* extract code rate LP */
+	switch (tps.code_rate_LP) {
+	case CODE_RATE_1_2:
+		c->code_rate_LP = FEC_1_2;
+		break;
+	case CODE_RATE_2_3:
+		c->code_rate_LP = FEC_2_3;
+		break;
+	case CODE_RATE_3_4:
+		c->code_rate_LP = FEC_3_4;
+		break;
+	case CODE_RATE_5_6:
+		c->code_rate_LP = FEC_5_6;
+		break;
+	case CODE_RATE_7_8:
+		c->code_rate_LP = FEC_7_8;
+		break;
+	}
+
+	/* extract guard interval */
+	switch (tps.guard_interval) {
+	case GUARD_INT_1_32:
+		c->guard_interval = GUARD_INTERVAL_1_32;
+		break;
+	case GUARD_INT_1_16:
+		c->guard_interval = GUARD_INTERVAL_1_16;
+		break;
+	case GUARD_INT_1_8:
+		c->guard_interval = GUARD_INTERVAL_1_8;
+		break;
+	case GUARD_INT_1_4:
+		c->guard_interval = GUARD_INTERVAL_1_4;
+		break;
+	}
+
+	/* extract transmission mode */
+	switch (tps.transmission_mode) {
+	case TRANS_MODE_2K:
+		c->transmission_mode = TRANSMISSION_MODE_2K;
+		break;
+	case TRANS_MODE_8K:
+		c->transmission_mode = TRANSMISSION_MODE_8K;
+		break;
+	}
+
+	return 0;
+}
+
+static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
+			struct dvb_frontend_tune_settings *settings) {
+
+	settings->min_delay_ms = 1000;
+
+	return 0;
+}
+
+static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	int ret = 0;
+	struct as102_state *state = fe->demodulator_priv;
+	struct as10x_tune_status tstate = { 0 };
+
+	/* send abilis command: GET_TUNE_STATUS */
+	ret = state->ops->get_status(state->priv, &tstate);
+	if (ret < 0)
+		return ret;
+
+	state->signal_strength  = tstate.signal_strength;
+	state->ber  = tstate.BER;
+
+	switch (tstate.tune_state) {
+	case TUNE_STATUS_SIGNAL_DVB_OK:
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+		break;
+	case TUNE_STATUS_STREAM_DETECTED:
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
+			  FE_HAS_VITERBI;
+		break;
+	case TUNE_STATUS_STREAM_TUNED:
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
+			  FE_HAS_LOCK | FE_HAS_VITERBI;
+		break;
+	default:
+		*status = TUNE_STATUS_NOT_TUNED;
+	}
+
+	pr_debug("as102: tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
+		 tstate.tune_state, tstate.signal_strength,
+		 tstate.PER, tstate.BER);
+
+	if (!(*status & FE_HAS_LOCK)) {
+		memset(&state->demod_stats, 0, sizeof(state->demod_stats));
+		return 0;
+	}
+
+	ret = state->ops->get_stats(state->priv, &state->demod_stats);
+	if (ret < 0)
+		memset(&state->demod_stats, 0, sizeof(state->demod_stats));
+
+	return ret;
+}
+
+/*
+ * Note:
+ * - in AS102 SNR=MER
+ *   - the SNR will be returned in linear terms, i.e. not in dB
+ *   - the accuracy equals ±2dB for a SNR range from 4dB to 30dB
+ *   - the accuracy is >2dB for SNR values outside this range
+ */
+static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct as102_state *state = fe->demodulator_priv;
+
+	*snr = state->demod_stats.mer;
+
+	return 0;
+}
+
+static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct as102_state *state = fe->demodulator_priv;
+
+	*ber = state->ber;
+
+	return 0;
+}
+
+static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
+					 u16 *strength)
+{
+	struct as102_state *state = fe->demodulator_priv;
+
+	*strength = (((0xffff * 400) * state->signal_strength + 41000) * 2);
+
+	return 0;
+}
+
+static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct as102_state *state = fe->demodulator_priv;
+
+	if (state->demod_stats.has_started)
+		*ucblocks = state->demod_stats.bad_frame_count;
+	else
+		*ucblocks = 0;
+
+	return 0;
+}
+
+static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+	struct as102_state *state = fe->demodulator_priv;
+
+	return state->ops->stream_ctrl(state->priv, acquire,
+				      state->elna_cfg);
+}
+
+static void as102_fe_release(struct dvb_frontend *fe)
+{
+	struct as102_state *state = fe->demodulator_priv;
+
+	kfree(state);
+}
+
+
+static struct dvb_frontend_ops as102_fe_ops = {
+	.delsys = { SYS_DVBT },
+	.info = {
+		.name			= "Abilis AS102 DVB-T",
+		.frequency_min		= 174000000,
+		.frequency_max		= 862000000,
+		.frequency_stepsize	= 166667,
+		.caps = FE_CAN_INVERSION_AUTO
+			| FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
+			| FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO
+			| FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK
+			| FE_CAN_QAM_AUTO
+			| FE_CAN_TRANSMISSION_MODE_AUTO
+			| FE_CAN_GUARD_INTERVAL_AUTO
+			| FE_CAN_HIERARCHY_AUTO
+			| FE_CAN_RECOVER
+			| FE_CAN_MUTE_TS
+	},
+
+	.set_frontend		= as102_fe_set_frontend,
+	.get_frontend		= as102_fe_get_frontend,
+	.get_tune_settings	= as102_fe_get_tune_settings,
+
+	.read_status		= as102_fe_read_status,
+	.read_snr		= as102_fe_read_snr,
+	.read_ber		= as102_fe_read_ber,
+	.read_signal_strength	= as102_fe_read_signal_strength,
+	.read_ucblocks		= as102_fe_read_ucblocks,
+	.ts_bus_ctrl		= as102_fe_ts_bus_ctrl,
+	.release		= as102_fe_release,
+};
+
+struct dvb_frontend *as102_attach(const char *name,
+				  const struct as102_fe_ops *ops,
+				  void *priv,
+				  uint8_t elna_cfg)
+{
+	struct as102_state *state;
+	struct dvb_frontend *fe;
+
+	state = kzalloc(sizeof(struct as102_state), GFP_KERNEL);
+	if (state == NULL) {
+		pr_err("%s: unable to allocate memory for state\n", __func__);
+		return NULL;
+	}
+	fe = &state->frontend;
+	fe->demodulator_priv = state;
+	state->ops = ops;
+	state->priv = priv;
+	state->elna_cfg = elna_cfg;
+
+	/* init frontend callback ops */
+	memcpy(&fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops));
+	strncpy(fe->ops.info.name, name, sizeof(fe->ops.info.name));
+
+	return fe;
+
+}
+EXPORT_SYMBOL_GPL(as102_attach);
+
+MODULE_DESCRIPTION("as102-fe");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>");

+ 29 - 0
drivers/media/dvb-frontends/as102_fe.h

@@ -0,0 +1,29 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2014 Mauro Carvalho Chehab <m.chehab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "as102_fe_types.h"
+
+struct as102_fe_ops {
+	int (*set_tune)(void *priv, struct as10x_tune_args *tune_args);
+	int (*get_tps)(void *priv, struct as10x_tps *tps);
+	int (*get_status)(void *priv, struct as10x_tune_status *tstate);
+	int (*get_stats)(void *priv, struct as10x_demod_stats *demod_stats);
+	int (*stream_ctrl)(void *priv, int acquire, uint32_t elna_cfg);
+};
+
+struct dvb_frontend *as102_attach(const char *name,
+				  const struct as102_fe_ops *ops,
+				  void *priv,
+				  uint8_t elna_cfg);

+ 0 - 6
drivers/staging/media/as102/as10x_types.h → drivers/media/dvb-frontends/as102_fe_types.h

@@ -11,16 +11,10 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #ifndef _AS10X_TYPES_H_
 #define _AS10X_TYPES_H_
 
-#include "as10x_handle.h"
-
 /*********************************/
 /*       MACRO DEFINITIONS       */
 /*********************************/

+ 3 - 3
drivers/media/dvb-frontends/bcm3510.c

@@ -639,12 +639,12 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe)
 		err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
 		return ret;
 	}
-	deb_info("got firmware: %zd\n",fw->size);
+	deb_info("got firmware: %zu\n", fw->size);
 
 	b = fw->data;
 	for (i = 0; i < fw->size;) {
-		addr = le16_to_cpu( *( (u16 *)&b[i] ) );
-		len  = le16_to_cpu( *( (u16 *)&b[i+2] ) );
+		addr = le16_to_cpu(*((__le16 *)&b[i]));
+		len  = le16_to_cpu(*((__le16 *)&b[i+2]));
 		deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
 		if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
 			err("firmware download failed: %d\n",ret);

+ 2 - 2
drivers/media/dvb-frontends/cxd2820r_c.c

@@ -65,7 +65,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
 	}
 
 	priv->delivery_system = SYS_DVBC_ANNEX_A;
-	priv->ber_running = 0; /* tune stops BER counter */
+	priv->ber_running = false; /* tune stops BER counter */
 
 	/* program IF frequency */
 	if (fe->ops.tuner_ops.get_if_frequency) {
@@ -168,7 +168,7 @@ int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
 			start_ber = 1;
 		}
 	} else {
-		priv->ber_running = 1;
+		priv->ber_running = true;
 		start_ber = 1;
 	}
 

+ 2 - 2
drivers/media/dvb-frontends/cxd2820r_core.c

@@ -564,10 +564,10 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
 
 	/* check if we have a valid signal */
 	if (status & FE_HAS_LOCK) {
-		priv->last_tune_failed = 0;
+		priv->last_tune_failed = false;
 		return DVBFE_ALGO_SEARCH_SUCCESS;
 	} else {
-		priv->last_tune_failed = 1;
+		priv->last_tune_failed = true;
 		return DVBFE_ALGO_SEARCH_AGAIN;
 	}
 

+ 2 - 2
drivers/media/dvb-frontends/cxd2820r_t.c

@@ -89,7 +89,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
 	}
 
 	priv->delivery_system = SYS_DVBT;
-	priv->ber_running = 0; /* tune stops BER counter */
+	priv->ber_running = false; /* tune stops BER counter */
 
 	/* program IF frequency */
 	if (fe->ops.tuner_ops.get_if_frequency) {
@@ -272,7 +272,7 @@ int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
 			start_ber = 1;
 		}
 	} else {
-		priv->ber_running = 1;
+		priv->ber_running = true;
 		start_ber = 1;
 	}
 

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

@@ -2559,7 +2559,7 @@ static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
 	dib7000p_write_word(state, 1288, reg_1288);
 }
 
-int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
+static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
 {
 	struct dib7000p_state *state = fe->demodulator_priv;
 	u16 reg_1287;

+ 19 - 19
drivers/media/dvb-frontends/drx39xyj/drxj.c

@@ -2174,7 +2174,7 @@ int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
 				     u32 addr,
 				     u32 *data, u32 flags)
 {
-	u8 buf[sizeof(*data)];
+	u8 buf[sizeof(*data)] = { 0 };
 	int rc = -EIO;
 	u32 word = 0;
 
@@ -4193,7 +4193,7 @@ int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
 					 u32 addr,
 					 u16 *data, u32 flags)
 {
-	u8 buf[2];
+	u8 buf[2] = { 0 };
 	int rc = -EIO;
 	u16 word = 0;
 
@@ -10667,7 +10667,7 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
 	enum drx_standard standard = ext_attr->standard;
 	int rc;
 	u32 ber, cnt, err, pkt;
-	u16 mer, strength;
+	u16 mer, strength = 0;
 
 	rc = get_sig_strength(demod, &strength);
 	if (rc < 0) {
@@ -11602,7 +11602,7 @@ static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
 	u32 carry = 0;
 
 	while (i < nr_words) {
-		crc_word |= (u32)be16_to_cpu(*(u32 *)(block_data));
+		crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
 		for (j = 0; j < 16; j++) {
 			crc_word <<= 1;
 			if (carry != 0)
@@ -11629,7 +11629,7 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
 	int i;
 	unsigned count = 2 * sizeof(u16);
 	u32 mc_dev_type, mc_version, mc_base_version;
-	u16 mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data + sizeof(u16)));
+	u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
 
 	/*
 	 * Scan microcode blocks first for version info
@@ -11647,13 +11647,13 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
 			goto eof;
 
 		/* Process block header */
-		block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data + count));
+		block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
 		count += sizeof(u32);
-		block_hdr.size = be16_to_cpu(*(u32 *)(mc_data + count));
+		block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
 		count += sizeof(u16);
-		block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data + count));
+		block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
 		count += sizeof(u16);
-		block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data + count));
+		block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
 		count += sizeof(u16);
 
 		pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
@@ -11667,7 +11667,7 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
 			if (block_hdr.addr + sizeof(u16) > size)
 				goto eof;
 
-			auxtype = be16_to_cpu(*(u32 *)(auxblk));
+			auxtype = be16_to_cpu(*(__be16 *)(auxblk));
 
 			/* Aux block. Check type */
 			if (DRX_ISMCVERTYPE(auxtype)) {
@@ -11675,11 +11675,11 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
 					goto eof;
 
 				auxblk += sizeof(u16);
-				mc_dev_type = be32_to_cpu(*(u32 *)(auxblk));
+				mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
 				auxblk += sizeof(u32);
-				mc_version = be32_to_cpu(*(u32 *)(auxblk));
+				mc_version = be32_to_cpu(*(__be32 *)(auxblk));
 				auxblk += sizeof(u32);
-				mc_base_version = be32_to_cpu(*(u32 *)(auxblk));
+				mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
 
 				DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
 				DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
@@ -11765,9 +11765,9 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
 
 	mc_data = (void *)mc_data_init;
 	/* Check data */
-	mc_magic_word = be16_to_cpu(*(u32 *)(mc_data));
+	mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
 	mc_data += sizeof(u16);
-	mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data));
+	mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
 	mc_data += sizeof(u16);
 
 	if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
@@ -11791,13 +11791,13 @@ static int drx_ctrl_u_code(struct drx_demod_instance *demod,
 		u16 mc_block_nr_bytes = 0;
 
 		/* Process block header */
-		block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data));
+		block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
 		mc_data += sizeof(u32);
-		block_hdr.size = be16_to_cpu(*(u32 *)(mc_data));
+		block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
 		mc_data += sizeof(u16);
-		block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data));
+		block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
 		mc_data += sizeof(u16);
-		block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data));
+		block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
 		mc_data += sizeof(u16);
 
 		pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",

+ 2 - 7
drivers/media/dvb-frontends/drxd_hard.c

@@ -2628,10 +2628,11 @@ static int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
 			break;
 
 		/* Apply I2c address patch to B1 */
-		if (!state->type_A && state->m_HiI2cPatch != NULL)
+		if (!state->type_A && state->m_HiI2cPatch != NULL) {
 			status = WriteTable(state, state->m_HiI2cPatch);
 			if (status < 0)
 				break;
+		}
 
 		if (state->type_A) {
 			/* HI firmware patch for UIO readout,
@@ -2830,14 +2831,8 @@ static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status)
 static int drxd_init(struct dvb_frontend *fe)
 {
 	struct drxd_state *state = fe->demodulator_priv;
-	int err = 0;
 
-/*	if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
 	return DRXD_init(state, NULL, 0);
-
-	err = DRXD_init(state, state->fw->data, state->fw->size);
-	release_firmware(state->fw);
-	return err;
 }
 
 static int drxd_config_i2c(struct dvb_frontend *fe, int onoff)

+ 19 - 18
drivers/media/dvb-frontends/drxk_hard.c

@@ -1028,7 +1028,7 @@ static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
 		    ((state->m_hi_cfg_ctrl) &
 		     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
 		    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
-	if (powerdown_cmd == false) {
+	if (!powerdown_cmd) {
 		/* Wait until command rdy */
 		u32 retry_count = 0;
 		u16 wait_cmd;
@@ -1129,7 +1129,7 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
 	if (status < 0)
 		goto error;
 
-	if (mpeg_enable == false) {
+	if (!mpeg_enable) {
 		/*  Set MPEG TS pads to inputmode */
 		status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
 		if (status < 0)
@@ -1190,7 +1190,7 @@ static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
 		if (status < 0)
 			goto error;
 
-		if (state->m_enable_parallel == true) {
+		if (state->m_enable_parallel) {
 			/* parallel -> enable MD1 to MD7 */
 			status = write16(state, SIO_PDR_MD1_CFG__A,
 					 sio_pdr_mdx_cfg);
@@ -1392,7 +1392,7 @@ static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
 
 	dprintk(1, "\n");
 
-	if (enable == false) {
+	if (!enable) {
 		desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
 		desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
 	}
@@ -2012,7 +2012,7 @@ static int mpegts_dto_setup(struct drxk_state *state,
 		goto error;
 	fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
 	fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
-	if (state->m_insert_rs_byte == true) {
+	if (state->m_insert_rs_byte) {
 		/* enable parity symbol forward */
 		fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
 		/* MVAL disable during parity bytes */
@@ -2023,7 +2023,7 @@ static int mpegts_dto_setup(struct drxk_state *state,
 
 	/* Check serial or parallel output */
 	fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
-	if (state->m_enable_parallel == false) {
+	if (!state->m_enable_parallel) {
 		/* MPEG data output is serial -> set ipr_mode[0] */
 		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
 	}
@@ -2136,19 +2136,19 @@ static int mpegts_configure_polarity(struct drxk_state *state)
 
 	/* Control selective inversion of output bits */
 	fec_oc_reg_ipr_invert &= (~(invert_data_mask));
-	if (state->m_invert_data == true)
+	if (state->m_invert_data)
 		fec_oc_reg_ipr_invert |= invert_data_mask;
 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
-	if (state->m_invert_err == true)
+	if (state->m_invert_err)
 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
-	if (state->m_invert_str == true)
+	if (state->m_invert_str)
 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
-	if (state->m_invert_val == true)
+	if (state->m_invert_val)
 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
 	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
-	if (state->m_invert_clk == true)
+	if (state->m_invert_clk)
 		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
 
 	return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
@@ -2220,12 +2220,13 @@ static int set_agc_rf(struct drxk_state *state,
 		}
 
 		/* Set TOP, only if IF-AGC is in AUTO mode */
-		if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
+		if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO) {
 			status = write16(state,
 					 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
 					 p_agc_cfg->top);
 			if (status < 0)
 				goto error;
+		}
 
 		/* Cut-Off current */
 		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
@@ -3352,7 +3353,7 @@ static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
 	int status;
 
 	dprintk(1, "\n");
-	if (*enabled == true)
+	if (*enabled)
 		status = write16(state, IQM_CF_BYPASSDET__A, 0);
 	else
 		status = write16(state, IQM_CF_BYPASSDET__A, 1);
@@ -3368,7 +3369,7 @@ static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
 	int status;
 
 	dprintk(1, "\n");
-	if (*enabled == true) {
+	if (*enabled) {
 		/* write mask to 1 */
 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
 				   DEFAULT_FR_THRES_8K);
@@ -6794,11 +6795,11 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 	state->enable_merr_cfg = config->enable_merr_cfg;
 
 	if (config->dynamic_clk) {
-		state->m_dvbt_static_clk = 0;
-		state->m_dvbc_static_clk = 0;
+		state->m_dvbt_static_clk = false;
+		state->m_dvbc_static_clk = false;
 	} else {
-		state->m_dvbt_static_clk = 1;
-		state->m_dvbc_static_clk = 1;
+		state->m_dvbt_static_clk = true;
+		state->m_dvbc_static_clk = true;
 	}
 
 

+ 74 - 27
drivers/media/dvb-frontends/m88ds3103.c

@@ -159,6 +159,7 @@ static int m88ds3103_wr_reg_val_tab(struct m88ds3103_priv *priv,
 {
 	int ret, i, j;
 	u8 buf[83];
+
 	dev_dbg(&priv->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
 
 	if (tab_len > 83) {
@@ -247,8 +248,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
 	u8 u8tmp, u8tmp1, u8tmp2;
 	u8 buf[2];
 	u16 u16tmp, divide_ratio;
-	u32 tuner_frequency, target_mclk, ts_clk;
+	u32 tuner_frequency, target_mclk;
 	s32 s32tmp;
+
 	dev_dbg(&priv->i2c->dev,
 			"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
 			__func__, c->delivery_system,
@@ -316,9 +318,6 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
 				target_mclk = 144000;
 			break;
 		case M88DS3103_TS_PARALLEL:
-		case M88DS3103_TS_PARALLEL_12:
-		case M88DS3103_TS_PARALLEL_16:
-		case M88DS3103_TS_PARALLEL_19_2:
 		case M88DS3103_TS_CI:
 			if (c->symbol_rate < 18000000)
 				target_mclk = 96000;
@@ -352,33 +351,17 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
 	switch (priv->cfg->ts_mode) {
 	case M88DS3103_TS_SERIAL:
 		u8tmp1 = 0x00;
-		ts_clk = 0;
-		u8tmp = 0x46;
+		u8tmp = 0x06;
 		break;
 	case M88DS3103_TS_SERIAL_D7:
 		u8tmp1 = 0x20;
-		ts_clk = 0;
-		u8tmp = 0x46;
+		u8tmp = 0x06;
 		break;
 	case M88DS3103_TS_PARALLEL:
-		ts_clk = 24000;
-		u8tmp = 0x42;
-		break;
-	case M88DS3103_TS_PARALLEL_12:
-		ts_clk = 12000;
-		u8tmp = 0x42;
-		break;
-	case M88DS3103_TS_PARALLEL_16:
-		ts_clk = 16000;
-		u8tmp = 0x42;
-		break;
-	case M88DS3103_TS_PARALLEL_19_2:
-		ts_clk = 19200;
-		u8tmp = 0x42;
+		u8tmp = 0x02;
 		break;
 	case M88DS3103_TS_CI:
-		ts_clk = 6000;
-		u8tmp = 0x43;
+		u8tmp = 0x03;
 		break;
 	default:
 		dev_dbg(&priv->i2c->dev, "%s: invalid ts_mode\n", __func__);
@@ -386,6 +369,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
 		goto err;
 	}
 
+	if (priv->cfg->ts_clk_pol)
+		u8tmp |= 0x40;
+
 	/* TS mode */
 	ret = m88ds3103_wr_reg(priv, 0xfd, u8tmp);
 	if (ret)
@@ -399,8 +385,8 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
 			goto err;
 	}
 
-	if (ts_clk) {
-		divide_ratio = DIV_ROUND_UP(target_mclk, ts_clk);
+	if (priv->cfg->ts_clk) {
+		divide_ratio = DIV_ROUND_UP(target_mclk, priv->cfg->ts_clk);
 		u8tmp1 = divide_ratio / 2;
 		u8tmp2 = DIV_ROUND_UP(divide_ratio, 2);
 	} else {
@@ -411,7 +397,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
 
 	dev_dbg(&priv->i2c->dev,
 			"%s: target_mclk=%d ts_clk=%d divide_ratio=%d\n",
-			__func__, target_mclk, ts_clk, divide_ratio);
+			__func__, target_mclk, priv->cfg->ts_clk, divide_ratio);
 
 	u8tmp1--;
 	u8tmp2--;
@@ -536,6 +522,7 @@ static int m88ds3103_init(struct dvb_frontend *fe)
 	const struct firmware *fw = NULL;
 	u8 *fw_file = M88DS3103_FIRMWARE;
 	u8 u8tmp;
+
 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
 
 	/* set cold state by default */
@@ -648,6 +635,7 @@ static int m88ds3103_sleep(struct dvb_frontend *fe)
 {
 	struct m88ds3103_priv *priv = fe->demodulator_priv;
 	int ret;
+
 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
 
 	priv->delivery_system = SYS_UNDEFINED;
@@ -682,6 +670,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int ret;
 	u8 buf[3];
+
 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
 
 	if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
@@ -857,6 +846,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
 	u8 buf[3];
 	u16 noise, signal;
 	u32 noise_tot, signal_tot;
+
 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
 	/* reports SNR in resolution of 0.1 dB */
 
@@ -933,6 +923,7 @@ static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
 	int ret;
 	unsigned int utmp;
 	u8 buf[3], u8tmp;
+
 	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
 
 	switch (c->delivery_system) {
@@ -1013,6 +1004,7 @@ static int m88ds3103_set_tone(struct dvb_frontend *fe,
 	struct m88ds3103_priv *priv = fe->demodulator_priv;
 	int ret;
 	u8 u8tmp, tone, reg_a1_mask;
+
 	dev_dbg(&priv->i2c->dev, "%s: fe_sec_tone_mode=%d\n", __func__,
 			fe_sec_tone_mode);
 
@@ -1053,12 +1045,64 @@ err:
 	return ret;
 }
 
+static int m88ds3103_set_voltage(struct dvb_frontend *fe,
+	fe_sec_voltage_t fe_sec_voltage)
+{
+	struct m88ds3103_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 u8tmp;
+	bool voltage_sel, voltage_dis;
+
+	dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
+			fe_sec_voltage);
+
+	if (!priv->warm) {
+		ret = -EAGAIN;
+		goto err;
+	}
+
+	switch (fe_sec_voltage) {
+	case SEC_VOLTAGE_18:
+		voltage_sel = true;
+		voltage_dis = false;
+		break;
+	case SEC_VOLTAGE_13:
+		voltage_sel = false;
+		voltage_dis = false;
+		break;
+	case SEC_VOLTAGE_OFF:
+		voltage_sel = false;
+		voltage_dis = true;
+		break;
+	default:
+		dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n",
+				__func__);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* output pin polarity */
+	voltage_sel ^= priv->cfg->lnb_hv_pol;
+	voltage_dis ^= priv->cfg->lnb_en_pol;
+
+	u8tmp = voltage_dis << 1 | voltage_sel << 0;
+	ret = m88ds3103_wr_reg_mask(priv, 0xa2, u8tmp, 0x03);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+	return ret;
+}
+
 static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
 		struct dvb_diseqc_master_cmd *diseqc_cmd)
 {
 	struct m88ds3103_priv *priv = fe->demodulator_priv;
 	int ret, i;
 	u8 u8tmp;
+
 	dev_dbg(&priv->i2c->dev, "%s: msg=%*ph\n", __func__,
 			diseqc_cmd->msg_len, diseqc_cmd->msg);
 
@@ -1130,6 +1174,7 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
 	struct m88ds3103_priv *priv = fe->demodulator_priv;
 	int ret, i;
 	u8 u8tmp, burst;
+
 	dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
 			fe_sec_mini_cmd);
 
@@ -1202,6 +1247,7 @@ static int m88ds3103_get_tune_settings(struct dvb_frontend *fe,
 static void m88ds3103_release(struct dvb_frontend *fe)
 {
 	struct m88ds3103_priv *priv = fe->demodulator_priv;
+
 	i2c_del_mux_adapter(priv->i2c_adapter);
 	kfree(priv);
 }
@@ -1370,6 +1416,7 @@ static struct dvb_frontend_ops m88ds3103_ops = {
 	.diseqc_send_burst = m88ds3103_diseqc_send_burst,
 
 	.set_tone = m88ds3103_set_tone,
+	.set_voltage = m88ds3103_set_voltage,
 };
 
 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");

+ 30 - 5
drivers/media/dvb-frontends/m88ds3103.h

@@ -47,13 +47,22 @@ struct m88ds3103_config {
 	 */
 #define M88DS3103_TS_SERIAL             0 /* TS output pin D0, normal */
 #define M88DS3103_TS_SERIAL_D7          1 /* TS output pin D7 */
-#define M88DS3103_TS_PARALLEL           2 /* 24 MHz, normal */
-#define M88DS3103_TS_PARALLEL_12        3 /* 12 MHz */
-#define M88DS3103_TS_PARALLEL_16        4 /* 16 MHz */
-#define M88DS3103_TS_PARALLEL_19_2      5 /* 19.2 MHz */
-#define M88DS3103_TS_CI                 6 /* 6 MHz */
+#define M88DS3103_TS_PARALLEL           2 /* TS Parallel mode */
+#define M88DS3103_TS_CI                 3 /* TS CI Mode */
 	u8 ts_mode;
 
+	/*
+	 * TS clk in KHz
+	 * Default: 0.
+	 */
+	u32 ts_clk;
+
+	/*
+	 * TS clk polarity.
+	 * Default: 0. 1-active at falling edge; 0-active at rising edge.
+	 */
+	u8 ts_clk_pol:1;
+
 	/*
 	 * spectrum inversion
 	 * Default: 0
@@ -86,6 +95,22 @@ struct m88ds3103_config {
 	 * Default: none, must set
 	 */
 	u8 agc;
+
+	/*
+	 * LNB H/V pin polarity
+	 * Default: 0.
+	 * 1: pin high set to VOLTAGE_13, pin low to set VOLTAGE_18.
+	 * 0: pin high set to VOLTAGE_18, pin low to set VOLTAGE_13.
+	 */
+	u8 lnb_hv_pol:1;
+
+	/*
+	 * LNB enable pin polarity
+	 * Default: 0.
+	 * 1: pin high to enable, pin low to disable.
+	 * 0: pin high to disable, pin low to enable.
+	 */
+	u8 lnb_en_pol:1;
 };
 
 /*

+ 4 - 2
drivers/media/dvb-frontends/mb86a16.c

@@ -28,7 +28,7 @@
 #include "mb86a16.h"
 #include "mb86a16_priv.h"
 
-unsigned int verbose = 5;
+static unsigned int verbose = 5;
 module_param(verbose, int, 0644);
 
 #define ABS(x)		((x) < 0 ? (-x) : (x))
@@ -115,9 +115,11 @@ static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val)
 	};
 	ret = i2c_transfer(state->i2c_adap, msg, 2);
 	if (ret != 2) {
-		dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)",
+		dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=%i)",
 			reg, ret);
 
+		if (ret < 0)
+			return ret;
 		return -EREMOTEIO;
 	}
 	*val = b1[0];

+ 7 - 7
drivers/media/dvb-frontends/mb86a20s.c

@@ -33,7 +33,7 @@ enum mb86a20s_bandwidth {
 	MB86A20S_3SEG = 3,
 };
 
-u8 mb86a20s_subchannel[] = {
+static u8 mb86a20s_subchannel[] = {
 	0xb0, 0xc0, 0xd0, 0xe0,
 	0xf0, 0x00, 0x10, 0x20,
 };
@@ -1228,7 +1228,7 @@ struct linear_segments {
  * All tables below return a dB/1000 measurement
  */
 
-static struct linear_segments cnr_to_db_table[] = {
+static const struct linear_segments cnr_to_db_table[] = {
 	{ 19648,     0},
 	{ 18187,  1000},
 	{ 16534,  2000},
@@ -1262,7 +1262,7 @@ static struct linear_segments cnr_to_db_table[] = {
 	{   788, 30000},
 };
 
-static struct linear_segments cnr_64qam_table[] = {
+static const struct linear_segments cnr_64qam_table[] = {
 	{ 3922688,     0},
 	{ 3920384,  1000},
 	{ 3902720,  2000},
@@ -1296,7 +1296,7 @@ static struct linear_segments cnr_64qam_table[] = {
 	{  388864, 30000},
 };
 
-static struct linear_segments cnr_16qam_table[] = {
+static const struct linear_segments cnr_16qam_table[] = {
 	{ 5314816,     0},
 	{ 5219072,  1000},
 	{ 5118720,  2000},
@@ -1330,7 +1330,7 @@ static struct linear_segments cnr_16qam_table[] = {
 	{   95744, 30000},
 };
 
-struct linear_segments cnr_qpsk_table[] = {
+static const struct linear_segments cnr_qpsk_table[] = {
 	{ 2834176,     0},
 	{ 2683648,  1000},
 	{ 2536960,  2000},
@@ -1364,7 +1364,7 @@ struct linear_segments cnr_qpsk_table[] = {
 	{   11520, 30000},
 };
 
-static u32 interpolate_value(u32 value, struct linear_segments *segments,
+static u32 interpolate_value(u32 value, const struct linear_segments *segments,
 			     unsigned len)
 {
 	u64 tmp64;
@@ -1448,7 +1448,7 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe)
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	u32 mer, cnr;
 	int rc, val, layer;
-	struct linear_segments *segs;
+	const struct linear_segments *segs;
 	unsigned segs_len;
 
 	dev_dbg(&state->i2c->dev, "%s called.\n", __func__);

+ 1 - 1
drivers/media/dvb-frontends/mt312.c

@@ -103,7 +103,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
 
 	if (1 + count > sizeof(buf)) {
 		printk(KERN_WARNING
-		       "mt312: write: len=%zd is too big!\n", count);
+		       "mt312: write: len=%zu is too big!\n", count);
 		return -EINVAL;
 	}
 

+ 1 - 1
drivers/media/dvb-frontends/or51211.c

@@ -111,7 +111,7 @@ static int or51211_load_firmware (struct dvb_frontend* fe,
 	u8 tudata[585];
 	int i;
 
-	dprintk("Firmware is %zd bytes\n",fw->size);
+	dprintk("Firmware is %zu bytes\n", fw->size);
 
 	/* Get eprom data */
 	tudata[0] = 17;

+ 1 - 1
drivers/media/dvb-frontends/rtl2832.c

@@ -936,7 +936,7 @@ static void rtl2832_i2c_gate_work(struct work_struct *work)
 	if (ret != 1)
 		goto err;
 
-	priv->i2c_gate_state = 0;
+	priv->i2c_gate_state = false;
 
 	return;
 err:

+ 56 - 62
drivers/media/dvb-frontends/rtl2832_sdr.c

@@ -329,7 +329,7 @@ static int rtl2832_sdr_rd_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
 static struct rtl2832_sdr_frame_buf *rtl2832_sdr_get_next_fill_buf(
 		struct rtl2832_sdr_state *s)
 {
-	unsigned long flags = 0;
+	unsigned long flags;
 	struct rtl2832_sdr_frame_buf *buf = NULL;
 
 	spin_lock_irqsave(&s->queued_bufs_lock, flags);
@@ -365,17 +365,19 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
 		dst_len = 0;
 	}
 
-	/* calculate samping rate and output it in 10 seconds intervals */
+	/* calculate sample rate and output it in 10 seconds intervals */
 	if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
-#define MSECS 10000UL
+		#define MSECS 10000UL
+		unsigned int msecs = jiffies_to_msecs(jiffies -
+				s->jiffies_next + msecs_to_jiffies(MSECS));
 		unsigned int samples = s->sample - s->sample_measured;
 
 		s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
 		s->sample_measured = s->sample;
 		dev_dbg(&s->udev->dev,
-				"slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
-				src_len, samples, MSECS,
-				samples * 1000UL / MSECS);
+				"slen=%u samples=%u msecs=%u sample rate=%lu\n",
+				src_len, samples, msecs,
+				samples * 1000UL / msecs);
 	}
 
 	/* total number of I+Q pairs */
@@ -394,8 +396,8 @@ static void rtl2832_sdr_urb_complete(struct urb *urb)
 	struct rtl2832_sdr_frame_buf *fbuf;
 
 	dev_dbg_ratelimited(&s->udev->dev,
-			"%s: status=%d length=%d/%d errors=%d\n",
-			__func__, urb->status, urb->actual_length,
+			"status=%d length=%d/%d errors=%d\n",
+			urb->status, urb->actual_length,
 			urb->transfer_buffer_length, urb->error_count);
 
 	switch (urb->status) {
@@ -443,7 +445,7 @@ static int rtl2832_sdr_kill_urbs(struct rtl2832_sdr_state *s)
 	int i;
 
 	for (i = s->urbs_submitted - 1; i >= 0; i--) {
-		dev_dbg(&s->udev->dev, "%s: kill urb=%d\n", __func__, i);
+		dev_dbg(&s->udev->dev, "kill urb=%d\n", i);
 		/* stop the URB */
 		usb_kill_urb(s->urb_list[i]);
 	}
@@ -457,7 +459,7 @@ static int rtl2832_sdr_submit_urbs(struct rtl2832_sdr_state *s)
 	int i, ret;
 
 	for (i = 0; i < s->urbs_initialized; i++) {
-		dev_dbg(&s->udev->dev, "%s: submit urb=%d\n", __func__, i);
+		dev_dbg(&s->udev->dev, "submit urb=%d\n", i);
 		ret = usb_submit_urb(s->urb_list[i], GFP_ATOMIC);
 		if (ret) {
 			dev_err(&s->udev->dev,
@@ -477,8 +479,7 @@ static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_state *s)
 	if (s->flags & USB_STATE_URB_BUF) {
 		while (s->buf_num) {
 			s->buf_num--;
-			dev_dbg(&s->udev->dev, "%s: free buf=%d\n",
-					__func__, s->buf_num);
+			dev_dbg(&s->udev->dev, "free buf=%d\n", s->buf_num);
 			usb_free_coherent(s->udev, s->buf_size,
 					  s->buf_list[s->buf_num],
 					  s->dma_addr[s->buf_num]);
@@ -494,24 +495,22 @@ static int rtl2832_sdr_alloc_stream_bufs(struct rtl2832_sdr_state *s)
 	s->buf_num = 0;
 	s->buf_size = BULK_BUFFER_SIZE;
 
-	dev_dbg(&s->udev->dev,
-			"%s: all in all I will use %u bytes for streaming\n",
-			__func__,  MAX_BULK_BUFS * BULK_BUFFER_SIZE);
+	dev_dbg(&s->udev->dev, "all in all I will use %u bytes for streaming\n",
+			MAX_BULK_BUFS * BULK_BUFFER_SIZE);
 
 	for (s->buf_num = 0; s->buf_num < MAX_BULK_BUFS; s->buf_num++) {
 		s->buf_list[s->buf_num] = usb_alloc_coherent(s->udev,
 				BULK_BUFFER_SIZE, GFP_ATOMIC,
 				&s->dma_addr[s->buf_num]);
 		if (!s->buf_list[s->buf_num]) {
-			dev_dbg(&s->udev->dev, "%s: alloc buf=%d failed\n",
-					__func__, s->buf_num);
+			dev_dbg(&s->udev->dev, "alloc buf=%d failed\n",
+					s->buf_num);
 			rtl2832_sdr_free_stream_bufs(s);
 			return -ENOMEM;
 		}
 
-		dev_dbg(&s->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
-				__func__, s->buf_num,
-				s->buf_list[s->buf_num],
+		dev_dbg(&s->udev->dev, "alloc buf=%d %p (dma %llu)\n",
+				s->buf_num, s->buf_list[s->buf_num],
 				(long long)s->dma_addr[s->buf_num]);
 		s->flags |= USB_STATE_URB_BUF;
 	}
@@ -527,8 +526,7 @@ static int rtl2832_sdr_free_urbs(struct rtl2832_sdr_state *s)
 
 	for (i = s->urbs_initialized - 1; i >= 0; i--) {
 		if (s->urb_list[i]) {
-			dev_dbg(&s->udev->dev, "%s: free urb=%d\n",
-					__func__, i);
+			dev_dbg(&s->udev->dev, "free urb=%d\n", i);
 			/* free the URBs */
 			usb_free_urb(s->urb_list[i]);
 		}
@@ -544,10 +542,10 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
 
 	/* allocate the URBs */
 	for (i = 0; i < MAX_BULK_BUFS; i++) {
-		dev_dbg(&s->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+		dev_dbg(&s->udev->dev, "alloc urb=%d\n", i);
 		s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
 		if (!s->urb_list[i]) {
-			dev_dbg(&s->udev->dev, "%s: failed\n", __func__);
+			dev_dbg(&s->udev->dev, "failed\n");
 			for (j = 0; j < i; j++)
 				usb_free_urb(s->urb_list[j]);
 			return -ENOMEM;
@@ -570,9 +568,9 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
 /* Must be called with vb_queue_lock hold */
 static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
 {
-	unsigned long flags = 0;
+	unsigned long flags;
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	spin_lock_irqsave(&s->queued_bufs_lock, flags);
 	while (!list_empty(&s->queued_bufs)) {
@@ -591,7 +589,7 @@ static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
 {
 	struct rtl2832_sdr_state *s = fe->sec_priv;
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	mutex_lock(&s->vb_queue_lock);
 	mutex_lock(&s->v4l2_lock);
@@ -613,7 +611,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
 {
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
 	strlcpy(cap->card, s->vdev.name, sizeof(cap->card));
@@ -631,15 +629,15 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
 {
 	struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
 
-	dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
+	dev_dbg(&s->udev->dev, "nbuffers=%d\n", *nbuffers);
 
 	/* Need at least 8 buffers */
 	if (vq->num_buffers + *nbuffers < 8)
 		*nbuffers = 8 - vq->num_buffers;
 	*nplanes = 1;
 	sizes[0] = PAGE_ALIGN(s->buffersize);
-	dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
-			__func__, *nbuffers, sizes[0]);
+	dev_dbg(&s->udev->dev, "nbuffers=%d sizes[0]=%d\n",
+			*nbuffers, sizes[0]);
 	return 0;
 }
 
@@ -659,7 +657,7 @@ static void rtl2832_sdr_buf_queue(struct vb2_buffer *vb)
 	struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
 	struct rtl2832_sdr_frame_buf *buf =
 			container_of(vb, struct rtl2832_sdr_frame_buf, vb);
-	unsigned long flags = 0;
+	unsigned long flags;
 
 	/* Check the device has not disconnected between prep and queuing */
 	if (!s->udev) {
@@ -681,7 +679,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
 	u64 u64tmp;
 	u32 u32tmp;
 
-	dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
+	dev_dbg(&s->udev->dev, "f_adc=%u\n", s->f_adc);
 
 	if (!test_bit(POWER_ON, &s->flags))
 		return 0;
@@ -715,8 +713,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
 	u64tmp = -u64tmp;
 	u32tmp = u64tmp & 0x3fffff;
 
-	dev_dbg(&s->udev->dev, "%s: f_if=%u if_ctl=%08x\n",
-			__func__, f_if, u32tmp);
+	dev_dbg(&s->udev->dev, "f_if=%u if_ctl=%08x\n", f_if, u32tmp);
 
 	buf[0] = (u32tmp >> 16) & 0xff;
 	buf[1] = (u32tmp >>  8) & 0xff;
@@ -903,7 +900,7 @@ static void rtl2832_sdr_unset_adc(struct rtl2832_sdr_state *s)
 {
 	int ret;
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	/* PID filter */
 	ret = rtl2832_sdr_wr_regs(s, 0x061, "\xe0", 1);
@@ -964,8 +961,8 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s)
 	c->frequency = s->f_tuner;
 	c->delivery_system = SYS_DVBT;
 
-	dev_dbg(&s->udev->dev, "%s: frequency=%u bandwidth=%d\n",
-			__func__, c->frequency, c->bandwidth_hz);
+	dev_dbg(&s->udev->dev, "frequency=%u bandwidth=%d\n",
+			c->frequency, c->bandwidth_hz);
 
 	if (!test_bit(POWER_ON, &s->flags))
 		return 0;
@@ -980,7 +977,7 @@ static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
 {
 	struct dvb_frontend *fe = s->fe;
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	if (fe->ops.tuner_ops.init)
 		fe->ops.tuner_ops.init(fe);
@@ -992,7 +989,7 @@ static void rtl2832_sdr_unset_tuner(struct rtl2832_sdr_state *s)
 {
 	struct dvb_frontend *fe = s->fe;
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	if (fe->ops.tuner_ops.sleep)
 		fe->ops.tuner_ops.sleep(fe);
@@ -1005,7 +1002,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
 	struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
 	int ret;
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	if (!s->udev)
 		return -ENODEV;
@@ -1054,7 +1051,7 @@ static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
 {
 	struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	mutex_lock(&s->v4l2_lock);
 
@@ -1088,8 +1085,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
 {
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 
-	dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
-			__func__, v->index, v->type);
+	dev_dbg(&s->udev->dev, "index=%d type=%d\n", v->index, v->type);
 
 	if (v->index == 0) {
 		strlcpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
@@ -1115,7 +1111,7 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
 {
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	if (v->index > 1)
 		return -EINVAL;
@@ -1127,8 +1123,8 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
 {
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 
-	dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
-			__func__, band->tuner, band->type, band->index);
+	dev_dbg(&s->udev->dev, "tuner=%d type=%d index=%d\n",
+			band->tuner, band->type, band->index);
 
 	if (band->tuner == 0) {
 		if (band->index >= ARRAY_SIZE(bands_adc))
@@ -1153,8 +1149,8 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 	int ret  = 0;
 
-	dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
-			__func__, f->tuner, f->type);
+	dev_dbg(&s->udev->dev, "tuner=%d type=%d\n",
+			f->tuner, f->type);
 
 	if (f->tuner == 0) {
 		f->frequency = s->f_adc;
@@ -1175,8 +1171,8 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 	int ret, band;
 
-	dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
-			__func__, f->tuner, f->type, f->frequency);
+	dev_dbg(&s->udev->dev, "tuner=%d type=%d frequency=%u\n",
+			f->tuner, f->type, f->frequency);
 
 	/* ADC band midpoints */
 	#define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
@@ -1194,15 +1190,13 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
 				bands_adc[band].rangelow,
 				bands_adc[band].rangehigh);
 
-		dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
-				__func__, s->f_adc);
+		dev_dbg(&s->udev->dev, "ADC frequency=%u Hz\n", s->f_adc);
 		ret = rtl2832_sdr_set_adc(s);
 	} else if (f->tuner == 1) {
 		s->f_tuner = clamp_t(unsigned int, f->frequency,
 				bands_fm[0].rangelow,
 				bands_fm[0].rangehigh);
-		dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
-				__func__, f->frequency);
+		dev_dbg(&s->udev->dev, "RF frequency=%u Hz\n", f->frequency);
 
 		ret = rtl2832_sdr_set_tuner_freq(s);
 	} else {
@@ -1217,7 +1211,7 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
 {
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	if (f->index >= s->num_formats)
 		return -EINVAL;
@@ -1233,7 +1227,7 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
 {
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 
-	dev_dbg(&s->udev->dev, "%s:\n", __func__);
+	dev_dbg(&s->udev->dev, "\n");
 
 	f->fmt.sdr.pixelformat = s->pixelformat;
 	f->fmt.sdr.buffersize = s->buffersize;
@@ -1250,7 +1244,7 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
 	struct vb2_queue *q = &s->vb_queue;
 	int i;
 
-	dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+	dev_dbg(&s->udev->dev, "pixelformat fourcc %4.4s\n",
 			(char *)&f->fmt.sdr.pixelformat);
 
 	if (vb2_is_busy(q))
@@ -1280,7 +1274,7 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
 	struct rtl2832_sdr_state *s = video_drvdata(file);
 	int i;
 
-	dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+	dev_dbg(&s->udev->dev, "pixelformat fourcc %4.4s\n",
 			(char *)&f->fmt.sdr.pixelformat);
 
 	memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
@@ -1354,8 +1348,8 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
 	int ret;
 
 	dev_dbg(&s->udev->dev,
-			"%s: id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
-			__func__, ctrl->id, ctrl->name, ctrl->val,
+			"id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
+			ctrl->id, ctrl->name, ctrl->val,
 			ctrl->minimum, ctrl->maximum, ctrl->step);
 
 	switch (ctrl->id) {
@@ -1432,7 +1426,7 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
 	s->pixelformat = formats[0].pixelformat;
 	s->buffersize = formats[0].buffersize;
 	s->num_formats = NUM_FORMATS;
-	if (rtl2832_sdr_emulated_fmt == false)
+	if (!rtl2832_sdr_emulated_fmt)
 		s->num_formats -= 1;
 
 	mutex_init(&s->v4l2_lock);

+ 43 - 20
drivers/media/dvb-frontends/si2165.c

@@ -1,5 +1,5 @@
 /*
-    Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+    Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
 
     Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
 
@@ -44,9 +44,7 @@ struct si2165_state {
 
 	struct si2165_config config;
 
-	/* chip revision */
-	u8 revcode;
-	/* chip type */
+	u8 chip_revcode;
 	u8 chip_type;
 
 	/* calculated by xtal and div settings */
@@ -312,7 +310,7 @@ static u32 si2165_get_fe_clk(struct si2165_state *state)
 	return state->adc_clk;
 }
 
-static bool si2165_wait_init_done(struct si2165_state *state)
+static int si2165_wait_init_done(struct si2165_state *state)
 {
 	int ret = -EINVAL;
 	u8 val = 0;
@@ -407,7 +405,7 @@ static int si2165_upload_firmware(struct si2165_state *state)
 	int ret;
 
 	const struct firmware *fw = NULL;
-	u8 *fw_file = SI2165_FIRMWARE;
+	u8 *fw_file;
 	const u8 *data;
 	u32 len;
 	u32 offset;
@@ -415,10 +413,20 @@ static int si2165_upload_firmware(struct si2165_state *state)
 	u8 block_count;
 	u16 crc_expected;
 
+	switch (state->chip_revcode) {
+	case 0x03: /* revision D */
+		fw_file = SI2165_FIRMWARE_REV_D;
+		break;
+	default:
+		dev_info(&state->i2c->dev, "%s: no firmware file for revision=%d\n",
+			KBUILD_MODNAME, state->chip_revcode);
+		return 0;
+	}
+
 	/* request the firmware, this will block and timeout */
 	ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
 	if (ret) {
-		dev_warn(&state->i2c->dev, "%s: firmare file '%s' not found\n",
+		dev_warn(&state->i2c->dev, "%s: firmware file '%s' not found\n",
 				KBUILD_MODNAME, fw_file);
 		goto error;
 	}
@@ -908,7 +916,7 @@ static void si2165_release(struct dvb_frontend *fe)
 
 static struct dvb_frontend_ops si2165_ops = {
 	.info = {
-		.name = "Silicon Labs Si2165",
+		.name = "Silicon Labs ",
 		.caps =	FE_CAN_FEC_1_2 |
 			FE_CAN_FEC_2_3 |
 			FE_CAN_FEC_3_4 |
@@ -948,6 +956,8 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
 	int n;
 	int io_ret;
 	u8 val;
+	char rev_char;
+	const char *chip_name;
 
 	if (config == NULL || i2c == NULL)
 		goto error;
@@ -984,7 +994,7 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
 	if (val != state->config.chip_mode)
 		goto error;
 
-	io_ret = si2165_readreg8(state, 0x0023 , &state->revcode);
+	io_ret = si2165_readreg8(state, 0x0023, &state->chip_revcode);
 	if (io_ret < 0)
 		goto error;
 
@@ -997,22 +1007,35 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
 	if (io_ret < 0)
 		goto error;
 
-	dev_info(&state->i2c->dev, "%s: hardware revision 0x%02x, chip type 0x%02x\n",
-		 KBUILD_MODNAME, state->revcode, state->chip_type);
+	if (state->chip_revcode < 26)
+		rev_char = 'A' + state->chip_revcode;
+	else
+		rev_char = '?';
 
-	/* It is a guess that register 0x0118 (chip type?) can be used to
-	 * differ between si2161, si2163 and si2165
-	 * Only si2165 has been tested.
-	 */
-	if (state->revcode == 0x03 && state->chip_type == 0x07) {
+	switch (state->chip_type) {
+	case 0x06:
+		chip_name = "Si2161";
+		state->has_dvbt = true;
+		break;
+	case 0x07:
+		chip_name = "Si2165";
 		state->has_dvbt = true;
 		state->has_dvbc = true;
-	} else {
-		dev_err(&state->i2c->dev, "%s: Unsupported chip.\n",
-			KBUILD_MODNAME);
+		break;
+	default:
+		dev_err(&state->i2c->dev, "%s: Unsupported Silicon Labs chip (type %d, rev %d)\n",
+			KBUILD_MODNAME, state->chip_type, state->chip_revcode);
 		goto error;
 	}
 
+	dev_info(&state->i2c->dev,
+		"%s: Detected Silicon Labs %s-%c (type %d, rev %d)\n",
+		KBUILD_MODNAME, chip_name, rev_char, state->chip_type,
+		state->chip_revcode);
+
+	strlcat(state->frontend.ops.info.name, chip_name,
+			sizeof(state->frontend.ops.info.name));
+
 	n = 0;
 	if (state->has_dvbt) {
 		state->frontend.ops.delsys[n++] = SYS_DVBT;
@@ -1037,4 +1060,4 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 MODULE_DESCRIPTION("Silicon Labs Si2165 DVB-C/-T Demodulator driver");
 MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
 MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(SI2165_FIRMWARE);
+MODULE_FIRMWARE(SI2165_FIRMWARE_REV_D);

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

@@ -18,6 +18,6 @@
 #ifndef _DVB_SI2165_PRIV
 #define _DVB_SI2165_PRIV
 
-#define SI2165_FIRMWARE "dvb-demod-si2165.fw"
+#define SI2165_FIRMWARE_REV_D "dvb-demod-si2165.fw"
 
 #endif /* _DVB_SI2165_PRIV */

+ 83 - 46
drivers/media/dvb-frontends/si2168.c

@@ -55,8 +55,7 @@ static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
 				break;
 		}
 
-		dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n",
-				__func__,
+		dev_dbg(&s->client->dev, "cmd execution took %d ms\n",
 				jiffies_to_msecs(jiffies) -
 				(jiffies_to_msecs(timeout) - TIMEOUT));
 
@@ -75,7 +74,7 @@ err_mutex_unlock:
 
 	return 0;
 err:
-	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&s->client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
@@ -150,12 +149,12 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
 		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 	}
 
-	dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
-			__func__, *status, cmd.rlen, cmd.args);
+	dev_dbg(&s->client->dev, "status=%02x args=%*ph\n",
+			*status, cmd.rlen, cmd.args);
 
 	return 0;
 err:
-	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&s->client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
@@ -168,10 +167,10 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	u8 bandwidth, delivery_system;
 
 	dev_dbg(&s->client->dev,
-			"%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u\n",
-			__func__, c->delivery_system, c->modulation,
+			"delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u, stream_id=%d\n",
+			c->delivery_system, c->modulation,
 			c->frequency, c->bandwidth_hz, c->symbol_rate,
-			c->inversion);
+			c->inversion, c->stream_id);
 
 	if (!s->active) {
 		ret = -EAGAIN;
@@ -235,6 +234,18 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
+	if (c->delivery_system == SYS_DVBT2) {
+		/* select PLP */
+		cmd.args[0] = 0x52;
+		cmd.args[1] = c->stream_id & 0xff;
+		cmd.args[2] = c->stream_id == NO_STREAM_ID_FILTER ? 0 : 1;
+		cmd.wlen = 3;
+		cmd.rlen = 1;
+		ret = si2168_cmd_execute(s, &cmd);
+		if (ret)
+			goto err;
+	}
+
 	memcpy(cmd.args, "\x51\x03", 2);
 	cmd.wlen = 2;
 	cmd.rlen = 12;
@@ -297,13 +308,6 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 4;
-	ret = si2168_cmd_execute(s, &cmd);
-	if (ret)
-		goto err;
-
 	memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
 	cmd.wlen = 6;
 	cmd.rlen = 4;
@@ -343,7 +347,7 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
 
 	return 0;
 err:
-	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&s->client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
@@ -357,8 +361,9 @@ static int si2168_init(struct dvb_frontend *fe)
 	struct si2168_cmd cmd;
 	unsigned int chip_id;
 
-	dev_dbg(&s->client->dev, "%s:\n", __func__);
+	dev_dbg(&s->client->dev, "\n");
 
+	/* initialize */
 	memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
 	cmd.wlen = 13;
 	cmd.rlen = 0;
@@ -366,6 +371,26 @@ static int si2168_init(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
+	if (s->fw_loaded) {
+		/* resume */
+		memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8);
+		cmd.wlen = 8;
+		cmd.rlen = 1;
+		ret = si2168_cmd_execute(s, &cmd);
+		if (ret)
+			goto err;
+
+		memcpy(cmd.args, "\x85", 1);
+		cmd.wlen = 1;
+		cmd.rlen = 1;
+		ret = si2168_cmd_execute(s, &cmd);
+		if (ret)
+			goto err;
+
+		goto warm;
+	}
+
+	/* power up */
 	memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
 	cmd.wlen = 8;
 	cmd.rlen = 1;
@@ -400,16 +425,16 @@ static int si2168_init(struct dvb_frontend *fe)
 		break;
 	default:
 		dev_err(&s->client->dev,
-				"%s: unkown chip version Si21%d-%c%c%c\n",
-				KBUILD_MODNAME, cmd.args[2], cmd.args[1],
+				"unknown chip version Si21%d-%c%c%c\n",
+				cmd.args[2], cmd.args[1],
 				cmd.args[3], cmd.args[4]);
 		ret = -EINVAL;
 		goto err;
 	}
 
 	/* cold state - try to download firmware */
-	dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
-			KBUILD_MODNAME, si2168_ops.info.name);
+	dev_info(&s->client->dev, "found a '%s' in cold state\n",
+			si2168_ops.info.name);
 
 	/* request the firmware, this will block and timeout */
 	ret = request_firmware(&fw, fw_file, &s->client->dev);
@@ -422,18 +447,18 @@ static int si2168_init(struct dvb_frontend *fe)
 
 		if (ret == 0) {
 			dev_notice(&s->client->dev,
-					"%s: please install firmware file '%s'\n",
-					KBUILD_MODNAME, SI2168_B40_FIRMWARE);
+					"please install firmware file '%s'\n",
+					SI2168_B40_FIRMWARE);
 		} else {
 			dev_err(&s->client->dev,
-					"%s: firmware file '%s' not found\n",
-					KBUILD_MODNAME, fw_file);
+					"firmware file '%s' not found\n",
+					fw_file);
 			goto err;
 		}
 	}
 
-	dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
-			KBUILD_MODNAME, fw_file);
+	dev_info(&s->client->dev, "downloading firmware from file '%s'\n",
+			fw_file);
 
 	for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
 		len = remaining;
@@ -446,8 +471,8 @@ static int si2168_init(struct dvb_frontend *fe)
 		ret = si2168_cmd_execute(s, &cmd);
 		if (ret) {
 			dev_err(&s->client->dev,
-					"%s: firmware download failed=%d\n",
-					KBUILD_MODNAME, ret);
+					"firmware download failed=%d\n",
+					ret);
 			goto err;
 		}
 	}
@@ -462,8 +487,20 @@ static int si2168_init(struct dvb_frontend *fe)
 	if (ret)
 		goto err;
 
-	dev_info(&s->client->dev, "%s: found a '%s' in warm state\n",
-			KBUILD_MODNAME, si2168_ops.info.name);
+	/* set ts mode */
+	memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6);
+	cmd.args[4] |= s->ts_mode;
+	cmd.wlen = 6;
+	cmd.rlen = 4;
+	ret = si2168_cmd_execute(s, &cmd);
+	if (ret)
+		goto err;
+
+	s->fw_loaded = true;
+
+warm:
+	dev_info(&s->client->dev, "found a '%s' in warm state\n",
+			si2168_ops.info.name);
 
 	s->active = true;
 
@@ -472,7 +509,7 @@ err:
 	if (fw)
 		release_firmware(fw);
 
-	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&s->client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
@@ -482,7 +519,7 @@ static int si2168_sleep(struct dvb_frontend *fe)
 	int ret;
 	struct si2168_cmd cmd;
 
-	dev_dbg(&s->client->dev, "%s:\n", __func__);
+	dev_dbg(&s->client->dev, "\n");
 
 	s->active = false;
 
@@ -495,7 +532,7 @@ static int si2168_sleep(struct dvb_frontend *fe)
 
 	return 0;
 err:
-	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&s->client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
@@ -528,8 +565,7 @@ static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
 	/* open tuner I2C gate */
 	ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1);
 	if (ret != 1) {
-		dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
-				KBUILD_MODNAME, ret);
+		dev_warn(&s->client->dev, "i2c write failed=%d\n", ret);
 		if (ret >= 0)
 			ret = -EREMOTEIO;
 	} else {
@@ -553,8 +589,7 @@ static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
 	/* close tuner I2C gate */
 	ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1);
 	if (ret != 1) {
-		dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
-				KBUILD_MODNAME, ret);
+		dev_warn(&s->client->dev, "i2c write failed=%d\n", ret);
 		if (ret >= 0)
 			ret = -EREMOTEIO;
 	} else {
@@ -587,7 +622,8 @@ static const struct dvb_frontend_ops si2168_ops = {
 			FE_CAN_GUARD_INTERVAL_AUTO |
 			FE_CAN_HIERARCHY_AUTO |
 			FE_CAN_MUTE_TS |
-			FE_CAN_2G_MODULATION
+			FE_CAN_2G_MODULATION |
+			FE_CAN_MULTISTREAM
 	},
 
 	.get_tune_settings = si2168_get_tune_settings,
@@ -607,12 +643,12 @@ static int si2168_probe(struct i2c_client *client,
 	struct si2168 *s;
 	int ret;
 
-	dev_dbg(&client->dev, "%s:\n", __func__);
+	dev_dbg(&client->dev, "\n");
 
 	s = kzalloc(sizeof(struct si2168), GFP_KERNEL);
 	if (!s) {
 		ret = -ENOMEM;
-		dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+		dev_err(&client->dev, "kzalloc() failed\n");
 		goto err;
 	}
 
@@ -633,16 +669,17 @@ static int si2168_probe(struct i2c_client *client,
 
 	*config->i2c_adapter = s->adapter;
 	*config->fe = &s->fe;
+	s->ts_mode = config->ts_mode;
+	s->fw_loaded = false;
 
 	i2c_set_clientdata(client, s);
 
 	dev_info(&s->client->dev,
-			"%s: Silicon Labs Si2168 successfully attached\n",
-			KBUILD_MODNAME);
+			"Silicon Labs Si2168 successfully attached\n");
 	return 0;
 err:
 	kfree(s);
-	dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
+	dev_dbg(&client->dev, "failed=%d\n", ret);
 	return ret;
 }
 
@@ -650,7 +687,7 @@ static int si2168_remove(struct i2c_client *client)
 {
 	struct si2168 *s = i2c_get_clientdata(client);
 
-	dev_dbg(&client->dev, "%s:\n", __func__);
+	dev_dbg(&client->dev, "\n");
 
 	i2c_del_mux_adapter(s->adapter);
 

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

@@ -34,6 +34,12 @@ struct si2168_config {
 	 * returned by driver
 	 */
 	struct i2c_adapter **i2c_adapter;
+
+	/* TS mode */
+	u8 ts_mode;
 };
 
+#define SI2168_TS_PARALLEL	0x06
+#define SI2168_TS_SERIAL	0x03
+
 #endif

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

@@ -36,6 +36,8 @@ struct si2168 {
 	fe_delivery_system_t delivery_system;
 	fe_status_t fe_status;
 	bool active;
+	bool fw_loaded;
+	u8 ts_mode;
 };
 
 /* firmare command struct */

+ 3 - 0
drivers/media/dvb-frontends/si21xx.c

@@ -236,6 +236,9 @@ static int si21_writeregs(struct si21xx_state *state, u8 reg1,
 				.len = len + 1
 	};
 
+	if (len > sizeof(buf) - 1)
+		return -EINVAL;
+
 	msg.buf[0] =  reg1;
 	memcpy(msg.buf + 1, data, len);
 

+ 441 - 0
drivers/media/dvb-frontends/sp2.c

@@ -0,0 +1,441 @@
+/*
+ * CIMaX SP2/SP2HF (Atmel T90FJR) CI driver
+ *
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
+ *
+ * Heavily based on CIMax2(R) SP2 driver in conjunction with NetUp Dual
+ * DVB-S2 CI card (cimax2) with following copyrights:
+ *
+ *  Copyright (C) 2009 NetUP Inc.
+ *  Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *  Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#include "sp2_priv.h"
+
+static int sp2_read_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
+{
+	int ret;
+	struct i2c_client *client = s->client;
+	struct i2c_adapter *adap = client->adapter;
+	struct i2c_msg msg[] = {
+		{
+			.addr = client->addr,
+			.flags = 0,
+			.buf = &reg,
+			.len = 1
+		}, {
+			.addr = client->addr,
+			.flags	= I2C_M_RD,
+			.buf = buf,
+			.len = len
+		}
+	};
+
+	ret = i2c_transfer(adap, msg, 2);
+
+	if (ret != 2) {
+		dev_err(&client->dev, "i2c read error, reg = 0x%02x, status = %d\n",
+				reg, ret);
+		if (ret < 0)
+			return ret;
+		else
+			return -EIO;
+	}
+
+	dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %02x\n",
+				client->addr, reg, buf[0]);
+
+	return 0;
+}
+
+static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
+{
+	int ret;
+	u8 buffer[35];
+	struct i2c_client *client = s->client;
+	struct i2c_adapter *adap = client->adapter;
+	struct i2c_msg msg = {
+		.addr = client->addr,
+		.flags = 0,
+		.buf = &buffer[0],
+		.len = len + 1
+	};
+
+	if ((len + 1) > sizeof(buffer)) {
+		dev_err(&client->dev, "i2c wr reg=%02x: len=%d is too big!\n",
+				reg, len);
+		return -EINVAL;
+	}
+
+	buffer[0] = reg;
+	memcpy(&buffer[1], buf, len);
+
+	ret = i2c_transfer(adap, &msg, 1);
+
+	if (ret != 1) {
+		dev_err(&client->dev, "i2c write error, reg = 0x%02x, status = %d\n",
+				reg, ret);
+		if (ret < 0)
+			return ret;
+		else
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
+			u8 read, int addr, u8 data)
+{
+	struct sp2 *s = en50221->data;
+	u8 store;
+	int mem, ret;
+	int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control;
+
+	dev_dbg(&s->client->dev, "slot=%d, acs=0x%02x, addr=0x%04x, data = 0x%02x",
+			slot, acs, addr, data);
+
+	if (slot != 0)
+		return -EINVAL;
+
+	/*
+	 * change module access type between IO space and attribute memory
+	 * when needed
+	 */
+	if (s->module_access_type != acs) {
+		ret = sp2_read_i2c(s, 0x00, &store, 1);
+
+		if (ret)
+			return ret;
+
+		store &= ~(SP2_MOD_CTL_ACS1 | SP2_MOD_CTL_ACS0);
+		store |= acs;
+
+		ret = sp2_write_i2c(s, 0x00, &store, 1);
+		if (ret)
+			return ret;
+	}
+
+	s->module_access_type = acs;
+
+	/* implementation of ci_op_cam is device specific */
+	if (ci_op_cam) {
+		ret = ci_op_cam(s->priv, read, addr, data, &mem);
+	} else {
+		dev_err(&s->client->dev, "callback not defined");
+		return -EINVAL;
+	}
+
+	if (ret)
+		return ret;
+
+	if (read) {
+		dev_dbg(&s->client->dev, "cam read, addr=0x%04x, data = 0x%04x",
+				addr, mem);
+		return mem;
+	} else {
+		return 0;
+	}
+}
+
+int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+				int slot, int addr)
+{
+	return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
+			SP2_CI_RD, addr, 0);
+}
+
+int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+				int slot, int addr, u8 data)
+{
+	return sp2_ci_op_cam(en50221, slot, SP2_CI_ATTR_ACS,
+			SP2_CI_WR, addr, data);
+}
+
+int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
+				int slot, u8 addr)
+{
+	return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
+			SP2_CI_RD, addr, 0);
+}
+
+int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
+				int slot, u8 addr, u8 data)
+{
+	return sp2_ci_op_cam(en50221, slot, SP2_CI_IO_ACS,
+			SP2_CI_WR, addr, data);
+}
+
+int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
+{
+	struct sp2 *s = en50221->data;
+	u8 buf;
+	int ret;
+
+	dev_dbg(&s->client->dev, "slot: %d\n", slot);
+
+	if (slot != 0)
+		return -EINVAL;
+
+	/* RST on */
+	buf = SP2_MOD_CTL_RST;
+	ret = sp2_write_i2c(s, 0x00, &buf, 1);
+
+	if (ret)
+		return ret;
+
+	usleep_range(500, 600);
+
+	/* RST off */
+	buf = 0x00;
+	ret = sp2_write_i2c(s, 0x00, &buf, 1);
+
+	if (ret)
+		return ret;
+
+	msleep(1000);
+
+	return 0;
+}
+
+int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
+{
+	struct sp2 *s = en50221->data;
+
+	dev_dbg(&s->client->dev, "slot:%d\n", slot);
+
+	/* not implemented */
+	return 0;
+}
+
+int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot)
+{
+	struct sp2 *s = en50221->data;
+	u8 buf;
+
+	dev_dbg(&s->client->dev, "slot:%d\n", slot);
+
+	if (slot != 0)
+		return -EINVAL;
+
+	sp2_read_i2c(s, 0x00, &buf, 1);
+
+	/* disable bypass and enable TS */
+	buf |= (SP2_MOD_CTL_TSOEN | SP2_MOD_CTL_TSIEN);
+	return sp2_write_i2c(s, 0, &buf, 1);
+}
+
+int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
+				int slot, int open)
+{
+	struct sp2 *s = en50221->data;
+	u8 buf[2];
+	int ret;
+
+	dev_dbg(&s->client->dev, "slot:%d open:%d\n", slot, open);
+
+	/*
+	 * CAM module INSERT/REMOVE processing. Slow operation because of i2c
+	 * transfers. Throttle read to one per sec.
+	 */
+	if (time_after(jiffies, s->next_status_checked_time)) {
+		ret = sp2_read_i2c(s, 0x00, buf, 1);
+		s->next_status_checked_time = jiffies +	msecs_to_jiffies(1000);
+
+		if (ret)
+			return 0;
+
+		if (buf[0] & SP2_MOD_CTL_DET)
+			s->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
+					DVB_CA_EN50221_POLL_CAM_READY;
+		else
+			s->status = 0;
+	}
+
+	return s->status;
+}
+
+int sp2_init(struct sp2 *s)
+{
+	int ret = 0;
+	u8 buf;
+	u8 cimax_init[34] = {
+		0x00, /* module A control*/
+		0x00, /* auto select mask high A */
+		0x00, /* auto select mask low A */
+		0x00, /* auto select pattern high A */
+		0x00, /* auto select pattern low A */
+		0x44, /* memory access time A, 600 ns */
+		0x00, /* invert input A */
+		0x00, /* RFU */
+		0x00, /* RFU */
+		0x00, /* module B control*/
+		0x00, /* auto select mask high B */
+		0x00, /* auto select mask low B */
+		0x00, /* auto select pattern high B */
+		0x00, /* auto select pattern low B */
+		0x44, /* memory access time B, 600 ns */
+		0x00, /* invert input B */
+		0x00, /* RFU */
+		0x00, /* RFU */
+		0x00, /* auto select mask high Ext */
+		0x00, /* auto select mask low Ext */
+		0x00, /* auto select pattern high Ext */
+		0x00, /* auto select pattern low Ext */
+		0x00, /* RFU */
+		0x02, /* destination - module A */
+		0x01, /* power control reg, VCC power on */
+		0x00, /* RFU */
+		0x00, /* int status read only */
+		0x00, /* Interrupt Mask Register */
+		0x05, /* EXTINT=active-high, INT=push-pull */
+		0x00, /* USCG1 */
+		0x04, /* ack active low */
+		0x00, /* LOCK = 0 */
+		0x22, /* unknown */
+		0x00, /* synchronization? */
+	};
+
+	dev_dbg(&s->client->dev, "\n");
+
+	s->ca.owner = THIS_MODULE;
+	s->ca.read_attribute_mem = sp2_ci_read_attribute_mem;
+	s->ca.write_attribute_mem = sp2_ci_write_attribute_mem;
+	s->ca.read_cam_control = sp2_ci_read_cam_control;
+	s->ca.write_cam_control = sp2_ci_write_cam_control;
+	s->ca.slot_reset = sp2_ci_slot_reset;
+	s->ca.slot_shutdown = sp2_ci_slot_shutdown;
+	s->ca.slot_ts_enable = sp2_ci_slot_ts_enable;
+	s->ca.poll_slot_status = sp2_ci_poll_slot_status;
+	s->ca.data = s;
+	s->module_access_type = 0;
+
+	/* initialize all regs */
+	ret = sp2_write_i2c(s, 0x00, &cimax_init[0], 34);
+	if (ret)
+		goto err;
+
+	/* lock registers */
+	buf = 1;
+	ret = sp2_write_i2c(s, 0x1f, &buf, 1);
+	if (ret)
+		goto err;
+
+	/* power on slots */
+	ret = sp2_write_i2c(s, 0x18, &buf, 1);
+	if (ret)
+		goto err;
+
+	ret = dvb_ca_en50221_init(s->dvb_adap, &s->ca, 0, 1);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	dev_dbg(&s->client->dev, "init failed=%d\n", ret);
+	return ret;
+}
+
+int sp2_exit(struct i2c_client *client)
+{
+	struct sp2 *s;
+
+	dev_dbg(&client->dev, "\n");
+
+	if (client == NULL)
+		return 0;
+
+	s = i2c_get_clientdata(client);
+	if (s == NULL)
+		return 0;
+
+	if (s->ca.data == NULL)
+		return 0;
+
+	dvb_ca_en50221_release(&s->ca);
+
+	return 0;
+}
+
+static int sp2_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct sp2_config *cfg = client->dev.platform_data;
+	struct sp2 *s;
+	int ret;
+
+	dev_dbg(&client->dev, "\n");
+
+	s = kzalloc(sizeof(struct sp2), GFP_KERNEL);
+	if (!s) {
+		ret = -ENOMEM;
+		dev_err(&client->dev, "kzalloc() failed\n");
+		goto err;
+	}
+
+	s->client = client;
+	s->dvb_adap = cfg->dvb_adap;
+	s->priv = cfg->priv;
+	s->ci_control = cfg->ci_control;
+
+	i2c_set_clientdata(client, s);
+
+	ret = sp2_init(s);
+	if (ret)
+		goto err;
+
+	dev_info(&s->client->dev, "CIMaX SP2 successfully attached\n");
+	return 0;
+err:
+	dev_dbg(&client->dev, "init failed=%d\n", ret);
+	kfree(s);
+
+	return ret;
+}
+
+static int sp2_remove(struct i2c_client *client)
+{
+	struct si2157 *s = i2c_get_clientdata(client);
+
+	dev_dbg(&client->dev, "\n");
+
+	sp2_exit(client);
+	if (s != NULL)
+		kfree(s);
+
+	return 0;
+}
+
+static const struct i2c_device_id sp2_id[] = {
+	{"sp2", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, sp2_id);
+
+static struct i2c_driver sp2_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "sp2",
+	},
+	.probe		= sp2_probe,
+	.remove		= sp2_remove,
+	.id_table	= sp2_id,
+};
+
+module_i2c_driver(sp2_driver);
+
+MODULE_DESCRIPTION("CIMaX SP2/HF CI driver");
+MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>");
+MODULE_LICENSE("GPL");

+ 53 - 0
drivers/media/dvb-frontends/sp2.h

@@ -0,0 +1,53 @@
+/*
+ * CIMaX SP2/HF CI driver
+ *
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef SP2_H
+#define SP2_H
+
+#include <linux/kconfig.h>
+#include "dvb_ca_en50221.h"
+
+/*
+ * I2C address
+ * 0x40 (port 0)
+ * 0x41 (port 1)
+ */
+struct sp2_config {
+	/* dvb_adapter to attach the ci to */
+	struct dvb_adapter *dvb_adap;
+
+	/* function ci_control handles the device specific ci ops */
+	void *ci_control;
+
+	/* priv is passed back to function ci_control */
+	void *priv;
+};
+
+extern int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+					int slot, int addr);
+extern int sp2_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+					int slot, int addr, u8 data);
+extern int sp2_ci_read_cam_control(struct dvb_ca_en50221 *en50221,
+					int slot, u8 addr);
+extern int sp2_ci_write_cam_control(struct dvb_ca_en50221 *en50221,
+					int slot, u8 addr, u8 data);
+extern int sp2_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
+extern int sp2_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
+extern int sp2_ci_slot_ts_enable(struct dvb_ca_en50221 *en50221, int slot);
+extern int sp2_ci_poll_slot_status(struct dvb_ca_en50221 *en50221,
+					int slot, int open);
+
+#endif

+ 50 - 0
drivers/media/dvb-frontends/sp2_priv.h

@@ -0,0 +1,50 @@
+/*
+ * CIMaX SP2/HF CI driver
+ *
+ * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef SP2_PRIV_H
+#define SP2_PRIV_H
+
+#include "sp2.h"
+#include "dvb_frontend.h"
+
+/* state struct */
+struct sp2 {
+	int status;
+	struct i2c_client *client;
+	struct dvb_adapter *dvb_adap;
+	struct dvb_ca_en50221 ca;
+	int module_access_type;
+	unsigned long next_status_checked_time;
+	void *priv;
+	void *ci_control;
+};
+
+#define SP2_CI_ATTR_ACS		0x00
+#define SP2_CI_IO_ACS		0x04
+#define SP2_CI_WR		0
+#define SP2_CI_RD		1
+
+/* Module control register (0x00 module A, 0x09 module B) bits */
+#define SP2_MOD_CTL_DET		0x01
+#define SP2_MOD_CTL_AUTO	0x02
+#define SP2_MOD_CTL_ACS0	0x04
+#define SP2_MOD_CTL_ACS1	0x08
+#define SP2_MOD_CTL_HAD		0x10
+#define SP2_MOD_CTL_TSIEN	0x20
+#define SP2_MOD_CTL_TSOEN	0x40
+#define SP2_MOD_CTL_RST		0x80
+
+#endif

+ 1 - 2
drivers/media/dvb-frontends/sp8870.c

@@ -394,8 +394,7 @@ static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
 	if (ret < 0)
 		return -EIO;
 
-	 tmp = ret << 6;
-
+	tmp = ret << 6;
 	if (tmp >= 0x3FFF0)
 		tmp = ~0;
 

+ 4 - 8
drivers/media/dvb-frontends/stv0367.c

@@ -59,7 +59,6 @@ struct stv0367cab_state {
 	int locked;			/* channel found		*/
 	u32 freq_khz;			/* found frequency (in kHz)	*/
 	u32 symbol_rate;		/* found symbol rate (in Bds)	*/
-	enum stv0367cab_mod modulation;	/* modulation			*/
 	fe_spectral_inversion_t	spect_inv; /* Spectrum Inversion	*/
 };
 
@@ -554,7 +553,7 @@ static struct st_register def0367ter[STV0367TER_NBREGS] = {
 #define RF_LOOKUP_TABLE_SIZE  31
 #define RF_LOOKUP_TABLE2_SIZE 16
 /* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
-s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
+static const s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
 	{/*AGC1*/
 		48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
 		64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
@@ -566,7 +565,7 @@ s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
 	}
 };
 /* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
-s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
+static const s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
 	{/*AGC2*/
 		28, 29, 31, 32, 34, 35, 36, 37,
 		38, 39, 40, 41, 42, 43, 44, 45,
@@ -1935,8 +1934,6 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe)
 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 	struct stv0367_state *state = fe->demodulator_priv;
 	struct stv0367ter_state *ter_state = state->ter_state;
-
-	int error = 0;
 	enum stv0367_ter_mode mode;
 	int constell = 0,/* snr = 0,*/ Data = 0;
 
@@ -2020,7 +2017,7 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe)
 
 	p->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
 
-	return error;
+	return 0;
 }
 
 static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
@@ -2999,7 +2996,6 @@ enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
 
 	if (QAMFEC_Lock) {
 		signalType = FE_CAB_DATAOK;
-		cab_state->modulation = p->modulation;
 		cab_state->spect_inv = stv0367_readbits(state,
 							F367CAB_QUAD_INV);
 #if 0
@@ -3165,7 +3161,7 @@ static int stv0367cab_get_frontend(struct dvb_frontend *fe)
 	case FE_CAB_MOD_QAM128:
 		p->modulation = QAM_128;
 		break;
-	case QAM_256:
+	case FE_CAB_MOD_QAM256:
 		p->modulation = QAM_256;
 		break;
 	default:

+ 2 - 5
drivers/media/dvb-frontends/stv0900_core.c

@@ -1270,7 +1270,6 @@ enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
 					enum fe_stv0900_demod_mode LDPC_Mode,
 					enum fe_stv0900_demod_num demod)
 {
-	enum fe_stv0900_error error = STV0900_NO_ERROR;
 	s32 reg_ind;
 
 	dprintk("%s\n", __func__);
@@ -1337,7 +1336,7 @@ enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
 		break;
 	}
 
-	return error;
+	return STV0900_NO_ERROR;
 }
 
 static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
@@ -1555,8 +1554,6 @@ static int stv0900_status(struct stv0900_internal *intp,
 static int stv0900_set_mis(struct stv0900_internal *intp,
 				enum fe_stv0900_demod_num demod, int mis)
 {
-	enum fe_stv0900_error error = STV0900_NO_ERROR;
-
 	dprintk("%s\n", __func__);
 
 	if (mis < 0 || mis > 255) {
@@ -1569,7 +1566,7 @@ static int stv0900_set_mis(struct stv0900_internal *intp,
 		stv0900_write_reg(intp, ISIBITENA, 0xff);
 	}
 
-	return error;
+	return STV0900_NO_ERROR;
 }
 
 

+ 2 - 1
drivers/media/dvb-frontends/stv0900_sw.c

@@ -1733,9 +1733,10 @@ static void stv0900_set_search_standard(struct stv0900_internal *intp,
 		break;
 	case STV0900_SEARCH_DSS:
 		dprintk("Search Standard = DSS\n");
-	case STV0900_SEARCH_DVBS2:
 		break;
+	case STV0900_SEARCH_DVBS2:
 		dprintk("Search Standard = DVBS2\n");
+		break;
 	case STV0900_AUTO_SEARCH:
 	default:
 		dprintk("Search Standard = AUTO\n");

+ 840 - 0
drivers/media/dvb-frontends/tc90522.c

@@ -0,0 +1,840 @@
+/*
+ * Toshiba TC90522 Demodulator
+ *
+ * Copyright (C) 2014 Akihiro Tsukada <tskd08@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ *
+ * 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.
+ */
+
+/*
+ * NOTICE:
+ * This driver is incomplete and lacks init/config of the chips,
+ * as the necessary info is not disclosed.
+ * It assumes that users of this driver (such as a PCI bridge of
+ * DTV receiver cards) properly init and configure the chip
+ * via I2C *before* calling this driver's init() function.
+ *
+ * Currently, PT3 driver is the only one that uses this driver,
+ * and contains init/config code in its firmware.
+ * Thus some part of the code might be dependent on PT3 specific config.
+ */
+
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <linux/dvb/frontend.h>
+#include "dvb_math.h"
+#include "tc90522.h"
+
+#define TC90522_I2C_THRU_REG 0xfe
+
+#define TC90522_MODULE_IDX(addr) (((u8)(addr) & 0x02U) >> 1)
+
+struct tc90522_state {
+	struct tc90522_config cfg;
+	struct dvb_frontend fe;
+	struct i2c_client *i2c_client;
+	struct i2c_adapter tuner_i2c;
+
+	bool lna;
+};
+
+struct reg_val {
+	u8 reg;
+	u8 val;
+};
+
+static int
+reg_write(struct tc90522_state *state, const struct reg_val *regs, int num)
+{
+	int i, ret;
+	struct i2c_msg msg;
+
+	ret = 0;
+	msg.addr = state->i2c_client->addr;
+	msg.flags = 0;
+	msg.len = 2;
+	for (i = 0; i < num; i++) {
+		msg.buf = (u8 *)&regs[i];
+		ret = i2c_transfer(state->i2c_client->adapter, &msg, 1);
+		if (ret == 0)
+			ret = -EIO;
+		if (ret < 0)
+			return ret;
+	}
+	return 0;
+}
+
+static int reg_read(struct tc90522_state *state, u8 reg, u8 *val, u8 len)
+{
+	struct i2c_msg msgs[2] = {
+		{
+			.addr = state->i2c_client->addr,
+			.flags = 0,
+			.buf = &reg,
+			.len = 1,
+		},
+		{
+			.addr = state->i2c_client->addr,
+			.flags = I2C_M_RD,
+			.buf = val,
+			.len = len,
+		},
+	};
+	int ret;
+
+	ret = i2c_transfer(state->i2c_client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret == ARRAY_SIZE(msgs))
+		ret = 0;
+	else if (ret >= 0)
+		ret = -EIO;
+	return ret;
+}
+
+static struct tc90522_state *cfg_to_state(struct tc90522_config *c)
+{
+	return container_of(c, struct tc90522_state, cfg);
+}
+
+
+static int tc90522s_set_tsid(struct dvb_frontend *fe)
+{
+	struct reg_val set_tsid[] = {
+		{ 0x8f, 00 },
+		{ 0x90, 00 }
+	};
+
+	set_tsid[0].val = (fe->dtv_property_cache.stream_id & 0xff00) >> 8;
+	set_tsid[1].val = fe->dtv_property_cache.stream_id & 0xff;
+	return reg_write(fe->demodulator_priv, set_tsid, ARRAY_SIZE(set_tsid));
+}
+
+static int tc90522t_set_layers(struct dvb_frontend *fe)
+{
+	struct reg_val rv;
+	u8 laysel;
+
+	laysel = ~fe->dtv_property_cache.isdbt_layer_enabled & 0x07;
+	laysel = (laysel & 0x01) << 2 | (laysel & 0x02) | (laysel & 0x04) >> 2;
+	rv.reg = 0x71;
+	rv.val = laysel;
+	return reg_write(fe->demodulator_priv, &rv, 1);
+}
+
+/* frontend ops */
+
+static int tc90522s_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct tc90522_state *state;
+	int ret;
+	u8 reg;
+
+	state = fe->demodulator_priv;
+	ret = reg_read(state, 0xc3, &reg, 1);
+	if (ret < 0)
+		return ret;
+
+	*status = 0;
+	if (reg & 0x80) /* input level under min ? */
+		return 0;
+	*status |= FE_HAS_SIGNAL;
+
+	if (reg & 0x60) /* carrier? */
+		return 0;
+	*status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
+
+	if (reg & 0x10)
+		return 0;
+	if (reg_read(state, 0xc5, &reg, 1) < 0 || !(reg & 0x03))
+		return 0;
+	*status |= FE_HAS_LOCK;
+	return 0;
+}
+
+static int tc90522t_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct tc90522_state *state;
+	int ret;
+	u8 reg;
+
+	state = fe->demodulator_priv;
+	ret = reg_read(state, 0x96, &reg, 1);
+	if (ret < 0)
+		return ret;
+
+	*status = 0;
+	if (reg & 0xe0) {
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI
+				| FE_HAS_SYNC | FE_HAS_LOCK;
+		return 0;
+	}
+
+	ret = reg_read(state, 0x80, &reg, 1);
+	if (ret < 0)
+		return ret;
+
+	if (reg & 0xf0)
+		return 0;
+	*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+	if (reg & 0x0c)
+		return 0;
+	*status |= FE_HAS_SYNC | FE_HAS_VITERBI;
+
+	if (reg & 0x02)
+		return 0;
+	*status |= FE_HAS_LOCK;
+	return 0;
+}
+
+static const fe_code_rate_t fec_conv_sat[] = {
+	FEC_NONE, /* unused */
+	FEC_1_2, /* for BPSK */
+	FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, /* for QPSK */
+	FEC_2_3, /* for 8PSK. (trellis code) */
+};
+
+static int tc90522s_get_frontend(struct dvb_frontend *fe)
+{
+	struct tc90522_state *state;
+	struct dtv_frontend_properties *c;
+	struct dtv_fe_stats *stats;
+	int ret, i;
+	int layers;
+	u8 val[10];
+	u32 cndat;
+
+	state = fe->demodulator_priv;
+	c = &fe->dtv_property_cache;
+	c->delivery_system = SYS_ISDBS;
+
+	layers = 0;
+	ret = reg_read(state, 0xe8, val, 3);
+	if (ret == 0) {
+		int slots;
+		u8 v;
+
+		/* high/single layer */
+		v = (val[0] & 0x70) >> 4;
+		c->modulation = (v == 7) ? PSK_8 : QPSK;
+		c->fec_inner = fec_conv_sat[v];
+		c->layer[0].fec = c->fec_inner;
+		c->layer[0].modulation = c->modulation;
+		c->layer[0].segment_count = val[1] & 0x3f; /* slots */
+
+		/* low layer */
+		v = (val[0] & 0x07);
+		c->layer[1].fec = fec_conv_sat[v];
+		if (v == 0)  /* no low layer */
+			c->layer[1].segment_count = 0;
+		else
+			c->layer[1].segment_count = val[2] & 0x3f; /* slots */
+		/* actually, BPSK if v==1, but not defined in fe_modulation_t */
+		c->layer[1].modulation = QPSK;
+		layers = (v > 0) ? 2 : 1;
+
+		slots =  c->layer[0].segment_count +  c->layer[1].segment_count;
+		c->symbol_rate = 28860000 * slots / 48;
+	}
+
+	/* statistics */
+
+	stats = &c->strength;
+	stats->len = 0;
+	/* let the connected tuner set RSSI property cache */
+	if (fe->ops.tuner_ops.get_rf_strength) {
+		u16 dummy;
+
+		fe->ops.tuner_ops.get_rf_strength(fe, &dummy);
+	}
+
+	stats = &c->cnr;
+	stats->len = 1;
+	stats->stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	cndat = 0;
+	ret = reg_read(state, 0xbc, val, 2);
+	if (ret == 0)
+		cndat = val[0] << 8 | val[1];
+	if (cndat >= 3000) {
+		u32 p, p4;
+		s64 cn;
+
+		cndat -= 3000;  /* cndat: 4.12 fixed point float */
+		/*
+		 * cnr[mdB] = -1634.6 * P^5 + 14341 * P^4 - 50259 * P^3
+		 *                 + 88977 * P^2 - 89565 * P + 58857
+		 *  (P = sqrt(cndat) / 64)
+		 */
+		/* p := sqrt(cndat) << 8 = P << 14, 2.14 fixed  point float */
+		/* cn = cnr << 3 */
+		p = int_sqrt(cndat << 16);
+		p4 = cndat * cndat;
+		cn = div64_s64(-16346LL * p4 * p, 10) >> 35;
+		cn += (14341LL * p4) >> 21;
+		cn -= (50259LL * cndat * p) >> 23;
+		cn += (88977LL * cndat) >> 9;
+		cn -= (89565LL * p) >> 11;
+		cn += 58857  << 3;
+		stats->stat[0].svalue = cn >> 3;
+		stats->stat[0].scale = FE_SCALE_DECIBEL;
+	}
+
+	/* per-layer post viterbi BER (or PER? config dependent?) */
+	stats = &c->post_bit_error;
+	memset(stats, 0, sizeof(*stats));
+	stats->len = layers;
+	ret = reg_read(state, 0xeb, val, 10);
+	if (ret < 0)
+		for (i = 0; i < layers; i++)
+			stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+	else {
+		for (i = 0; i < layers; i++) {
+			stats->stat[i].scale = FE_SCALE_COUNTER;
+			stats->stat[i].uvalue = val[i * 5] << 16
+				| val[i * 5 + 1] << 8 | val[i * 5 + 2];
+		}
+	}
+	stats = &c->post_bit_count;
+	memset(stats, 0, sizeof(*stats));
+	stats->len = layers;
+	if (ret < 0)
+		for (i = 0; i < layers; i++)
+			stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+	else {
+		for (i = 0; i < layers; i++) {
+			stats->stat[i].scale = FE_SCALE_COUNTER;
+			stats->stat[i].uvalue =
+				val[i * 5 + 3] << 8 | val[i * 5 + 4];
+			stats->stat[i].uvalue *= 204 * 8;
+		}
+	}
+
+	return 0;
+}
+
+
+static const fe_transmit_mode_t tm_conv[] = {
+	TRANSMISSION_MODE_2K,
+	TRANSMISSION_MODE_4K,
+	TRANSMISSION_MODE_8K,
+	0
+};
+
+static const fe_code_rate_t fec_conv_ter[] = {
+	FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, 0, 0, 0
+};
+
+static const fe_modulation_t mod_conv[] = {
+	DQPSK, QPSK, QAM_16, QAM_64, 0, 0, 0, 0
+};
+
+static int tc90522t_get_frontend(struct dvb_frontend *fe)
+{
+	struct tc90522_state *state;
+	struct dtv_frontend_properties *c;
+	struct dtv_fe_stats *stats;
+	int ret, i;
+	int layers;
+	u8 val[15], mode;
+	u32 cndat;
+
+	state = fe->demodulator_priv;
+	c = &fe->dtv_property_cache;
+	c->delivery_system = SYS_ISDBT;
+	c->bandwidth_hz = 6000000;
+	mode = 1;
+	ret = reg_read(state, 0xb0, val, 1);
+	if (ret == 0) {
+		mode = (val[0] & 0xc0) >> 2;
+		c->transmission_mode = tm_conv[mode];
+		c->guard_interval = (val[0] & 0x30) >> 4;
+	}
+
+	ret = reg_read(state, 0xb2, val, 6);
+	layers = 0;
+	if (ret == 0) {
+		u8 v;
+
+		c->isdbt_partial_reception = val[0] & 0x01;
+		c->isdbt_sb_mode = (val[0] & 0xc0) == 0x01;
+
+		/* layer A */
+		v = (val[2] & 0x78) >> 3;
+		if (v == 0x0f)
+			c->layer[0].segment_count = 0;
+		else {
+			layers++;
+			c->layer[0].segment_count = v;
+			c->layer[0].fec = fec_conv_ter[(val[1] & 0x1c) >> 2];
+			c->layer[0].modulation = mod_conv[(val[1] & 0xe0) >> 5];
+			v = (val[1] & 0x03) << 1 | (val[2] & 0x80) >> 7;
+			c->layer[0].interleaving = v;
+		}
+
+		/* layer B */
+		v = (val[3] & 0x03) << 1 | (val[4] & 0xc0) >> 6;
+		if (v == 0x0f)
+			c->layer[1].segment_count = 0;
+		else {
+			layers++;
+			c->layer[1].segment_count = v;
+			c->layer[1].fec = fec_conv_ter[(val[3] & 0xe0) >> 5];
+			c->layer[1].modulation = mod_conv[(val[2] & 0x07)];
+			c->layer[1].interleaving = (val[3] & 0x1c) >> 2;
+		}
+
+		/* layer C */
+		v = (val[5] & 0x1e) >> 1;
+		if (v == 0x0f)
+			c->layer[2].segment_count = 0;
+		else {
+			layers++;
+			c->layer[2].segment_count = v;
+			c->layer[2].fec = fec_conv_ter[(val[4] & 0x07)];
+			c->layer[2].modulation = mod_conv[(val[4] & 0x38) >> 3];
+			c->layer[2].interleaving = (val[5] & 0xe0) >> 5;
+		}
+	}
+
+	/* statistics */
+
+	stats = &c->strength;
+	stats->len = 0;
+	/* let the connected tuner set RSSI property cache */
+	if (fe->ops.tuner_ops.get_rf_strength) {
+		u16 dummy;
+
+		fe->ops.tuner_ops.get_rf_strength(fe, &dummy);
+	}
+
+	stats = &c->cnr;
+	stats->len = 1;
+	stats->stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	cndat = 0;
+	ret = reg_read(state, 0x8b, val, 3);
+	if (ret == 0)
+		cndat = val[0] << 16 | val[1] << 8 | val[2];
+	if (cndat != 0) {
+		u32 p, tmp;
+		s64 cn;
+
+		/*
+		 * cnr[mdB] = 0.024 P^4 - 1.6 P^3 + 39.8 P^2 + 549.1 P + 3096.5
+		 * (P = 10log10(5505024/cndat))
+		 */
+		/* cn = cnr << 3 (61.3 fixed point float */
+		/* p = 10log10(5505024/cndat) << 24  (8.24 fixed point float)*/
+		p = intlog10(5505024) - intlog10(cndat);
+		p *= 10;
+
+		cn = 24772;
+		cn += div64_s64(43827LL * p, 10) >> 24;
+		tmp = p >> 8;
+		cn += div64_s64(3184LL * tmp * tmp, 10) >> 32;
+		tmp = p >> 13;
+		cn -= div64_s64(128LL * tmp * tmp * tmp, 10) >> 33;
+		tmp = p >> 18;
+		cn += div64_s64(192LL * tmp * tmp * tmp * tmp, 1000) >> 24;
+
+		stats->stat[0].svalue = cn >> 3;
+		stats->stat[0].scale = FE_SCALE_DECIBEL;
+	}
+
+	/* per-layer post viterbi BER (or PER? config dependent?) */
+	stats = &c->post_bit_error;
+	memset(stats, 0, sizeof(*stats));
+	stats->len = layers;
+	ret = reg_read(state, 0x9d, val, 15);
+	if (ret < 0)
+		for (i = 0; i < layers; i++)
+			stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+	else {
+		for (i = 0; i < layers; i++) {
+			stats->stat[i].scale = FE_SCALE_COUNTER;
+			stats->stat[i].uvalue = val[i * 3] << 16
+				| val[i * 3 + 1] << 8 | val[i * 3 + 2];
+		}
+	}
+	stats = &c->post_bit_count;
+	memset(stats, 0, sizeof(*stats));
+	stats->len = layers;
+	if (ret < 0)
+		for (i = 0; i < layers; i++)
+			stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+	else {
+		for (i = 0; i < layers; i++) {
+			stats->stat[i].scale = FE_SCALE_COUNTER;
+			stats->stat[i].uvalue =
+				val[9 + i * 2] << 8 | val[9 + i * 2 + 1];
+			stats->stat[i].uvalue *= 204 * 8;
+		}
+	}
+
+	return 0;
+}
+
+static const struct reg_val reset_sat = { 0x03, 0x01 };
+static const struct reg_val reset_ter = { 0x01, 0x40 };
+
+static int tc90522_set_frontend(struct dvb_frontend *fe)
+{
+	struct tc90522_state *state;
+	int ret;
+
+	state = fe->demodulator_priv;
+
+	if (fe->ops.tuner_ops.set_params)
+		ret = fe->ops.tuner_ops.set_params(fe);
+	else
+		ret = -ENODEV;
+	if (ret < 0)
+		goto failed;
+
+	if (fe->ops.delsys[0] == SYS_ISDBS) {
+		ret = tc90522s_set_tsid(fe);
+		if (ret < 0)
+			goto failed;
+		ret = reg_write(state, &reset_sat, 1);
+	} else {
+		ret = tc90522t_set_layers(fe);
+		if (ret < 0)
+			goto failed;
+		ret = reg_write(state, &reset_ter, 1);
+	}
+	if (ret < 0)
+		goto failed;
+
+	return 0;
+
+failed:
+	dev_warn(&state->tuner_i2c.dev, "(%s) failed. [adap%d-fe%d]\n",
+			__func__, fe->dvb->num, fe->id);
+	return ret;
+}
+
+static int tc90522_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *settings)
+{
+	if (fe->ops.delsys[0] == SYS_ISDBS) {
+		settings->min_delay_ms = 250;
+		settings->step_size = 1000;
+		settings->max_drift = settings->step_size * 2;
+	} else {
+		settings->min_delay_ms = 400;
+		settings->step_size = 142857;
+		settings->max_drift = settings->step_size;
+	}
+	return 0;
+}
+
+static int tc90522_set_if_agc(struct dvb_frontend *fe, bool on)
+{
+	struct reg_val agc_sat[] = {
+		{ 0x0a, 0x00 },
+		{ 0x10, 0x30 },
+		{ 0x11, 0x00 },
+		{ 0x03, 0x01 },
+	};
+	struct reg_val agc_ter[] = {
+		{ 0x25, 0x00 },
+		{ 0x23, 0x4c },
+		{ 0x01, 0x40 },
+	};
+	struct tc90522_state *state;
+	struct reg_val *rv;
+	int num;
+
+	state = fe->demodulator_priv;
+	if (fe->ops.delsys[0] == SYS_ISDBS) {
+		agc_sat[0].val = on ? 0xff : 0x00;
+		agc_sat[1].val |= 0x80;
+		agc_sat[1].val |= on ? 0x01 : 0x00;
+		agc_sat[2].val |= on ? 0x40 : 0x00;
+		rv = agc_sat;
+		num = ARRAY_SIZE(agc_sat);
+	} else {
+		agc_ter[0].val = on ? 0x40 : 0x00;
+		agc_ter[1].val |= on ? 0x00 : 0x01;
+		rv = agc_ter;
+		num = ARRAY_SIZE(agc_ter);
+	}
+	return reg_write(state, rv, num);
+}
+
+static const struct reg_val sleep_sat = { 0x17, 0x01 };
+static const struct reg_val sleep_ter = { 0x03, 0x90 };
+
+static int tc90522_sleep(struct dvb_frontend *fe)
+{
+	struct tc90522_state *state;
+	int ret;
+
+	state = fe->demodulator_priv;
+	if (fe->ops.delsys[0] == SYS_ISDBS)
+		ret = reg_write(state, &sleep_sat, 1);
+	else {
+		ret = reg_write(state, &sleep_ter, 1);
+		if (ret == 0 && fe->ops.set_lna &&
+		    fe->dtv_property_cache.lna == LNA_AUTO) {
+			fe->dtv_property_cache.lna = 0;
+			ret = fe->ops.set_lna(fe);
+			fe->dtv_property_cache.lna = LNA_AUTO;
+		}
+	}
+	if (ret < 0)
+		dev_warn(&state->tuner_i2c.dev,
+			"(%s) failed. [adap%d-fe%d]\n",
+			__func__, fe->dvb->num, fe->id);
+	return ret;
+}
+
+static const struct reg_val wakeup_sat = { 0x17, 0x00 };
+static const struct reg_val wakeup_ter = { 0x03, 0x80 };
+
+static int tc90522_init(struct dvb_frontend *fe)
+{
+	struct tc90522_state *state;
+	int ret;
+
+	/*
+	 * Because the init sequence is not public,
+	 * the parent device/driver should have init'ed the device before.
+	 * just wake up the device here.
+	 */
+
+	state = fe->demodulator_priv;
+	if (fe->ops.delsys[0] == SYS_ISDBS)
+		ret = reg_write(state, &wakeup_sat, 1);
+	else {
+		ret = reg_write(state, &wakeup_ter, 1);
+		if (ret == 0 && fe->ops.set_lna &&
+		    fe->dtv_property_cache.lna == LNA_AUTO) {
+			fe->dtv_property_cache.lna = 1;
+			ret = fe->ops.set_lna(fe);
+			fe->dtv_property_cache.lna = LNA_AUTO;
+		}
+	}
+	if (ret < 0) {
+		dev_warn(&state->tuner_i2c.dev,
+			"(%s) failed. [adap%d-fe%d]\n",
+			__func__, fe->dvb->num, fe->id);
+		return ret;
+	}
+
+	/* prefer 'all-layers' to 'none' as a default */
+	if (fe->dtv_property_cache.isdbt_layer_enabled == 0)
+		fe->dtv_property_cache.isdbt_layer_enabled = 7;
+	return tc90522_set_if_agc(fe, true);
+}
+
+
+/*
+ * tuner I2C adapter functions
+ */
+
+static int
+tc90522_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct tc90522_state *state;
+	struct i2c_msg *new_msgs;
+	int i, j;
+	int ret, rd_num;
+	u8 wbuf[256];
+	u8 *p, *bufend;
+
+	if (num <= 0)
+		return -EINVAL;
+
+	rd_num = 0;
+	for (i = 0; i < num; i++)
+		if (msgs[i].flags & I2C_M_RD)
+			rd_num++;
+	new_msgs = kmalloc(sizeof(*new_msgs) * (num + rd_num), GFP_KERNEL);
+	if (!new_msgs)
+		return -ENOMEM;
+
+	state = i2c_get_adapdata(adap);
+	p = wbuf;
+	bufend = wbuf + sizeof(wbuf);
+	for (i = 0, j = 0; i < num; i++, j++) {
+		new_msgs[j].addr = state->i2c_client->addr;
+		new_msgs[j].flags = msgs[i].flags;
+
+		if (msgs[i].flags & I2C_M_RD) {
+			new_msgs[j].flags &= ~I2C_M_RD;
+			if (p + 2 > bufend)
+				break;
+			p[0] = TC90522_I2C_THRU_REG;
+			p[1] = msgs[i].addr << 1 | 0x01;
+			new_msgs[j].buf = p;
+			new_msgs[j].len = 2;
+			p += 2;
+			j++;
+			new_msgs[j].addr = state->i2c_client->addr;
+			new_msgs[j].flags = msgs[i].flags;
+			new_msgs[j].buf = msgs[i].buf;
+			new_msgs[j].len = msgs[i].len;
+			continue;
+		}
+
+		if (p + msgs[i].len + 2 > bufend)
+			break;
+		p[0] = TC90522_I2C_THRU_REG;
+		p[1] = msgs[i].addr << 1;
+		memcpy(p + 2, msgs[i].buf, msgs[i].len);
+		new_msgs[j].buf = p;
+		new_msgs[j].len = msgs[i].len + 2;
+		p += new_msgs[j].len;
+	}
+
+	if (i < num)
+		ret = -ENOMEM;
+	else
+		ret = i2c_transfer(state->i2c_client->adapter, new_msgs, j);
+	if (ret >= 0 && ret < j)
+		ret = -EIO;
+	kfree(new_msgs);
+	return (ret == j) ? num : ret;
+}
+
+static u32 tc90522_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C;
+}
+
+static const struct i2c_algorithm tc90522_tuner_i2c_algo = {
+	.master_xfer   = &tc90522_master_xfer,
+	.functionality = &tc90522_functionality,
+};
+
+
+/*
+ * I2C driver functions
+ */
+
+static const struct dvb_frontend_ops tc90522_ops_sat = {
+	.delsys = { SYS_ISDBS },
+	.info = {
+		.name = "Toshiba TC90522 ISDB-S module",
+		.frequency_min =  950000,
+		.frequency_max = 2150000,
+		.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.init = tc90522_init,
+	.sleep = tc90522_sleep,
+	.set_frontend = tc90522_set_frontend,
+	.get_tune_settings = tc90522_get_tune_settings,
+
+	.get_frontend = tc90522s_get_frontend,
+	.read_status = tc90522s_read_status,
+};
+
+static const struct dvb_frontend_ops tc90522_ops_ter = {
+	.delsys = { SYS_ISDBT },
+	.info = {
+		.name = "Toshiba TC90522 ISDB-T module",
+		.frequency_min = 470000000,
+		.frequency_max = 770000000,
+		.frequency_stepsize = 142857,
+		.caps = FE_CAN_INVERSION_AUTO |
+			FE_CAN_FEC_1_2  | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_5_6  | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+			FE_CAN_QPSK     | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
+			FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.init = tc90522_init,
+	.sleep = tc90522_sleep,
+	.set_frontend = tc90522_set_frontend,
+	.get_tune_settings = tc90522_get_tune_settings,
+
+	.get_frontend = tc90522t_get_frontend,
+	.read_status = tc90522t_read_status,
+};
+
+
+static int tc90522_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct tc90522_state *state;
+	struct tc90522_config *cfg;
+	const struct dvb_frontend_ops *ops;
+	struct i2c_adapter *adap;
+	int ret;
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+	state->i2c_client = client;
+
+	cfg = client->dev.platform_data;
+	memcpy(&state->cfg, cfg, sizeof(state->cfg));
+	cfg->fe = state->cfg.fe = &state->fe;
+	ops =  id->driver_data == 0 ? &tc90522_ops_sat : &tc90522_ops_ter;
+	memcpy(&state->fe.ops, ops, sizeof(*ops));
+	state->fe.demodulator_priv = state;
+
+	adap = &state->tuner_i2c;
+	adap->owner = THIS_MODULE;
+	adap->algo = &tc90522_tuner_i2c_algo;
+	adap->dev.parent = &client->dev;
+	strlcpy(adap->name, "tc90522_sub", sizeof(adap->name));
+	i2c_set_adapdata(adap, state);
+	ret = i2c_add_adapter(adap);
+	if (ret < 0)
+		goto err;
+	cfg->tuner_i2c = state->cfg.tuner_i2c = adap;
+
+	i2c_set_clientdata(client, &state->cfg);
+	dev_info(&client->dev, "Toshiba TC90522 attached.\n");
+	return 0;
+
+err:
+	kfree(state);
+	return ret;
+}
+
+static int tc90522_remove(struct i2c_client *client)
+{
+	struct tc90522_state *state;
+
+	state = cfg_to_state(i2c_get_clientdata(client));
+	i2c_del_adapter(&state->tuner_i2c);
+	kfree(state);
+	return 0;
+}
+
+
+static const struct i2c_device_id tc90522_id[] = {
+	{ TC90522_I2C_DEV_SAT, 0 },
+	{ TC90522_I2C_DEV_TER, 1 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, tc90522_id);
+
+static struct i2c_driver tc90522_driver = {
+	.driver = {
+		.name	= "tc90522",
+	},
+	.probe		= tc90522_probe,
+	.remove		= tc90522_remove,
+	.id_table	= tc90522_id,
+};
+
+module_i2c_driver(tc90522_driver);
+
+MODULE_DESCRIPTION("Toshiba TC90522 frontend");
+MODULE_AUTHOR("Akihiro TSUKADA");
+MODULE_LICENSE("GPL");

+ 42 - 0
drivers/media/dvb-frontends/tc90522.h

@@ -0,0 +1,42 @@
+/*
+ * Toshiba TC90522 Demodulator
+ *
+ * Copyright (C) 2014 Akihiro Tsukada <tskd08@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ *
+ * 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.
+ */
+
+/*
+ * The demod has 4 input (2xISDB-T and 2xISDB-S),
+ * and provides independent sub modules for each input.
+ * As the sub modules work in parallel and have the separate i2c addr's,
+ * this driver treats each sub module as one demod device.
+ */
+
+#ifndef TC90522_H
+#define TC90522_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/* I2C device types */
+#define TC90522_I2C_DEV_SAT "tc90522sat"
+#define TC90522_I2C_DEV_TER "tc90522ter"
+
+struct tc90522_config {
+	/* [OUT] frontend returned by driver */
+	struct dvb_frontend *fe;
+
+	/* [OUT] tuner I2C adapter returned by driver */
+	struct i2c_adapter *tuner_i2c;
+};
+
+#endif /* TC90522_H */

+ 1 - 1
drivers/media/dvb-frontends/tda10071.c

@@ -1037,7 +1037,7 @@ static int tda10071_init(struct dvb_frontend *fe)
 			ret = -EFAULT;
 			goto error;
 		} else {
-			priv->warm = 1;
+			priv->warm = true;
 		}
 
 		cmd.args[0] = CMD_GET_FW_VERSION;

+ 1 - 1
drivers/media/dvb-frontends/zl10039.c

@@ -111,7 +111,7 @@ static int zl10039_write(struct zl10039_state *state,
 
 	if (1 + count > sizeof(buf)) {
 		printk(KERN_WARNING
-		       "%s: i2c wr reg=%04x: len=%zd is too big!\n",
+		       "%s: i2c wr reg=%04x: len=%zu is too big!\n",
 		       KBUILD_MODNAME, reg, count);
 		return -EINVAL;
 	}

+ 10 - 0
drivers/media/firewire/firedtv-avc.c

@@ -1157,6 +1157,10 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
 		if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
 			dev_err(fdtv->device,
 				"invalid pmt_cmd_id %d\n", pmt_cmd_id);
+		if (program_info_length > sizeof(c->operand) - 4 - write_pos) {
+			ret = -EINVAL;
+			goto out;
+		}
 
 		memcpy(&c->operand[write_pos], &msg[read_pos],
 		       program_info_length);
@@ -1180,6 +1184,12 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
 				dev_err(fdtv->device, "invalid pmt_cmd_id %d "
 					"at stream level\n", pmt_cmd_id);
 
+			if (es_info_length > sizeof(c->operand) - 4 -
+					     write_pos) {
+				ret = -EINVAL;
+				goto out;
+			}
+
 			memcpy(&c->operand[write_pos], &msg[read_pos],
 			       es_info_length);
 			read_pos += es_info_length;

+ 1 - 1
drivers/media/i2c/adv7343_regs.h

@@ -13,7 +13,7 @@
  * GNU General Public License for more details.
  */
 
-#ifndef ADV7343_REG_H
+#ifndef ADV7343_REGS_H
 #define ADV7343_REGS_H
 
 struct adv7343_std_info {

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

@@ -1593,7 +1593,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
 			bt->height += hdmi_read16(sd, 0x0b, 0xfff);
 			bt->il_vfrontporch = hdmi_read16(sd, 0x2c, 0x1fff) / 2;
 			bt->il_vsync = hdmi_read16(sd, 0x30, 0x1fff) / 2;
-			bt->vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2;
+			bt->il_vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2;
 		}
 		adv7604_fill_optional_dv_timings_fields(sd, timings);
 	} else {

+ 3 - 1
drivers/media/i2c/adv7842.c

@@ -1435,6 +1435,8 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
 
 	v4l2_dbg(1, debug, sd, "%s:\n", __func__);
 
+	memset(timings, 0, sizeof(struct v4l2_dv_timings));
+
 	/* SDP block */
 	if (state->mode == ADV7842_MODE_SDP)
 		return -ENODATA;
@@ -1483,7 +1485,7 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
 					hdmi_read(sd, 0x2d)) / 2;
 			bt->il_vsync = ((hdmi_read(sd, 0x30) & 0x1f) * 256 +
 					hdmi_read(sd, 0x31)) / 2;
-			bt->vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
+			bt->il_vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
 					hdmi_read(sd, 0x35)) / 2;
 		}
 		adv7842_fill_optional_dv_timings_fields(sd, timings);

+ 1 - 1
drivers/media/i2c/cx25840/cx25840-ir.c

@@ -224,7 +224,7 @@ static inline unsigned int lpf_count_to_us(unsigned int count)
 }
 
 /*
- * FIFO register pulse width count compuations
+ * FIFO register pulse width count computations
  */
 static u32 clock_divider_to_resolution(u16 divider)
 {

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

@@ -100,14 +100,14 @@ static int lm3560_enable_ctrl(struct lm3560_flash *flash,
 	int rval;
 
 	if (led_no == LM3560_LED0) {
-		if (on == true)
+		if (on)
 			rval = regmap_update_bits(flash->regmap,
 						  REG_ENABLE, 0x08, 0x08);
 		else
 			rval = regmap_update_bits(flash->regmap,
 						  REG_ENABLE, 0x08, 0x00);
 	} else {
-		if (on == true)
+		if (on)
 			rval = regmap_update_bits(flash->regmap,
 						  REG_ENABLE, 0x10, 0x10);
 		else

+ 1 - 13
drivers/media/i2c/ov7670.c

@@ -19,6 +19,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-mediabus.h>
+#include <media/v4l2-image-sizes.h>
 #include <media/ov7670.h>
 
 MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
@@ -29,19 +30,6 @@ static bool debug;
 module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-/*
- * Basic window sizes.  These probably belong somewhere more globally
- * useful.
- */
-#define VGA_WIDTH	640
-#define VGA_HEIGHT	480
-#define QVGA_WIDTH	320
-#define QVGA_HEIGHT	240
-#define CIF_WIDTH	352
-#define CIF_HEIGHT	288
-#define QCIF_WIDTH	176
-#define	QCIF_HEIGHT	144
-
 /*
  * The 7670 sits on i2c with ID 0x42
  */

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

@@ -816,7 +816,7 @@ static void s5k5baf_hw_find_min_fiv(struct s5k5baf *state)
 				 "error setting frame interval: %d\n", err);
 			state->error = -EINVAL;
 		}
-	};
+	}
 	v4l2_err(&state->sd, "cannot find correct frame interval\n");
 	state->error = -ERANGE;
 }

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

@@ -660,7 +660,7 @@ static const struct v4l2_subdev_ops saa6752hs_ops = {
 static int saa6752hs_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
-	struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
+	struct saa6752hs_state *h;
 	struct v4l2_subdev *sd;
 	struct v4l2_ctrl_handler *hdl;
 	u8 addr = 0x13;
@@ -668,6 +668,8 @@ static int saa6752hs_probe(struct i2c_client *client,
 
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
+
+	h = devm_kzalloc(&client->dev, sizeof(*h), GFP_KERNEL);
 	if (h == NULL)
 		return -ENOMEM;
 	sd = &h->sd;
@@ -752,7 +754,6 @@ static int saa6752hs_probe(struct i2c_client *client,
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(h);
 		return err;
 	}
 	v4l2_ctrl_cluster(3, &h->video_bitrate_mode);
@@ -767,7 +768,6 @@ static int saa6752hs_remove(struct i2c_client *client)
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&to_state(sd)->hdl);
-	kfree(to_state(sd));
 	return 0;
 }
 

+ 100 - 43
drivers/media/i2c/smiapp/smiapp-core.c

@@ -31,8 +31,9 @@
 #include <linux/device.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/smiapp.h>
 #include <linux/v4l2-mediabus.h>
 #include <media/v4l2-device.h>
 
@@ -297,8 +298,9 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor)
 	if (rval < 0)
 		return rval;
 
-	*sensor->pixel_rate_parray->p_cur.p_s64 = pll->vt_pix_clk_freq_hz;
-	*sensor->pixel_rate_csi->p_cur.p_s64 = pll->pixel_rate_csi;
+	__v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_parray,
+				 pll->vt_pix_clk_freq_hz);
+	__v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_csi, pll->pixel_rate_csi);
 
 	return 0;
 }
@@ -319,13 +321,7 @@ static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor)
 		+ sensor->vblank->val
 		- sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];
 
-	ctrl->maximum = max;
-	if (ctrl->default_value > max)
-		ctrl->default_value = max;
-	if (ctrl->val > max)
-		ctrl->val = max;
-	if (ctrl->cur.val > max)
-		ctrl->cur.val = max;
+	__v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max);
 }
 
 /*
@@ -404,6 +400,14 @@ static void smiapp_update_mbus_formats(struct smiapp_sensor *sensor)
 		pixel_order_str[pixel_order]);
 }
 
+static const char * const smiapp_test_patterns[] = {
+	"Disabled",
+	"Solid Colour",
+	"Eight Vertical Colour Bars",
+	"Colour Bars With Fade to Grey",
+	"Pseudorandom Sequence (PN9)",
+};
+
 static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct smiapp_sensor *sensor =
@@ -477,6 +481,39 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
 
 		return smiapp_pll_update(sensor);
 
+	case V4L2_CID_TEST_PATTERN: {
+		unsigned int i;
+
+		for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
+			v4l2_ctrl_activate(
+				sensor->test_data[i],
+				ctrl->val ==
+				V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR);
+
+		return smiapp_write(
+			sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
+	}
+
+	case V4L2_CID_TEST_PATTERN_RED:
+		return smiapp_write(
+			sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
+
+	case V4L2_CID_TEST_PATTERN_GREENR:
+		return smiapp_write(
+			sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
+
+	case V4L2_CID_TEST_PATTERN_BLUE:
+		return smiapp_write(
+			sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
+
+	case V4L2_CID_TEST_PATTERN_GREENB:
+		return smiapp_write(
+			sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
+
+	case V4L2_CID_PIXEL_RATE:
+		/* For v4l2_ctrl_s_ctrl_int64() used internally. */
+		return 0;
+
 	default:
 		return -EINVAL;
 	}
@@ -489,10 +526,10 @@ static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
 static int smiapp_init_controls(struct smiapp_sensor *sensor)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
-	unsigned int max;
+	unsigned int max, i;
 	int rval;
 
-	rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 7);
+	rval = v4l2_ctrl_handler_init(&sensor->pixel_array->ctrl_handler, 12);
 	if (rval)
 		return rval;
 	sensor->pixel_array->ctrl_handler.lock = &sensor->mutex;
@@ -535,6 +572,20 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor)
 		&sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
 		V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
 
+	v4l2_ctrl_new_std_menu_items(&sensor->pixel_array->ctrl_handler,
+				     &smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN,
+				     ARRAY_SIZE(smiapp_test_patterns) - 1,
+				     0, 0, smiapp_test_patterns);
+
+	for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++) {
+		int max_value = (1 << sensor->csi_format->width) - 1;
+		sensor->test_data[i] =
+			v4l2_ctrl_new_std(
+				&sensor->pixel_array->ctrl_handler,
+				&smiapp_ctrl_ops, V4L2_CID_TEST_PATTERN_RED + i,
+				0, max_value, 1, max_value);
+	}
+
 	if (sensor->pixel_array->ctrl_handler.error) {
 		dev_err(&client->dev,
 			"pixel array controls initialization failed (%d)\n",
@@ -782,36 +833,25 @@ static void smiapp_update_blanking(struct smiapp_sensor *sensor)
 {
 	struct v4l2_ctrl *vblank = sensor->vblank;
 	struct v4l2_ctrl *hblank = sensor->hblank;
+	int min, max;
 
-	vblank->minimum =
-		max_t(int,
-		      sensor->limits[SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES],
-		      sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN] -
-		      sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);
-	vblank->maximum =
-		sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN] -
+	min = max_t(int,
+		    sensor->limits[SMIAPP_LIMIT_MIN_FRAME_BLANKING_LINES],
+		    sensor->limits[SMIAPP_LIMIT_MIN_FRAME_LENGTH_LINES_BIN] -
+		    sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height);
+	max = sensor->limits[SMIAPP_LIMIT_MAX_FRAME_LENGTH_LINES_BIN] -
 		sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height;
 
-	vblank->val = clamp_t(int, vblank->val,
-			      vblank->minimum, vblank->maximum);
-	vblank->default_value = vblank->minimum;
-	vblank->val = vblank->val;
-	vblank->cur.val = vblank->val;
-
-	hblank->minimum =
-		max_t(int,
-		      sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN] -
-		      sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width,
-		      sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN]);
-	hblank->maximum =
-		sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN] -
+	__v4l2_ctrl_modify_range(vblank, min, max, vblank->step, min);
+
+	min = max_t(int,
+		    sensor->limits[SMIAPP_LIMIT_MIN_LINE_LENGTH_PCK_BIN] -
+		    sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width,
+		    sensor->limits[SMIAPP_LIMIT_MIN_LINE_BLANKING_PCK_BIN]);
+	max = sensor->limits[SMIAPP_LIMIT_MAX_LINE_LENGTH_PCK_BIN] -
 		sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width;
 
-	hblank->val = clamp_t(int, hblank->val,
-			      hblank->minimum, hblank->maximum);
-	hblank->default_value = hblank->minimum;
-	hblank->val = hblank->val;
-	hblank->cur.val = hblank->val;
+	__v4l2_ctrl_modify_range(hblank, min, max, hblank->step, min);
 
 	__smiapp_update_exposure_limits(sensor);
 }
@@ -1272,7 +1312,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor)
 		clk_disable_unprepare(sensor->ext_clk);
 	usleep_range(5000, 5000);
 	regulator_disable(sensor->vana);
-	sensor->streaming = 0;
+	sensor->streaming = false;
 }
 
 static int smiapp_set_power(struct v4l2_subdev *subdev, int on)
@@ -1462,13 +1502,13 @@ static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
 		return 0;
 
 	if (enable) {
-		sensor->streaming = 1;
+		sensor->streaming = true;
 		rval = smiapp_start_streaming(sensor);
 		if (rval < 0)
-			sensor->streaming = 0;
+			sensor->streaming = false;
 	} else {
 		rval = smiapp_stop_streaming(sensor);
-		sensor->streaming = 0;
+		sensor->streaming = false;
 	}
 
 	return rval;
@@ -1664,17 +1704,34 @@ static int smiapp_set_format(struct v4l2_subdev *subdev,
 	if (fmt->pad == ssd->source_pad) {
 		u32 code = fmt->format.code;
 		int rval = __smiapp_get_format(subdev, fh, fmt);
+		bool range_changed = false;
+		unsigned int i;
 
 		if (!rval && subdev == &sensor->src->sd) {
 			const struct smiapp_csi_data_format *csi_format =
 				smiapp_validate_csi_data_format(sensor, code);
-			if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+
+			if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+				if (csi_format->width !=
+				    sensor->csi_format->width)
+					range_changed = true;
+
 				sensor->csi_format = csi_format;
+			}
+
 			fmt->format.code = csi_format->code;
 		}
 
 		mutex_unlock(&sensor->mutex);
-		return rval;
+		if (rval || !range_changed)
+			return rval;
+
+		for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
+			v4l2_ctrl_modify_range(
+				sensor->test_data[i],
+				0, (1 << sensor->csi_format->width) - 1, 1, 0);
+
+		return 0;
 	}
 
 	/* Sink pad. Width and height are changeable here. */

+ 4 - 0
drivers/media/i2c/smiapp/smiapp.h

@@ -54,6 +54,8 @@
 	(1000 +	(SMIAPP_RESET_DELAY_CLOCKS * 1000	\
 		 + (clk) / 1000 - 1) / ((clk) / 1000))
 
+#define SMIAPP_COLOUR_COMPONENTS	4
+
 #include "smiapp-limits.h"
 
 struct smiapp_quirk;
@@ -241,6 +243,8 @@ struct smiapp_sensor {
 	/* src controls */
 	struct v4l2_ctrl *link_freq;
 	struct v4l2_ctrl *pixel_rate_csi;
+	/* test pattern colour components */
+	struct v4l2_ctrl *test_data[SMIAPP_COLOUR_COMPONENTS];
 };
 
 #define to_smiapp_subdev(_sd)				\

+ 1 - 3
drivers/media/i2c/soc_camera/mt9t112.c

@@ -29,6 +29,7 @@
 #include <media/soc_camera.h>
 #include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-image-sizes.h>
 
 /* you can check PLL/clock info */
 /* #define EXT_CLOCK 24000000 */
@@ -42,9 +43,6 @@
 #define MAX_WIDTH   2048
 #define MAX_HEIGHT  1536
 
-#define VGA_WIDTH   640
-#define VGA_HEIGHT  480
-
 /*
  * macro of read/write
  */

+ 1 - 4
drivers/media/i2c/soc_camera/ov772x.c

@@ -29,6 +29,7 @@
 #include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-subdev.h>
+#include <media/v4l2-image-sizes.h>
 
 /*
  * register offset
@@ -360,10 +361,6 @@
 #define SCAL0_ACTRL     0x08 /* Auto scaling factor control */
 #define SCAL1_2_ACTRL   0x04 /* Auto scaling factor control */
 
-#define VGA_WIDTH		640
-#define VGA_HEIGHT		480
-#define QVGA_WIDTH		320
-#define QVGA_HEIGHT		240
 #define OV772X_MAX_WIDTH	VGA_WIDTH
 #define OV772X_MAX_HEIGHT	VGA_HEIGHT
 

+ 2 - 2
drivers/media/i2c/soc_camera/ov9740.c

@@ -564,13 +564,13 @@ static int ov9740_set_res(struct i2c_client *client, u32 width, u32 height)
 	u32 y_start;
 	u32 x_end;
 	u32 y_end;
-	bool scaling = 0;
+	bool scaling = false;
 	u32 scale_input_x;
 	u32 scale_input_y;
 	int ret;
 
 	if ((width != OV9740_MAX_WIDTH) || (height != OV9740_MAX_HEIGHT))
-		scaling = 1;
+		scaling = true;
 
 	/*
 	 * Try to use as much of the sensor area as possible when supporting

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

@@ -293,7 +293,7 @@ static int tda7432_s_ctrl(struct v4l2_ctrl *ctrl)
 		if (t->mute->val) {
 			lf |= TDA7432_MUTE;
 			lr |= TDA7432_MUTE;
-			lf |= TDA7432_MUTE;
+			rf |= TDA7432_MUTE;
 			rr |= TDA7432_MUTE;
 		}
 		/* Mute & update balance*/

+ 8 - 13
drivers/media/i2c/tvp7002.c

@@ -775,25 +775,20 @@ static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
 static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct tvp7002 *device = to_tvp7002(sd);
-	int error = 0;
+	int error;
 
 	if (device->streaming == enable)
 		return 0;
 
-	if (enable) {
-		/* Set output state on (low impedance means stream on) */
-		error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x00);
-		device->streaming = enable;
-	} else {
-		/* Set output state off (high impedance means stream off) */
-		error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x03);
-		if (error)
-			v4l2_dbg(1, debug, sd, "Unable to stop streaming\n");
-
-		device->streaming = enable;
+	/* low impedance: on, high impedance: off */
+	error = tvp7002_write(sd, TVP7002_MISC_CTL_2, enable ? 0x00 : 0x03);
+	if (error) {
+		v4l2_dbg(1, debug, sd, "Fail to set streaming\n");
+		return error;
 	}
 
-	return error;
+	device->streaming = enable;
+	return 0;
 }
 
 /*

+ 1 - 13
drivers/media/i2c/vs6624.c

@@ -30,22 +30,10 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-mediabus.h>
+#include <media/v4l2-image-sizes.h>
 
 #include "vs6624_regs.h"
 
-#define VGA_WIDTH       640
-#define VGA_HEIGHT      480
-#define QVGA_WIDTH      320
-#define QVGA_HEIGHT     240
-#define QQVGA_WIDTH     160
-#define QQVGA_HEIGHT    120
-#define CIF_WIDTH       352
-#define CIF_HEIGHT      288
-#define QCIF_WIDTH      176
-#define QCIF_HEIGHT     144
-#define QQCIF_WIDTH     88
-#define QQCIF_HEIGHT    72
-
 #define MAX_FRAME_RATE  30
 
 struct vs6624 {

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

@@ -103,10 +103,8 @@ static long media_device_enum_entities(struct media_device *mdev,
 		return -EINVAL;
 
 	u_ent.id = ent->id;
-	if (ent->name) {
-		strncpy(u_ent.name, ent->name, sizeof(u_ent.name));
-		u_ent.name[sizeof(u_ent.name) - 1] = '\0';
-	}
+	if (ent->name)
+		strlcpy(u_ent.name, ent->name, sizeof(u_ent.name));
 	u_ent.type = ent->type;
 	u_ent.revision = ent->revision;
 	u_ent.flags = ent->flags;

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

@@ -192,7 +192,6 @@ static int media_open(struct inode *inode, struct file *filp)
 static int media_release(struct inode *inode, struct file *filp)
 {
 	struct media_devnode *mdev = media_devnode_data(filp);
-	int ret = 0;
 
 	if (mdev->fops->release)
 		mdev->fops->release(filp);
@@ -201,7 +200,7 @@ static int media_release(struct inode *inode, struct file *filp)
 	   return value is ignored. */
 	put_device(&mdev->dev);
 	filp->private_data = NULL;
-	return ret;
+	return 0;
 }
 
 static const struct file_operations media_devnode_fops = {

+ 6 - 1
drivers/media/parport/pms.c

@@ -629,11 +629,15 @@ static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
 {
 	int y;
 	int dw = 2 * dev->width;
-	char tmp[dw + 32]; /* using a temp buffer is faster than direct  */
+	char *tmp; /* using a temp buffer is faster than direct  */
 	int cnt = 0;
 	int len = 0;
 	unsigned char r8 = 0x5;  /* value for reg8  */
 
+	tmp = kmalloc(dw + 32, GFP_KERNEL);
+	if (!tmp)
+		return 0;
+
 	if (rgb555)
 		r8 |= 0x20; /* else use untranslated rgb = 565 */
 	mvv_write(dev, 0x08, r8); /* capture rgb555/565, init DRAM, PC enable */
@@ -664,6 +668,7 @@ static int pms_capture(struct pms *dev, char __user *buf, int rgb555, int count)
 			len += dt;
 		}
 	}
+	kfree(tmp);
 	return len;
 }
 

+ 2 - 0
drivers/media/pci/Kconfig

@@ -20,6 +20,7 @@ source "drivers/media/pci/ivtv/Kconfig"
 source "drivers/media/pci/zoran/Kconfig"
 source "drivers/media/pci/saa7146/Kconfig"
 source "drivers/media/pci/solo6x10/Kconfig"
+source "drivers/media/pci/tw68/Kconfig"
 endif
 
 if MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
@@ -41,6 +42,7 @@ source "drivers/media/pci/b2c2/Kconfig"
 source "drivers/media/pci/pluto2/Kconfig"
 source "drivers/media/pci/dm1105/Kconfig"
 source "drivers/media/pci/pt1/Kconfig"
+source "drivers/media/pci/pt3/Kconfig"
 source "drivers/media/pci/mantis/Kconfig"
 source "drivers/media/pci/ngene/Kconfig"
 source "drivers/media/pci/ddbridge/Kconfig"

+ 2 - 1
drivers/media/pci/Makefile

@@ -7,10 +7,10 @@ obj-y        +=	ttpci/		\
 		pluto2/		\
 		dm1105/		\
 		pt1/		\
+		pt3/		\
 		mantis/		\
 		ngene/		\
 		ddbridge/	\
-		b2c2/		\
 		saa7146/
 
 obj-$(CONFIG_VIDEO_IVTV) += ivtv/
@@ -22,6 +22,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_BT848) += bt8xx/
 obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
 obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
+obj-$(CONFIG_VIDEO_TW68) += tw68/
 obj-$(CONFIG_VIDEO_MEYE) += meye/
 obj-$(CONFIG_STA2X11_VIP) += sta2x11/
 obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/

+ 2 - 3
drivers/media/pci/bt8xx/bttv-driver.c

@@ -1531,7 +1531,6 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
 {
 	struct bttv_buffer *old;
 	unsigned long flags;
-	int retval = 0;
 
 	dprintk("switch_overlay: enter [new=%p]\n", new);
 	if (new)
@@ -1551,7 +1550,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
 	if (NULL == new)
 		free_btres_lock(btv,fh,RESOURCE_OVERLAY);
 	dprintk("switch_overlay: done\n");
-	return retval;
+	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
@@ -3856,7 +3855,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id)
 
 				btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
 						BT848_INT_MASK);
-			};
+			}
 
 			bttv_print_irqbits(stat,astat);
 

+ 1 - 3
drivers/media/pci/bt8xx/dst_ca.c

@@ -674,11 +674,9 @@ static int dst_ca_release(struct inode *inode, struct file *file)
 
 static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
 {
-	ssize_t bytes_read = 0;
-
 	dprintk(verbose, DST_CA_DEBUG, 1, " Device read.");
 
-	return bytes_read;
+	return 0;
 }
 
 static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)

+ 1 - 1
drivers/media/pci/cx18/cx18-alsa-pcm.c

@@ -80,7 +80,7 @@ void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data,
 	int period_elapsed = 0;
 	int length;
 
-	dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zd\n", cxsc,
+	dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%zu\n", cxsc,
 		pcm_data, num_bytes);
 
 	substream = cxsc->capture_pcm_substream;

+ 3 - 3
drivers/media/pci/cx18/cx18-firmware.c

@@ -130,7 +130,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
 		}
 	}
 	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
-		CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
+		CX18_INFO("loaded %s firmware (%zu bytes)\n", fn, fw->size);
 	size = fw->size;
 	release_firmware(fw);
 	cx18_setup_page(cx, SCB_OFFSET);
@@ -164,7 +164,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
 
 	apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
 	while (offset + sizeof(seghdr) < fw->size) {
-		const u32 *shptr = src + offset / 4;
+		const __le32 *shptr = (__force __le32 *)src + offset / 4;
 
 		seghdr.sync1 = le32_to_cpu(shptr[0]);
 		seghdr.sync2 = le32_to_cpu(shptr[1]);
@@ -202,7 +202,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
 		offset += seghdr.size;
 	}
 	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
-		CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
+		CX18_INFO("loaded %s firmware V%08x (%zu bytes)\n",
 				fn, apu_version, fw->size);
 	size = fw->size;
 	release_firmware(fw);

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

@@ -364,7 +364,7 @@ int cx18_stream_alloc(struct cx18_stream *s)
 					((char __iomem *)cx->scb->cpu_mdl));
 
 		CX18_ERR("Too many buffers, cannot fit in SCB area\n");
-		CX18_ERR("Max buffers = %zd\n",
+		CX18_ERR("Max buffers = %zu\n",
 			bufsz / sizeof(struct cx18_mdl_ent));
 		return -ENOMEM;
 	}

+ 6 - 3
drivers/media/pci/cx23885/Kconfig

@@ -3,12 +3,11 @@ config VIDEO_CX23885
 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
 	select SND_PCM
 	select I2C_ALGOBIT
-	select VIDEO_BTCX
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	depends on RC_CORE
-	select VIDEOBUF_DVB
-	select VIDEOBUF_DMA_SG
+	select VIDEOBUF2_DVB
+	select VIDEOBUF2_DMA_SG
 	select VIDEO_CX25840
 	select VIDEO_CX2341X
 	select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
@@ -32,12 +31,16 @@ config VIDEO_CX23885
 	select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
+	select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
+	select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
 	---help---
 	  This is a video4linux driver for Conexant 23885 based

+ 0 - 1
drivers/media/pci/cx23885/Makefile

@@ -8,7 +8,6 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
 obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
 
 ccflags-y += -Idrivers/media/i2c
-ccflags-y += -Idrivers/media/common
 ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends

+ 2 - 6
drivers/media/pci/cx23885/altera-ci.c

@@ -16,10 +16,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -52,8 +48,8 @@
  * |  DATA7|  DATA6|  DATA5|  DATA4|  DATA3|  DATA2|  DATA1|  DATA0|
  * +-------+-------+-------+-------+-------+-------+-------+-------+
  */
-#include <media/videobuf-dma-sg.h>
-#include <media/videobuf-dvb.h>
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
 #include "altera-ci.h"
 #include "dvb_ca_en50221.h"
 

+ 0 - 4
drivers/media/pci/cx23885/altera-ci.h

@@ -16,10 +16,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #ifndef __ALTERA_CI_H
 #define __ALTERA_CI_H

+ 0 - 4
drivers/media/pci/cx23885/cimax2.c

@@ -17,10 +17,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "cx23885.h"

+ 0 - 4
drivers/media/pci/cx23885/cimax2.h

@@ -17,10 +17,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #ifndef CIMAX2_H

+ 149 - 354
drivers/media/pci/cx23885/cx23885-417.c

@@ -18,10 +18,6 @@
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -865,6 +861,11 @@ static int cx23885_api_cmd(struct cx23885_dev *dev,
 	return err;
 }
 
+static int cx23885_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
+{
+	return cx23885_mbox_func(priv, cmd, in, out, data);
+}
+
 static int cx23885_find_mailbox(struct cx23885_dev *dev)
 {
 	u32 signature[4] = {
@@ -941,7 +942,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
 
 	if (firmware->size != CX23885_FIRM_IMAGE_SIZE) {
 		printk(KERN_ERR "ERROR: Firmware size mismatch "
-			"(have %zd, expected %d)\n",
+			"(have %zu, expected %d)\n",
 			firmware->size, CX23885_FIRM_IMAGE_SIZE);
 		release_firmware(firmware);
 		return -1;
@@ -1033,12 +1034,12 @@ static void cx23885_codec_settings(struct cx23885_dev *dev)
 	cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
 				dev->ts1.height, dev->ts1.width);
 
-	dev->mpeg_params.width = dev->ts1.width;
-	dev->mpeg_params.height = dev->ts1.height;
-	dev->mpeg_params.is_50hz =
+	dev->cxhdl.width = dev->ts1.width;
+	dev->cxhdl.height = dev->ts1.height;
+	dev->cxhdl.is_50hz =
 		(dev->encodernorm.id & V4L2_STD_625_50) != 0;
 
-	cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params);
+	cx2341x_handler_setup(&dev->cxhdl);
 
 	cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
 	cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
@@ -1137,85 +1138,107 @@ static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder)
 
 /* ------------------------------------------------------------------ */
 
-static int bb_buf_setup(struct videobuf_queue *q,
-	unsigned int *count, unsigned int *size)
+static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+			   unsigned int *num_buffers, unsigned int *num_planes,
+			   unsigned int sizes[], void *alloc_ctxs[])
 {
-	struct cx23885_fh *fh = q->priv_data;
-
-	fh->dev->ts1.ts_packet_size  = mpeglinesize;
-	fh->dev->ts1.ts_packet_count = mpeglines;
-
-	*size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count;
-	*count = mpegbufs;
+	struct cx23885_dev *dev = q->drv_priv;
 
+	dev->ts1.ts_packet_size  = mpeglinesize;
+	dev->ts1.ts_packet_count = mpeglines;
+	*num_planes = 1;
+	sizes[0] = mpeglinesize * mpeglines;
+	*num_buffers = mpegbufs;
 	return 0;
 }
 
-static int bb_buf_prepare(struct videobuf_queue *q,
-	struct videobuf_buffer *vb, enum v4l2_field field)
+static int buffer_prepare(struct vb2_buffer *vb)
 {
-	struct cx23885_fh *fh = q->priv_data;
-	return cx23885_buf_prepare(q, &fh->dev->ts1,
-		(struct cx23885_buffer *)vb,
-		field);
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer *buf =
+		container_of(vb, struct cx23885_buffer, vb);
+
+	return cx23885_buf_prepare(buf, &dev->ts1);
 }
 
-static void bb_buf_queue(struct videobuf_queue *q,
-	struct videobuf_buffer *vb)
+static void buffer_finish(struct vb2_buffer *vb)
 {
-	struct cx23885_fh *fh = q->priv_data;
-	cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb);
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer *buf = container_of(vb,
+		struct cx23885_buffer, vb);
+	struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
+
+	cx23885_free_buffer(dev, buf);
+
+	dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
 }
 
-static void bb_buf_release(struct videobuf_queue *q,
-	struct videobuf_buffer *vb)
+static void buffer_queue(struct vb2_buffer *vb)
 {
-	cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
-}
+	struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
+	struct cx23885_buffer   *buf = container_of(vb,
+		struct cx23885_buffer, vb);
 
-static struct videobuf_queue_ops cx23885_qops = {
-	.buf_setup    = bb_buf_setup,
-	.buf_prepare  = bb_buf_prepare,
-	.buf_queue    = bb_buf_queue,
-	.buf_release  = bb_buf_release,
-};
+	cx23885_buf_queue(&dev->ts1, buf);
+}
 
-/* ------------------------------------------------------------------ */
+static int cx23885_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct cx23885_dev *dev = q->drv_priv;
+	struct cx23885_dmaqueue *dmaq = &dev->ts1.mpegq;
+	unsigned long flags;
+	int ret;
+
+	ret = cx23885_initialize_codec(dev, 1);
+	if (ret == 0) {
+		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
+
+		cx23885_start_dma(&dev->ts1, dmaq, buf);
+		return 0;
+	}
+	spin_lock_irqsave(&dev->slock, flags);
+	while (!list_empty(&dmaq->active)) {
+		struct cx23885_buffer *buf = list_entry(dmaq->active.next,
+			struct cx23885_buffer, queue);
 
-static const u32 *ctrl_classes[] = {
-	cx2341x_mpeg_ctrls,
-	NULL
-};
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+	}
+	spin_unlock_irqrestore(&dev->slock, flags);
+	return ret;
+}
 
-static int cx23885_queryctrl(struct cx23885_dev *dev,
-	struct v4l2_queryctrl *qctrl)
+static void cx23885_stop_streaming(struct vb2_queue *q)
 {
-	qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
-	if (qctrl->id == 0)
-		return -EINVAL;
+	struct cx23885_dev *dev = q->drv_priv;
 
-	/* MPEG V4L2 controls */
-	if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl))
-		qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+	/* stop mpeg capture */
+	cx23885_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
+			CX23885_END_NOW, CX23885_MPEG_CAPTURE,
+			CX23885_RAW_BITS_NONE);
 
-	return 0;
+	msleep(500);
+	cx23885_417_check_encoder(dev);
+	cx23885_cancel_buffers(&dev->ts1);
 }
 
-static int cx23885_querymenu(struct cx23885_dev *dev,
-	struct v4l2_querymenu *qmenu)
-{
-	struct v4l2_queryctrl qctrl;
+static struct vb2_ops cx23885_qops = {
+	.queue_setup    = queue_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_finish = buffer_finish,
+	.buf_queue    = buffer_queue,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = cx23885_start_streaming,
+	.stop_streaming = cx23885_stop_streaming,
+};
 
-	qctrl.id = qmenu->id;
-	cx23885_queryctrl(dev, &qctrl);
-	return v4l2_ctrl_query_menu(qmenu, &qctrl,
-		cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));
-}
+/* ------------------------------------------------------------------ */
 
 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	*id = dev->tvnorm;
 	return 0;
@@ -1223,29 +1246,26 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	unsigned int i;
+	int ret;
 
 	for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
 		if (id & cx23885_tvnorms[i].id)
 			break;
 	if (i == ARRAY_SIZE(cx23885_tvnorms))
 		return -EINVAL;
-	dev->encodernorm = cx23885_tvnorms[i];
 
-	/* Have the drier core notify the subdevices */
-	mutex_lock(&dev->lock);
-	cx23885_set_tvnorm(dev, id);
-	mutex_unlock(&dev->lock);
-
-	return 0;
+	ret = cx23885_set_tvnorm(dev, id);
+	if (!ret)
+		dev->encodernorm = cx23885_tvnorms[i];
+	return ret;
 }
 
 static int vidioc_enum_input(struct file *file, void *priv,
 	struct v4l2_input *i)
 {
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	dprintk(1, "%s()\n", __func__);
 	return cx23885_enum_input(dev, i);
 }
@@ -1263,8 +1283,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *t)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1281,8 +1300,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 static int vidioc_s_tuner(struct file *file, void *priv,
 				const struct v4l2_tuner *t)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1296,8 +1314,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	if (dev->tuner_type == TUNER_ABSENT)
 		return -EINVAL;
@@ -1315,27 +1332,10 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 	return cx23885_set_frequency(file, priv, f);
 }
 
-static int vidioc_g_ctrl(struct file *file, void *priv,
-	struct v4l2_control *ctl)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
-	return cx23885_get_control(dev, ctl);
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-	struct v4l2_control *ctl)
-{
-	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
-
-	return cx23885_set_control(dev, ctl);
-}
-
 static int vidioc_querycap(struct file *file, void  *priv,
 				struct v4l2_capability *cap)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	struct cx23885_tsport  *tsport = &dev->ts1;
 
 	strlcpy(cap->driver, dev->name, sizeof(cap->driver));
@@ -1368,8 +1368,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
@@ -1378,285 +1377,63 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 	f->fmt.pix.colorspace   = 0;
 	f->fmt.pix.width        = dev->ts1.width;
 	f->fmt.pix.height       = dev->ts1.height;
-	f->fmt.pix.field        = fh->mpegq.field;
-	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
-		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
+	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
+	dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
+		dev->ts1.width, dev->ts1.height);
 	return 0;
 }
 
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    =
 		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
 	f->fmt.pix.colorspace   = 0;
-	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
-		dev->ts1.width, dev->ts1.height, fh->mpegq.field);
+	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
+	dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
+		dev->ts1.width, dev->ts1.height);
 	return 0;
 }
 
 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage    =
 		dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
 	f->fmt.pix.colorspace   = 0;
+	f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
 	dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
 		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
 	return 0;
 }
 
-static int vidioc_reqbufs(struct file *file, void *priv,
-				struct v4l2_requestbuffers *p)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_reqbufs(&fh->mpegq, p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
-				struct v4l2_buffer *p)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_querybuf(&fh->mpegq, p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv,
-				struct v4l2_buffer *p)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_qbuf(&fh->mpegq, p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
-	struct cx23885_fh  *fh  = priv;
-
-	return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK);
-}
-
-
-static int vidioc_streamon(struct file *file, void *priv,
-				enum v4l2_buf_type i)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_streamon(&fh->mpegq);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-
-	return videobuf_streamoff(&fh->mpegq);
-}
-
-static int vidioc_g_ext_ctrls(struct file *file, void *priv,
-				struct v4l2_ext_controls *f)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-
-	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-	return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS);
-}
-
-static int vidioc_s_ext_ctrls(struct file *file, void *priv,
-				struct v4l2_ext_controls *f)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-	struct cx2341x_mpeg_params p;
-	int err;
-
-	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-
-	p = dev->mpeg_params;
-	err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
-
-	if (err == 0) {
-		err = cx2341x_update(dev, cx23885_mbox_func,
-			&dev->mpeg_params, &p);
-		dev->mpeg_params = p;
-	}
-	return err;
-}
-
-static int vidioc_try_ext_ctrls(struct file *file, void *priv,
-				struct v4l2_ext_controls *f)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-	struct cx2341x_mpeg_params p;
-	int err;
-
-	if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-
-	p = dev->mpeg_params;
-	err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
-	return err;
-}
-
 static int vidioc_log_status(struct file *file, void *priv)
 {
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
+	struct cx23885_dev *dev = video_drvdata(file);
 	char name[32 + 2];
 
 	snprintf(name, sizeof(name), "%s/2", dev->name);
-	printk(KERN_INFO
-		"%s/2: ============  START LOG STATUS  ============\n",
-	       dev->name);
 	call_all(dev, core, log_status);
-	cx2341x_log_status(&dev->mpeg_params, name);
-	printk(KERN_INFO
-		"%s/2: =============  END LOG STATUS  =============\n",
-	       dev->name);
+	v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name);
 	return 0;
 }
 
-static int vidioc_querymenu(struct file *file, void *priv,
-				struct v4l2_querymenu *a)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-
-	return cx23885_querymenu(dev, a);
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
-				struct v4l2_queryctrl *c)
-{
-	struct cx23885_fh  *fh  = priv;
-	struct cx23885_dev *dev = fh->dev;
-
-	return cx23885_queryctrl(dev, c);
-}
-
-static int mpeg_open(struct file *file)
-{
-	struct cx23885_dev *dev = video_drvdata(file);
-	struct cx23885_fh *fh;
-
-	dprintk(2, "%s()\n", __func__);
-
-	/* allocate + initialize per filehandle data */
-	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-	if (!fh)
-		return -ENOMEM;
-
-	file->private_data = fh;
-	fh->dev      = dev;
-
-	videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops,
-			    &dev->pci->dev, &dev->ts1.slock,
-			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			    V4L2_FIELD_INTERLACED,
-			    sizeof(struct cx23885_buffer),
-			    fh, NULL);
-	return 0;
-}
-
-static int mpeg_release(struct file *file)
-{
-	struct cx23885_fh  *fh  = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
-
-	dprintk(2, "%s()\n", __func__);
-
-	/* FIXME: Review this crap */
-	/* Shut device down on last close */
-	if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
-		if (atomic_dec_return(&dev->v4l_reader_count) == 0) {
-			/* stop mpeg capture */
-			cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
-				CX23885_END_NOW, CX23885_MPEG_CAPTURE,
-				CX23885_RAW_BITS_NONE);
-
-			msleep(500);
-			cx23885_417_check_encoder(dev);
-
-			cx23885_cancel_buffers(&fh->dev->ts1);
-		}
-	}
-
-	if (fh->mpegq.streaming)
-		videobuf_streamoff(&fh->mpegq);
-	if (fh->mpegq.reading)
-		videobuf_read_stop(&fh->mpegq);
-
-	videobuf_mmap_free(&fh->mpegq);
-	file->private_data = NULL;
-	kfree(fh);
-
-	return 0;
-}
-
-static ssize_t mpeg_read(struct file *file, char __user *data,
-	size_t count, loff_t *ppos)
-{
-	struct cx23885_fh *fh = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
-
-	dprintk(2, "%s()\n", __func__);
-
-	/* Deal w/ A/V decoder * and mpeg encoder sync issues. */
-	/* Start mpeg encoder on first read. */
-	if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
-		if (atomic_inc_return(&dev->v4l_reader_count) == 1) {
-			if (cx23885_initialize_codec(dev, 1) < 0)
-				return -EINVAL;
-		}
-	}
-
-	return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
-				    file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int mpeg_poll(struct file *file,
-	struct poll_table_struct *wait)
-{
-	struct cx23885_fh *fh = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
-
-	dprintk(2, "%s\n", __func__);
-
-	return videobuf_poll_stream(file, &fh->mpegq, wait);
-}
-
-static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct cx23885_fh *fh = file->private_data;
-	struct cx23885_dev *dev = fh->dev;
-
-	dprintk(2, "%s()\n", __func__);
-
-	return videobuf_mmap_mapper(&fh->mpegq, vma);
-}
-
 static struct v4l2_file_operations mpeg_fops = {
 	.owner	       = THIS_MODULE,
-	.open	       = mpeg_open,
-	.release       = mpeg_release,
-	.read	       = mpeg_read,
-	.poll          = mpeg_poll,
-	.mmap	       = mpeg_mmap,
-	.ioctl	       = video_ioctl2,
+	.open           = v4l2_fh_open,
+	.release        = vb2_fop_release,
+	.read           = vb2_fop_read,
+	.poll		= vb2_fop_poll,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap           = vb2_fop_mmap,
 };
 
 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
@@ -1669,25 +1446,19 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_s_tuner		 = vidioc_s_tuner,
 	.vidioc_g_frequency	 = vidioc_g_frequency,
 	.vidioc_s_frequency	 = vidioc_s_frequency,
-	.vidioc_s_ctrl		 = vidioc_s_ctrl,
-	.vidioc_g_ctrl		 = vidioc_g_ctrl,
 	.vidioc_querycap	 = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap	 = vidioc_g_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap	 = vidioc_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap	 = vidioc_s_fmt_vid_cap,
-	.vidioc_reqbufs		 = vidioc_reqbufs,
-	.vidioc_querybuf	 = vidioc_querybuf,
-	.vidioc_qbuf		 = vidioc_qbuf,
-	.vidioc_dqbuf		 = vidioc_dqbuf,
-	.vidioc_streamon	 = vidioc_streamon,
-	.vidioc_streamoff	 = vidioc_streamoff,
-	.vidioc_g_ext_ctrls	 = vidioc_g_ext_ctrls,
-	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
-	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
+	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
+	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf      = vb2_ioctl_querybuf,
+	.vidioc_qbuf          = vb2_ioctl_qbuf,
+	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
+	.vidioc_streamon      = vb2_ioctl_streamon,
+	.vidioc_streamoff     = vb2_ioctl_streamoff,
 	.vidioc_log_status	 = vidioc_log_status,
-	.vidioc_querymenu	 = vidioc_querymenu,
-	.vidioc_queryctrl	 = vidioc_queryctrl,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_chip_info	 = cx23885_g_chip_info,
 	.vidioc_g_register	 = cx23885_g_register,
@@ -1711,6 +1482,7 @@ void cx23885_417_unregister(struct cx23885_dev *dev)
 			video_unregister_device(dev->v4l_device);
 		else
 			video_device_release(dev->v4l_device);
+		v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
 		dev->v4l_device = NULL;
 	}
 }
@@ -1742,6 +1514,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
 	/* FIXME: Port1 hardcoded here */
 	int err = -ENODEV;
 	struct cx23885_tsport *tsport = &dev->ts1;
+	struct vb2_queue *q;
 
 	dprintk(1, "%s()\n", __func__);
 
@@ -1757,14 +1530,36 @@ int cx23885_417_register(struct cx23885_dev *dev)
 		tsport->height = 576;
 
 	tsport->width = 720;
-	cx2341x_fill_defaults(&dev->mpeg_params);
-
-	dev->mpeg_params.port = CX2341X_PORT_SERIAL;
+	dev->cxhdl.port = CX2341X_PORT_SERIAL;
+	err = cx2341x_handler_init(&dev->cxhdl, 50);
+	if (err)
+		return err;
+	dev->cxhdl.priv = dev;
+	dev->cxhdl.func = cx23885_api_func;
+	cx2341x_handler_set_50hz(&dev->cxhdl, tsport->height == 576);
+	v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL);
 
 	/* Allocate and initialize V4L video device */
 	dev->v4l_device = cx23885_video_dev_alloc(tsport,
 		dev->pci, &cx23885_mpeg_template, "mpeg");
+	q = &dev->vb2_mpegq;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+	q->gfp_flags = GFP_DMA32;
+	q->min_buffers_needed = 2;
+	q->drv_priv = dev;
+	q->buf_struct_size = sizeof(struct cx23885_buffer);
+	q->ops = &cx23885_qops;
+	q->mem_ops = &vb2_dma_sg_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &dev->lock;
+
+	err = vb2_queue_init(q);
+	if (err < 0)
+		return err;
 	video_set_drvdata(dev->v4l_device, dev);
+	dev->v4l_device->lock = &dev->lock;
+	dev->v4l_device->queue = q;
 	err = video_register_device(dev->v4l_device,
 		VFL_TYPE_GRABBER, -1);
 	if (err < 0) {

+ 90 - 19
drivers/media/pci/cx23885/cx23885-alsa.c

@@ -15,10 +15,6 @@
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -84,6 +80,82 @@ MODULE_PARM_DESC(audio_debug, "enable debug messages [analog audio]");
 #define AUD_INT_MCHG_IRQ        (1 << 21)
 #define GP_COUNT_CONTROL_RESET	0x3
 
+static int cx23885_alsa_dma_init(struct cx23885_audio_dev *chip, int nr_pages)
+{
+	struct cx23885_audio_buffer *buf = chip->buf;
+	struct page *pg;
+	int i;
+
+	buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
+	if (NULL == buf->vaddr) {
+		dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
+		return -ENOMEM;
+	}
+
+	dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
+				(unsigned long)buf->vaddr,
+				nr_pages << PAGE_SHIFT);
+
+	memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT);
+	buf->nr_pages = nr_pages;
+
+	buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist));
+	if (NULL == buf->sglist)
+		goto vzalloc_err;
+
+	sg_init_table(buf->sglist, buf->nr_pages);
+	for (i = 0; i < buf->nr_pages; i++) {
+		pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE);
+		if (NULL == pg)
+			goto vmalloc_to_page_err;
+		sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0);
+	}
+	return 0;
+
+vmalloc_to_page_err:
+	vfree(buf->sglist);
+	buf->sglist = NULL;
+vzalloc_err:
+	vfree(buf->vaddr);
+	buf->vaddr = NULL;
+	return -ENOMEM;
+}
+
+static int cx23885_alsa_dma_map(struct cx23885_audio_dev *dev)
+{
+	struct cx23885_audio_buffer *buf = dev->buf;
+
+	buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist,
+			buf->nr_pages, PCI_DMA_FROMDEVICE);
+
+	if (0 == buf->sglen) {
+		pr_warn("%s: cx23885_alsa_map_sg failed\n", __func__);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int cx23885_alsa_dma_unmap(struct cx23885_audio_dev *dev)
+{
+	struct cx23885_audio_buffer *buf = dev->buf;
+
+	if (!buf->sglen)
+		return 0;
+
+	dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, PCI_DMA_FROMDEVICE);
+	buf->sglen = 0;
+	return 0;
+}
+
+static int cx23885_alsa_dma_free(struct cx23885_audio_buffer *buf)
+{
+	vfree(buf->sglist);
+	buf->sglist = NULL;
+	vfree(buf->vaddr);
+	buf->vaddr = NULL;
+	return 0;
+}
+
 /*
  * BOARD Specific: Sets audio DMA
  */
@@ -198,15 +270,18 @@ int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask)
 
 static int dsp_buffer_free(struct cx23885_audio_dev *chip)
 {
+	struct cx23885_riscmem *risc;
+
 	BUG_ON(!chip->dma_size);
 
 	dprintk(2, "Freeing buffer\n");
-	videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc);
-	videobuf_dma_free(chip->dma_risc);
-	btcx_riscmem_free(chip->pci, &chip->buf->risc);
+	cx23885_alsa_dma_unmap(chip);
+	cx23885_alsa_dma_free(chip->buf);
+	risc = &chip->buf->risc;
+	pci_free_consistent(chip->pci, risc->size, risc->cpu, risc->dma);
 	kfree(chip->buf);
 
-	chip->dma_risc = NULL;
+	chip->buf = NULL;
 	chip->dma_size = 0;
 
 	return 0;
@@ -289,6 +364,7 @@ static int snd_cx23885_close(struct snd_pcm_substream *substream)
 	return 0;
 }
 
+
 /*
  * hw_params callback
  */
@@ -296,8 +372,6 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 			      struct snd_pcm_hw_params *hw_params)
 {
 	struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream);
-	struct videobuf_dmabuf *dma;
-
 	struct cx23885_audio_buffer *buf;
 	int ret;
 
@@ -318,19 +392,18 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 		return -ENOMEM;
 
 	buf->bpl = chip->period_size;
+	chip->buf = buf;
 
-	dma = &buf->dma;
-	videobuf_dma_init(dma);
-	ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
+	ret = cx23885_alsa_dma_init(chip,
 			(PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
 	if (ret < 0)
 		goto error;
 
-	ret = videobuf_dma_map(&chip->pci->dev, dma);
+	ret = cx23885_alsa_dma_map(chip);
 	if (ret < 0)
 		goto error;
 
-	ret = cx23885_risc_databuffer(chip->pci, &buf->risc, dma->sglist,
+	ret = cx23885_risc_databuffer(chip->pci, &buf->risc, buf->sglist,
 				   chip->period_size, chip->num_periods, 1);
 	if (ret < 0)
 		goto error;
@@ -340,10 +413,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 	buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
 
-	chip->buf = buf;
-	chip->dma_risc = dma;
-
-	substream->runtime->dma_area = chip->dma_risc->vaddr;
+	substream->runtime->dma_area = chip->buf->vaddr;
 	substream->runtime->dma_bytes = chip->dma_size;
 	substream->runtime->dma_addr = 0;
 
@@ -351,6 +421,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream,
 
 error:
 	kfree(buf);
+	chip->buf = NULL;
 	return ret;
 }
 

+ 0 - 5
drivers/media/pci/cx23885/cx23885-av.c

@@ -14,11 +14,6 @@
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
  */
 
 #include "cx23885.h"

+ 0 - 5
drivers/media/pci/cx23885/cx23885-av.h

@@ -14,11 +14,6 @@
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
  */
 
 #ifndef _CX23885_AV_H_

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff