Browse Source

Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (452 commits)
  V4L/DVB (7731): tuner-xc2028: fix signal strength calculus
  V4L/DVB (7730): tuner-xc2028: Fix SCODE load for MTS firmwares
  V4L/DVB (7729): Fix VIDIOCGAP corruption in ivtv
  V4L/DVB (7728): tea5761: bugzilla #10462: tea5761 autodetection code were broken
  V4L/DVB (7726): cx23885: Enable cx23417 support on the HVR1800
  V4L/DVB (7725): cx23885: Add generic cx23417 hardware encoder support
  V4L/DVB (7723): pvrusb2: Clean up input selection list generation in V4L interface
  V4L/DVB (7722): pvrusb2: Implement FM radio support for Gotview USB2.0 DVD 2
  V4L/DVB (7721): pvrusb2: Restructure cx23416 firmware loading to have a common exit point
  V4L/DVB (7720): pvrusb2: Fix bad error code on cx23416 firmware load failure
  V4L/DVB (7719): pvrusb2: Implement input selection enforcement
  V4L/DVB (7718): pvrusb2-dvb: update Kbuild selections
  V4L/DVB (7717): pvrusb2-dvb: add DVB-T support for Hauppauge pvrusb2 model 73xxx
  V4L/DVB (7716): pvrusb2: clean up global functions
  V4L/DVB (7715): pvrusb2: Clean out all use of __FUNCTION__
  V4L/DVB (7714): pvrusb2: Fix hang on module removal
  V4L/DVB (7713): pvrusb2: Implement cleaner DVB kernel thread shutdown
  V4L/DVB (7712): pvrusb2: Close connect/disconnect race
  V4L/DVB (7711): pvrusb2: Fix race on module unload
  V4L/DVB (7710): pvrusb2: Implement critical digital streaming quirk for onair devices
  ...
Linus Torvalds 17 năm trước cách đây
mục cha
commit
c328d54cd4
100 tập tin đã thay đổi với 3235 bổ sung872 xóa
  1. 4 0
      Documentation/video4linux/CARDLIST.au0828
  2. 2 0
      Documentation/video4linux/CARDLIST.bttv
  3. 3 0
      Documentation/video4linux/CARDLIST.cx23885
  4. 9 0
      Documentation/video4linux/CARDLIST.cx88
  5. 11 2
      Documentation/video4linux/CARDLIST.saa7134
  6. 23 23
      Documentation/video4linux/extract_xc3028.pl
  7. 8 3
      drivers/media/Kconfig
  8. 1 1
      drivers/media/common/ir-functions.c
  9. 170 2
      drivers/media/common/ir-keymaps.c
  10. 4 4
      drivers/media/common/saa7146_core.c
  11. 3 3
      drivers/media/common/saa7146_i2c.c
  12. 2 2
      drivers/media/common/saa7146_vbi.c
  13. 2 2
      drivers/media/common/saa7146_video.c
  14. 5 0
      drivers/media/dvb/b2c2/Kconfig
  15. 2 0
      drivers/media/dvb/b2c2/Makefile
  16. 13 4
      drivers/media/dvb/b2c2/flexcop-common.h
  17. 2 2
      drivers/media/dvb/b2c2/flexcop-dma.c
  18. 6 3
      drivers/media/dvb/b2c2/flexcop-eeprom.c
  19. 164 47
      drivers/media/dvb/b2c2/flexcop-fe-tuner.c
  20. 122 58
      drivers/media/dvb/b2c2/flexcop-i2c.c
  21. 2 0
      drivers/media/dvb/b2c2/flexcop-misc.c
  22. 1 1
      drivers/media/dvb/b2c2/flexcop-pci.c
  23. 2 0
      drivers/media/dvb/b2c2/flexcop-reg.h
  24. 14 14
      drivers/media/dvb/b2c2/flexcop-sram.c
  25. 10 7
      drivers/media/dvb/b2c2/flexcop-usb.c
  26. 12 6
      drivers/media/dvb/b2c2/flexcop.c
  27. 1 1
      drivers/media/dvb/bt8xx/Kconfig
  28. 4 1
      drivers/media/dvb/bt8xx/Makefile
  29. 1 1
      drivers/media/dvb/bt8xx/dst.c
  30. 5 5
      drivers/media/dvb/bt8xx/dst_ca.c
  31. 15 8
      drivers/media/dvb/bt8xx/dvb-bt8xx.c
  32. 1 1
      drivers/media/dvb/bt8xx/dvb-bt8xx.h
  33. 7 2
      drivers/media/dvb/cinergyT2/cinergyT2.c
  34. 2 0
      drivers/media/dvb/dvb-core/demux.h
  35. 63 24
      drivers/media/dvb/dvb-core/dmxdev.c
  36. 18 18
      drivers/media/dvb/dvb-core/dvb_ca_en50221.c
  37. 3 3
      drivers/media/dvb/dvb-core/dvb_demux.c
  38. 15 15
      drivers/media/dvb/dvb-core/dvb_frontend.c
  39. 16 16
      drivers/media/dvb/dvb-core/dvb_net.c
  40. 5 1
      drivers/media/dvb/dvb-core/dvb_ringbuffer.c
  41. 8 0
      drivers/media/dvb/dvb-core/dvb_ringbuffer.h
  42. 34 13
      drivers/media/dvb/dvb-core/dvbdev.c
  43. 12 1
      drivers/media/dvb/dvb-core/dvbdev.h
  44. 1 0
      drivers/media/dvb/dvb-usb/Kconfig
  45. 5 1
      drivers/media/dvb/dvb-usb/a800.c
  46. 4 1
      drivers/media/dvb/dvb-usb/af9005.c
  47. 5 1
      drivers/media/dvb/dvb-usb/au6610.c
  48. 32 19
      drivers/media/dvb/dvb-usb/cxusb.c
  49. 4 0
      drivers/media/dvb/dvb-usb/dib0700.h
  50. 6 3
      drivers/media/dvb/dvb-usb/dib0700_core.c
  51. 293 32
      drivers/media/dvb/dvb-usb/dib0700_devices.c
  52. 10 4
      drivers/media/dvb/dvb-usb/dibusb-mb.c
  53. 4 1
      drivers/media/dvb/dvb-usb/dibusb-mc.c
  54. 6 2
      drivers/media/dvb/dvb-usb/digitv.c
  55. 12 5
      drivers/media/dvb/dvb-usb/dtt200u.c
  56. 2 1
      drivers/media/dvb/dvb-usb/dvb-usb-common.h
  57. 5 4
      drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
  58. 11 2
      drivers/media/dvb/dvb-usb/dvb-usb-ids.h
  59. 9 7
      drivers/media/dvb/dvb-usb/dvb-usb-init.c
  60. 4 1
      drivers/media/dvb/dvb-usb/dvb-usb.h
  61. 5 1
      drivers/media/dvb/dvb-usb/gl861.c
  62. 2 2
      drivers/media/dvb/dvb-usb/gp8psk-fe.c
  63. 4 1
      drivers/media/dvb/dvb-usb/gp8psk.c
  64. 20 14
      drivers/media/dvb/dvb-usb/m920x.c
  65. 4 1
      drivers/media/dvb/dvb-usb/nova-t-usb2.c
  66. 6 2
      drivers/media/dvb/dvb-usb/opera1.c
  67. 63 4
      drivers/media/dvb/dvb-usb/ttusb2.c
  68. 4 1
      drivers/media/dvb/dvb-usb/umt-010.c
  69. 9 9
      drivers/media/dvb/dvb-usb/vp702x-fe.c
  70. 4 1
      drivers/media/dvb/dvb-usb/vp702x.c
  71. 5 1
      drivers/media/dvb/dvb-usb/vp7045.c
  72. 28 0
      drivers/media/dvb/frontends/Kconfig
  73. 4 0
      drivers/media/dvb/frontends/Makefile
  74. 692 0
      drivers/media/dvb/frontends/au8522.c
  75. 56 0
      drivers/media/dvb/frontends/au8522.h
  76. 2 2
      drivers/media/dvb/frontends/bcm3510.c
  77. 1 1
      drivers/media/dvb/frontends/bcm3510.h
  78. 19 39
      drivers/media/dvb/frontends/bsbe1.h
  79. 1 1
      drivers/media/dvb/frontends/bsru6.h
  80. 6 6
      drivers/media/dvb/frontends/cx22700.c
  81. 1 1
      drivers/media/dvb/frontends/cx22700.h
  82. 13 13
      drivers/media/dvb/frontends/cx22702.c
  83. 1 1
      drivers/media/dvb/frontends/cx22702.h
  84. 3 3
      drivers/media/dvb/frontends/cx24110.c
  85. 1 1
      drivers/media/dvb/frontends/cx24110.h
  86. 48 0
      drivers/media/dvb/frontends/cx24113.h
  87. 204 100
      drivers/media/dvb/frontends/cx24123.c
  88. 16 5
      drivers/media/dvb/frontends/cx24123.h
  89. 1 1
      drivers/media/dvb/frontends/dib3000.h
  90. 1 1
      drivers/media/dvb/frontends/dib3000mc.h
  91. 7 1
      drivers/media/dvb/frontends/dib7000p.c
  92. 2 0
      drivers/media/dvb/frontends/dib7000p.h
  93. 1 259
      drivers/media/dvb/frontends/dvb-pll.c
  94. 12 21
      drivers/media/dvb/frontends/dvb-pll.h
  95. 164 0
      drivers/media/dvb/frontends/isl6405.c
  96. 74 0
      drivers/media/dvb/frontends/isl6405.h
  97. 1 1
      drivers/media/dvb/frontends/isl6421.h
  98. 400 0
      drivers/media/dvb/frontends/itd1000.c
  99. 42 0
      drivers/media/dvb/frontends/itd1000.h
  100. 88 0
      drivers/media/dvb/frontends/itd1000_priv.h

+ 4 - 0
Documentation/video4linux/CARDLIST.au0828

@@ -0,0 +1,4 @@
+  0 -> Unknown board                            (au0828)
+  1 -> Hauppauge HVR950Q                        (au0828)        [2040:7200]
+  2 -> Hauppauge HVR850                         (au0828)        [2040:7240]
+  3 -> DViCO FusionHDTV USB                     (au0828)        [0fe9:d620]

+ 2 - 0
Documentation/video4linux/CARDLIST.bttv

@@ -148,3 +148,5 @@
 147 -> VoodooTV 200 (USA)                                  [121a:3000]
 148 -> DViCO FusionHDTV 2                                  [dbc0:d200]
 149 -> Typhoon TV-Tuner PCI (50684)
+150 -> Geovision GV-600                                    [008a:763c]
+151 -> Kozumi KTV-01C

+ 3 - 0
Documentation/video4linux/CARDLIST.cx23885

@@ -5,3 +5,6 @@
   4 -> DViCO FusionHDTV5 Express                           [18ac:d500]
   5 -> Hauppauge WinTV-HVR1500Q                            [0070:7790,0070:7797]
   6 -> Hauppauge WinTV-HVR1500                             [0070:7710,0070:7717]
+  7 -> Hauppauge WinTV-HVR1200                             [0070:71d1]
+  8 -> Hauppauge WinTV-HVR1700                             [0070:8101]
+  9 -> Hauppauge WinTV-HVR1400                             [0070:8010]

+ 9 - 0
Documentation/video4linux/CARDLIST.cx88

@@ -57,3 +57,12 @@
  56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder   [0070:9600,0070:9601,0070:9602]
  57 -> ADS Tech Instant Video PCI                          [1421:0390]
  58 -> Pinnacle PCTV HD 800i                               [11bd:0051]
+ 59 -> DViCO FusionHDTV 5 PCI nano                         [18ac:d530]
+ 60 -> Pinnacle Hybrid PCTV                                [12ab:1788]
+ 61 -> Winfast TV2000 XP Global                            [107d:6f18]
+ 62 -> PowerColor Real Angel 330                           [14f1:ea3d]
+ 63 -> Geniatech X8000-MT DVBT                             [14f1:8852]
+ 64 -> DViCO FusionHDTV DVB-T PRO                          [18ac:db30]
+ 65 -> DViCO FusionHDTV 7 Gold                             [18ac:d610]
+ 66 -> Prolink Pixelview MPEG 8000GT                       [1554:4935]
+ 67 -> Kworld PlusTV HD PCI 120 (ATSC 120)                 [17de:08c1]

+ 11 - 2
Documentation/video4linux/CARDLIST.saa7134

@@ -25,8 +25,8 @@
  24 -> KNC One TV-Station DVR                   [1894:a006]
  25 -> ASUS TV-FM 7133                          [1043:4843]
  26 -> Pinnacle PCTV Stereo (saa7134)           [11bd:002b]
- 27 -> Manli MuchTV M-TV002/Behold TV 403 FM
- 28 -> Manli MuchTV M-TV001/Behold TV 401
+ 27 -> Manli MuchTV M-TV002
+ 28 -> Manli MuchTV M-TV001
  29 -> Nagase Sangyo TransGear 3000TV           [1461:050c]
  30 -> Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM)  [1019:4cb4]
  31 -> Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) [1019:4cb5]
@@ -131,3 +131,12 @@
 130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193]
 131 -> Twinhan Hybrid DTV-DVB 3056 PCI          [1822:0022]
 132 -> Genius TVGO AM11MCE
+133 -> NXP Snake DVB-S reference design
+134 -> Medion/Creatix CTX953 Hybrid             [16be:0010]
+135 -> MSI TV@nywhere A/D v1.1                  [1462:8625]
+136 -> AVerMedia Cardbus TV/Radio (E506R)       [1461:f436]
+137 -> AVerMedia Hybrid TV/Radio (A16D)         [1461:f936]
+138 -> Avermedia M115                           [1461:a836]
+139 -> Compro VideoMate T750                    [185b:c900]
+140 -> Avermedia DVB-S Pro A700                 [1461:a7a1]
+141 -> Avermedia DVB-S Hybrid+FM A700           [1461:a7a2]

+ 23 - 23
Documentation/video4linux/extract_xc3028.pl

@@ -686,11 +686,11 @@ sub main_firmware($$$$)
 	write_hunk(812664, 192);
 
 	#
-	# Firmware 58, type: SCODE FW  HAS IF (0x60000000), IF = 4.50 MHz id: NTSC/M Jp (0000000000002000), size: 192
+	# Firmware 58, type: SCODE FW  MTS LCD NOGD MONO IF HAS IF (0x6002b004), IF = 4.50 MHz id: NTSC PAL/M PAL/N (000000000000b700), size: 192
 	#
 
-	write_le32(0x60000000);			# Type
-	write_le64(0x00000000, 0x00002000);	# ID
+	write_le32(0x6002b004);			# Type
+	write_le64(0x00000000, 0x0000b700);	# ID
 	write_le16(4500);			# IF
 	write_le32(192);			# Size
 	write_hunk(807672, 192);
@@ -706,10 +706,10 @@ sub main_firmware($$$$)
 	write_hunk(807864, 192);
 
 	#
-	# Firmware 60, type: SCODE FW  DTV78 ZARLINK456 HAS IF (0x62000100), IF = 4.76 MHz id: (0000000000000000), size: 192
+	# Firmware 60, type: SCODE FW  DTV6 QAM DTV7 DTV78 DTV8 ZARLINK456 HAS IF (0x620003e0), IF = 4.76 MHz id: (0000000000000000), size: 192
 	#
 
-	write_le32(0x62000100);			# Type
+	write_le32(0x620003e0);			# Type
 	write_le64(0x00000000, 0x00000000);	# ID
 	write_le16(4760);			# IF
 	write_le32(192);			# Size
@@ -726,30 +726,30 @@ sub main_firmware($$$$)
 	write_hunk(811512, 192);
 
 	#
-	# Firmware 62, type: SCODE FW  DTV7 ZARLINK456 HAS IF (0x62000080), IF = 5.26 MHz id: (0000000000000000), size: 192
+	# Firmware 62, type: SCODE FW  HAS IF (0x60000000), IF = 5.26 MHz id: (0000000000000000), size: 192
 	#
 
-	write_le32(0x62000080);			# Type
+	write_le32(0x60000000);			# Type
 	write_le64(0x00000000, 0x00000000);	# ID
 	write_le16(5260);			# IF
 	write_le32(192);			# Size
 	write_hunk(810552, 192);
 
 	#
-	# Firmware 63, type: SCODE FW  MONO HAS IF (0x60008000), IF = 5.32 MHz id: PAL/BG NICAM/B (0000000800000007), size: 192
+	# Firmware 63, type: SCODE FW  MONO HAS IF (0x60008000), IF = 5.32 MHz id: PAL/BG A2 NICAM (0000000f00000007), size: 192
 	#
 
 	write_le32(0x60008000);			# Type
-	write_le64(0x00000008, 0x00000007);	# ID
+	write_le64(0x0000000f, 0x00000007);	# ID
 	write_le16(5320);			# IF
 	write_le32(192);			# Size
 	write_hunk(810744, 192);
 
 	#
-	# Firmware 64, type: SCODE FW  DTV8 CHINA HAS IF (0x64000200), IF = 5.40 MHz id: (0000000000000000), size: 192
+	# Firmware 64, type: SCODE FW  DTV7 DTV78 DTV8 DIBCOM52 CHINA HAS IF (0x65000380), IF = 5.40 MHz id: (0000000000000000), size: 192
 	#
 
-	write_le32(0x64000200);			# Type
+	write_le32(0x65000380);			# Type
 	write_le64(0x00000000, 0x00000000);	# ID
 	write_le16(5400);			# IF
 	write_le32(192);			# Size
@@ -766,50 +766,50 @@ sub main_firmware($$$$)
 	write_hunk(809592, 192);
 
 	#
-	# Firmware 66, type: SCODE FW  HAS IF (0x60000000), IF = 5.64 MHz id: PAL/BG A2/B (0000000200000007), size: 192
+	# Firmware 66, type: SCODE FW  HAS IF (0x60000000), IF = 5.64 MHz id: PAL/BG A2 (0000000300000007), size: 192
 	#
 
 	write_le32(0x60000000);			# Type
-	write_le64(0x00000002, 0x00000007);	# ID
+	write_le64(0x00000003, 0x00000007);	# ID
 	write_le16(5640);			# IF
 	write_le32(192);			# Size
 	write_hunk(808440, 192);
 
 	#
-	# Firmware 67, type: SCODE FW  HAS IF (0x60000000), IF = 5.74 MHz id: PAL/BG NICAM/B (0000000800000007), size: 192
+	# Firmware 67, type: SCODE FW  HAS IF (0x60000000), IF = 5.74 MHz id: PAL/BG NICAM (0000000c00000007), size: 192
 	#
 
 	write_le32(0x60000000);			# Type
-	write_le64(0x00000008, 0x00000007);	# ID
+	write_le64(0x0000000c, 0x00000007);	# ID
 	write_le16(5740);			# IF
 	write_le32(192);			# Size
 	write_hunk(808632, 192);
 
 	#
-	# Firmware 68, type: SCODE FW  DTV7 DIBCOM52 HAS IF (0x61000080), IF = 5.90 MHz id: (0000000000000000), size: 192
+	# Firmware 68, type: SCODE FW  HAS IF (0x60000000), IF = 5.90 MHz id: (0000000000000000), size: 192
 	#
 
-	write_le32(0x61000080);			# Type
+	write_le32(0x60000000);			# Type
 	write_le64(0x00000000, 0x00000000);	# ID
 	write_le16(5900);			# IF
 	write_le32(192);			# Size
 	write_hunk(810360, 192);
 
 	#
-	# Firmware 69, type: SCODE FW  MONO HAS IF (0x60008000), IF = 6.00 MHz id: PAL/I (0000000000000010), size: 192
+	# Firmware 69, type: SCODE FW  MONO HAS IF (0x60008000), IF = 6.00 MHz id: PAL/DK PAL/I SECAM/K3 SECAM/L SECAM/Lc NICAM (0000000c04c000f0), size: 192
 	#
 
 	write_le32(0x60008000);			# Type
-	write_le64(0x00000000, 0x00000010);	# ID
+	write_le64(0x0000000c, 0x04c000f0);	# ID
 	write_le16(6000);			# IF
 	write_le32(192);			# Size
 	write_hunk(808824, 192);
 
 	#
-	# Firmware 70, type: SCODE FW  DTV6 QAM F6MHZ HAS IF (0x68000060), IF = 6.20 MHz id: (0000000000000000), size: 192
+	# Firmware 70, type: SCODE FW  DTV6 QAM ATSC LG60 F6MHZ HAS IF (0x68050060), IF = 6.20 MHz id: (0000000000000000), size: 192
 	#
 
-	write_le32(0x68000060);			# Type
+	write_le32(0x68050060);			# Type
 	write_le64(0x00000000, 0x00000000);	# ID
 	write_le16(6200);			# IF
 	write_le32(192);			# Size
@@ -846,11 +846,11 @@ sub main_firmware($$$$)
 	write_hunk(809208, 192);
 
 	#
-	# Firmware 74, type: SCODE FW  MONO HAS IF (0x60008000), IF = 6.50 MHz id: SECAM/K3 (0000000004000000), size: 192
+	# Firmware 74, type: SCODE FW  MONO HAS IF (0x60008000), IF = 6.50 MHz id: PAL/DK SECAM/K3 SECAM/L NICAM (0000000c044000e0), size: 192
 	#
 
 	write_le32(0x60008000);			# Type
-	write_le64(0x00000000, 0x04000000);	# ID
+	write_le64(0x0000000c, 0x044000e0);	# ID
 	write_le16(6500);			# IF
 	write_le32(192);			# Size
 	write_hunk(811128, 192);

+ 8 - 3
drivers/media/Kconfig

@@ -30,7 +30,7 @@ config VIDEO_V4L2_COMMON
 	depends on (I2C || I2C=n) && VIDEO_DEV
 	default (I2C || I2C=n) && VIDEO_DEV
 
-config VIDEO_V4L1
+config VIDEO_ALLOW_V4L1
 	bool "Enable Video For Linux API 1 (DEPRECATED)"
 	depends on VIDEO_DEV && VIDEO_V4L2_COMMON
 	default VIDEO_DEV && VIDEO_V4L2_COMMON
@@ -59,10 +59,15 @@ config VIDEO_V4L1_COMPAT
 	  If you are unsure as to whether this is required, answer Y.
 
 config VIDEO_V4L2
-	bool
+	tristate
 	depends on VIDEO_DEV && VIDEO_V4L2_COMMON
 	default VIDEO_DEV && VIDEO_V4L2_COMMON
 
+config VIDEO_V4L1
+	tristate
+	depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
+	default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
+
 source "drivers/media/video/Kconfig"
 
 source "drivers/media/radio/Kconfig"
@@ -155,7 +160,7 @@ config VIDEOBUF_GEN
 	tristate
 
 config VIDEOBUF_DMA_SG
-	depends on PCI
+	depends on HAS_DMA
 	select VIDEOBUF_GEN
 	tristate
 

+ 1 - 1
drivers/media/common/ir-functions.c

@@ -34,7 +34,7 @@ static int repeat = 1;
 module_param(repeat, int, 0444);
 MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
 
-static int debug = 0;    /* debug level (0,1,2) */
+static int debug;    /* debug level (0,1,2) */
 module_param(debug, int, 0644);
 
 #define dprintk(level, fmt, arg...)	if (debug >= level) \

+ 170 - 2
drivers/media/common/ir-keymaps.c

@@ -212,6 +212,51 @@ IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
 
 EXPORT_SYMBOL_GPL(ir_codes_pixelview);
 
+/*
+   Mauro Carvalho Chehab <mchehab@infradead.org>
+   present on PV MPEG 8000GT
+ */
+IR_KEYTAB_TYPE ir_codes_pixelview_new[IR_KEYTAB_SIZE] = {
+	[0x3c] = KEY_PAUSE,		/* Timeshift */
+	[0x12] = KEY_POWER,
+
+	[0x3d] = KEY_1,
+	[0x38] = KEY_2,
+	[0x18] = KEY_3,
+	[0x35] = KEY_4,
+	[0x39] = KEY_5,
+	[0x15] = KEY_6,
+	[0x36] = KEY_7,
+	[0x3a] = KEY_8,
+	[0x1e] = KEY_9,
+	[0x3e] = KEY_0,
+
+	[0x1c] = KEY_AGAIN,		/* LOOP	*/
+	[0x3f] = KEY_MEDIA,		/* Source */
+	[0x1f] = KEY_LAST,		/* +100 */
+	[0x1b] = KEY_MUTE,
+
+	[0x17] = KEY_CHANNELDOWN,
+	[0x16] = KEY_CHANNELUP,
+	[0x10] = KEY_VOLUMEUP,
+	[0x14] = KEY_VOLUMEDOWN,
+	[0x13] = KEY_ZOOM,
+
+	[0x19] = KEY_SHUFFLE,		/* SNAPSHOT */
+	[0x1a] = KEY_SEARCH,		/* scan */
+
+	[0x37] = KEY_REWIND,		/* << */
+	[0x32] = KEY_RECORD,		/* o (red) */
+	[0x33] = KEY_FORWARD,		/* >> */
+	[0x11] = KEY_STOP,		/* square */
+	[0x3b] = KEY_PLAY,		/* > */
+	[0x30] = KEY_PLAYPAUSE,		/* || */
+
+	[0x31] = KEY_TV,
+	[0x34] = KEY_RADIO,
+};
+EXPORT_SYMBOL_GPL(ir_codes_pixelview_new);
+
 IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
 	[ 0x00 ] = KEY_0,
 	[ 0x01 ] = KEY_1,
@@ -726,7 +771,11 @@ IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = {
 	[ 0x12 ] = KEY_CHANNELUP,    // Channel +
 	[ 0x13 ] = KEY_CHANNELDOWN,  // Channel -
 	[ 0x06 ] = KEY_AGAIN,        // Recall
-	[ 0x10 ] = KEY_ENTER,      // Enter
+	[ 0x10 ] = KEY_ENTER,        // Enter
+
+	[ 0x19 ] = KEY_BACK,         // Rewind  ( <<< )
+	[ 0x1f ] = KEY_FORWARD,      // Forward ( >>> )
+	[ 0x0a ] = KEY_ANGLE,        // (no label, may be used as the PAUSE button)
 };
 
 EXPORT_SYMBOL_GPL(ir_codes_flyvideo);
@@ -1157,7 +1206,8 @@ EXPORT_SYMBOL_GPL(ir_codes_purpletv);
 
 /* Mapping for the 28 key remote control as seen at
    http://www.sednacomputer.com/photo/cardbus-tv.jpg
-   Pavel Mihaylov <bin@bash.info> */
+   Pavel Mihaylov <bin@bash.info>
+   Also for the remote bundled with Kozumi KTV-01C card */
 IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = {
 	[ 0x00 ] = KEY_0,
 	[ 0x01 ] = KEY_1,
@@ -1188,6 +1238,11 @@ IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = {
 	[ 0x1c ] = KEY_RADIO,          /* FM Radio */
 	[ 0x1d ] = KEY_RECORD,
 	[ 0x1e ] = KEY_PAUSE,
+	/* additional codes for Kozumi's remote */
+	[0x14] = KEY_INFO,        /* OSD */
+	[0x16] = KEY_OK,          /* OK */
+	[0x17] = KEY_DIGITS,      /* Plus */
+	[0x1f] = KEY_PLAY,        /* Play */
 };
 
 EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna);
@@ -1988,6 +2043,76 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
 
 EXPORT_SYMBOL_GPL(ir_codes_behold);
 
+/* Beholder Intl. Ltd. 2008
+ * Dmitry Belimov d.belimov@google.com
+ * Keytable is used by BeholdTV Columbus
+ * The "ascii-art picture" below (in comments, first row
+ * is the keycode in hex, and subsequent row(s) shows
+ * the button labels (several variants when appropriate)
+ * helps to descide which keycodes to assign to the buttons.
+ */
+IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE] = {
+
+	/*  0x13   0x11   0x1C   0x12  *
+	 *  Mute  Source  TV/FM  Power *
+	 *                             */
+
+	[0x13] = KEY_MUTE,
+	[0x11] = KEY_PROPS,
+	[0x1C] = KEY_TUNER,	/* KEY_TV/KEY_RADIO */
+	[0x12] = KEY_POWER,
+
+	/*  0x01    0x02    0x03  0x0D    *
+	 *   1       2       3   Stereo   *
+	 *                        	  *
+	 *  0x04    0x05    0x06  0x19    *
+	 *   4       5       6   Snapshot *
+	 *                        	  *
+	 *  0x07    0x08    0x09  0x10    *
+	 *   7       8       9    Zoom 	  *
+	 *                                */
+	[0x01] = KEY_1,
+	[0x02] = KEY_2,
+	[0x03] = KEY_3,
+	[0x0D] = KEY_SETUP,	  /* Setup key */
+	[0x04] = KEY_4,
+	[0x05] = KEY_5,
+	[0x06] = KEY_6,
+	[0x19] = KEY_BOOKMARKS, /* Snapshot key */
+	[0x07] = KEY_7,
+	[0x08] = KEY_8,
+	[0x09] = KEY_9,
+	[0x10] = KEY_ZOOM,
+
+	/*  0x0A    0x00    0x0B       0x0C   *
+	 * RECALL    0    ChannelUp  VolumeUp *
+	 *                                    */
+	[0x0A] = KEY_AGAIN,
+	[0x00] = KEY_0,
+	[0x0B] = KEY_CHANNELUP,
+	[0x0C] = KEY_VOLUMEUP,
+
+	/*   0x1B      0x1D      0x15        0x18     *
+	 * Timeshift  Record  ChannelDown  VolumeDown *
+	 *                                            */
+
+	[0x1B] = KEY_REWIND,
+	[0x1D] = KEY_RECORD,
+	[0x15] = KEY_CHANNELDOWN,
+	[0x18] = KEY_VOLUMEDOWN,
+
+	/*   0x0E   0x1E     0x0F     0x1A  *
+	 *   Stop   Pause  Previouse  Next  *
+	 *                                  */
+
+	[0x0E] = KEY_STOP,
+	[0x1E] = KEY_PAUSE,
+	[0x0F] = KEY_PREVIOUS,
+	[0x1A] = KEY_NEXT,
+
+};
+EXPORT_SYMBOL_GPL(ir_codes_behold_columbus);
+
 /*
  * Remote control for the Genius TVGO A11MCE
  * Adrian Pardini <pardo.bsso@gmail.com>
@@ -2033,3 +2158,46 @@ IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = {
 	[0x50] = KEY_BLUE,
 };
 EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce);
+
+/*
+ * Remote control for Powercolor Real Angel 330
+ * Daniel Fraga <fragabr@gmail.com>
+ */
+IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = {
+	[0x38] = KEY_SWITCHVIDEOMODE,	/* switch inputs */
+	[0x0c] = KEY_MEDIA,		/* Turn ON/OFF App */
+	[0x00] = KEY_0,
+	[0x01] = KEY_1,
+	[0x02] = KEY_2,
+	[0x03] = KEY_3,
+	[0x04] = KEY_4,
+	[0x05] = KEY_5,
+	[0x06] = KEY_6,
+	[0x07] = KEY_7,
+	[0x08] = KEY_8,
+	[0x09] = KEY_9,
+	[0x0a] = KEY_DIGITS,		/* single, double, tripple digit */
+	[0x29] = KEY_PREVIOUS,		/* previous channel */
+	[0x12] = KEY_BRIGHTNESSUP,
+	[0x13] = KEY_BRIGHTNESSDOWN,
+	[0x2b] = KEY_MODE,		/* stereo/mono */
+	[0x2c] = KEY_TEXT,		/* teletext */
+	[0x20] = KEY_UP,		/* channel up */
+	[0x21] = KEY_DOWN,		/* channel down */
+	[0x10] = KEY_RIGHT,		/* volume up */
+	[0x11] = KEY_LEFT,		/* volume down */
+	[0x0d] = KEY_MUTE,
+	[0x1f] = KEY_RECORD,
+	[0x17] = KEY_PLAY,
+	[0x16] = KEY_PAUSE,
+	[0x0b] = KEY_STOP,
+	[0x27] = KEY_FASTFORWARD,
+	[0x26] = KEY_REWIND,
+	[0x1e] = KEY_SEARCH,		/* autoscan */
+	[0x0e] = KEY_SHUFFLE,		/* snapshot */
+	[0x2d] = KEY_SETUP,
+	[0x0f] = KEY_SCREEN,		/* full screen */
+	[0x14] = KEY_RADIO,		/* FM radio */
+	[0x25] = KEY_POWER,		/* power */
+};
+EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel);

+ 4 - 4
drivers/media/common/saa7146_core.c

@@ -74,7 +74,7 @@ static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
 		if (err) {
 			printk(KERN_ERR "%s: %s timed out while waiting for "
 					"registers getting programmed\n",
-					dev->name, __FUNCTION__);
+					dev->name, __func__);
 			return -ETIMEDOUT;
 		}
 		msleep(1);
@@ -89,7 +89,7 @@ static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
 		saa7146_read(dev, MC2);
 		if (err) {
 			DEB_S(("%s: %s timed out while waiting for transfer "
-				"completion\n",	dev->name, __FUNCTION__));
+				"completion\n",	dev->name, __func__));
 			return -ETIMEDOUT;
 		}
 		msleep(1);
@@ -111,7 +111,7 @@ static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
 		if (!loops--) {
 			printk(KERN_ERR "%s: %s timed out while waiting for "
 					"registers getting programmed\n",
-					dev->name, __FUNCTION__);
+					dev->name, __func__);
 			return -ETIMEDOUT;
 		}
 		udelay(1);
@@ -125,7 +125,7 @@ static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
 		saa7146_read(dev, MC2);
 		if (!loops--) {
 			DEB_S(("%s: %s timed out while waiting for transfer "
-				"completion\n", dev->name, __FUNCTION__));
+				"completion\n", dev->name, __func__));
 			return -ETIMEDOUT;
 		}
 		udelay(5);

+ 3 - 3
drivers/media/common/saa7146_i2c.c

@@ -203,7 +203,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
 				return -ERESTARTSYS;
 
 			printk(KERN_WARNING "%s %s [irq]: timed out waiting for end of xfer\n",
-				dev->name, __FUNCTION__);
+				dev->name, __func__);
 			return -EIO;
 		}
 		status = saa7146_read(dev, I2C_STATUS);
@@ -221,7 +221,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
 			}
 			if (time_after(jiffies,timeout)) {
 				printk(KERN_WARNING "%s %s: timed out waiting for MC2\n",
-					dev->name, __FUNCTION__);
+					dev->name, __func__);
 				return -EIO;
 			}
 		}
@@ -238,7 +238,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
 				 * (no answer from nonexisistant device...)
 				 */
 				printk(KERN_WARNING "%s %s [poll]: timed out waiting for end of xfer\n",
-					dev->name, __FUNCTION__);
+					dev->name, __func__);
 				return -EIO;
 			}
 			if (++trial < 50 && short_delay)

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

@@ -407,8 +407,8 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
 	fh->vbi_fmt.start[1] = 312;
 	fh->vbi_fmt.count[1] = 16;
 
-	videobuf_queue_pci_init(&fh->vbi_q, &vbi_qops,
-			    dev->pci, &dev->slock,
+	videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
+			    &dev->pci->dev, &dev->slock,
 			    V4L2_BUF_TYPE_VBI_CAPTURE,
 			    V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
 			    sizeof(struct saa7146_buf),

+ 2 - 2
drivers/media/common/saa7146_video.c

@@ -1410,8 +1410,8 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
 	sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
 	fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
 
-	videobuf_queue_pci_init(&fh->video_q, &video_qops,
-			    dev->pci, &dev->slock,
+	videobuf_queue_sg_init(&fh->video_q, &video_qops,
+			    &dev->pci->dev, &dev->slock,
 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
 			    V4L2_FIELD_INTERLACED,
 			    sizeof(struct saa7146_buf),

+ 5 - 0
drivers/media/dvb/b2c2/Kconfig

@@ -9,6 +9,11 @@ config DVB_B2C2_FLEXCOP
 	select DVB_STV0297 if !DVB_FE_CUSTOMISE
 	select DVB_BCM3510 if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
+	select TUNER_SIMPLE if !DVB_FE_CUSTOMISE
+	select DVB_S5H1420 if !DVB_FE_CUSTOMISE
+	select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
+	select DVB_ISL6421 if !DVB_FE_CUSTOMISE
+	select DVB_CX24123 if !DVB_FE_CUSTOMISE
 	help
 	  Support for the digital TV receiver chip made by B2C2 Inc. included in
 	  Technisats PCI cards and USB boxes.

+ 2 - 0
drivers/media/dvb/b2c2/Makefile

@@ -2,6 +2,7 @@ b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
 	flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
 
+
 ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
 b2c2-flexcop-objs += flexcop-dma.o
 endif
@@ -13,3 +14,4 @@ b2c2-flexcop-usb-objs = flexcop-usb.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
+EXTRA_CFLAGS += -Idrivers/media/video/

+ 13 - 4
drivers/media/dvb/b2c2/flexcop-common.h

@@ -44,6 +44,14 @@ struct flexcop_dma {
 	u32 size; /* size of each address in bytes */
 };
 
+struct flexcop_i2c_adapter {
+	struct flexcop_device *fc;
+	struct i2c_adapter i2c_adap;
+
+	u8 no_base_addr;
+	flexcop_i2c_port_t port;
+};
+
 /* Control structure for data definitions that are common to
  * the B2C2-based PCI and USB devices.
  */
@@ -72,7 +80,7 @@ struct flexcop_device {
 	struct dmx_frontend mem_frontend;
 	int (*fe_sleep) (struct dvb_frontend *);
 
-	struct i2c_adapter i2c_adap;
+	struct flexcop_i2c_adapter fc_i2c_adap[3];
 	struct mutex i2c_mutex;
 	struct module *owner;
 
@@ -87,7 +95,8 @@ struct flexcop_device {
 	int               (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value);
 
 
-	int (*i2c_request) (struct flexcop_device*, flexcop_access_op_t, flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
+	int (*i2c_request) (struct flexcop_i2c_adapter*,
+		flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
 	int (*stream_control) (struct flexcop_device*, int);
 
 	int (*get_mac_addr) (struct flexcop_device *fc, int extended);
@@ -128,8 +137,8 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended);
  * one. We have it in flexcop-i2c.c, because it is going via the actual
  * I2C-channel of the flexcop.
  */
-int flexcop_i2c_request(struct flexcop_device*, flexcop_access_op_t,
-			flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
+int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
+	u8 chipaddr, u8 addr, u8 *buf, u16 len);
 
 /* from flexcop-sram.c */
 int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target);

+ 2 - 2
drivers/media/dvb/b2c2/flexcop-dma.c

@@ -112,7 +112,7 @@ static int flexcop_dma_remap(struct flexcop_device *fc,
 {
 	flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
 	flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
-	deb_info("%s\n",__FUNCTION__);
+	deb_info("%s\n",__func__);
 	v.dma_0xc.remap_enable = onoff;
 	fc->write_ibi_reg(fc,r,v);
 	return 0;
@@ -162,7 +162,7 @@ int flexcop_dma_config_timer(struct flexcop_device *fc,
 
 	flexcop_dma_remap(fc,dma_idx,0);
 
-	deb_info("%s\n",__FUNCTION__);
+	deb_info("%s\n",__func__);
 	v.dma_0x4_write.dmatimer = cycles;
 	fc->write_ibi_reg(fc,r,v);
 	return 0;

+ 6 - 3
drivers/media/dvb/b2c2/flexcop-eeprom.c

@@ -114,15 +114,18 @@ static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t
 {
 	int i,ret = 0;
 	u8 chipaddr =  0x50 | ((addr >> 8) & 3);
-	for (i = 0; i < retries; i++)
-		if ((ret = fc->i2c_request(fc,op,FC_I2C_PORT_EEPROM,chipaddr,addr & 0xff,buf,len)) == 0)
+	for (i = 0; i < retries; i++) {
+		ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr,
+			addr & 0xff, buf, len);
+		if (ret == 0)
 			break;
+	}
 	return ret;
 }
 
 static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries)
 {
-	int ret = flexcop_eeprom_request(fc,FC_READ,addr,buf,len,retries);
+	int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
 	if (ret == 0)
 		if (calc_lrc(buf, len - 1) != buf[len - 1])
 			ret = -EINVAL;

+ 164 - 47
drivers/media/dvb/b2c2/flexcop-fe-tuner.c

@@ -5,6 +5,8 @@
  *
  * see flexcop.c for copyright information.
  */
+#include <media/tuner.h>
+
 #include "flexcop.h"
 
 #include "stv0299.h"
@@ -15,6 +17,15 @@
 #include "mt312.h"
 #include "lgdt330x.h"
 #include "dvb-pll.h"
+#include "tuner-simple.h"
+
+#include "s5h1420.h"
+#include "itd1000.h"
+
+#include "cx24123.h"
+#include "cx24113.h"
+
+#include "isl6421.h"
 
 /* lnb control */
 
@@ -180,13 +191,13 @@ static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dv
 	buf[2] = 0x84;  /* 0xC4 */
 	buf[3] = 0x08;
 
-	if (params->frequency < 1500000) buf[3] |= 0x10;
+	if (params->frequency < 1500000)
+		buf[3] |= 0x10;
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) {
+	if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
 		return -EIO;
-	}
 	return 0;
 }
 
@@ -241,7 +252,7 @@ static struct stv0299_config samsung_tbmu24112_config = {
 	.mclk = 88000000UL,
 	.invert = 0,
 	.skip_reinit = 0,
-	.lock_output = STV0229_LOCKOUTPUT_LK,
+	.lock_output = STV0299_LOCKOUTPUT_LK,
 	.volt13_op0_op1 = STV0299_VOLT13_OP1,
 	.min_delay_ms = 100,
 	.set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
@@ -337,7 +348,7 @@ static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe,
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
+	if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
 		return -EIO;
 	return 0;
 }
@@ -386,10 +397,11 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 	deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]);
-	ret = fc->i2c_request(fc, FC_WRITE, FC_I2C_PORT_TUNER, 0x61, buf[0], &buf[1], 3);
+	ret = fc->i2c_request(&fc->fc_i2c_adap[2],
+		FC_WRITE, 0x61, buf[0], &buf[1], 3);
 	deb_tuner("tuner write returned: %d\n",ret);
 
-	return 0;
+	return ret;
 }
 
 static u8 alps_tdee4_stv0297_inittab[] = {
@@ -472,56 +484,159 @@ static struct stv0297_config alps_tdee4_stv0297_config = {
 //	.pll_set = alps_tdee4_stv0297_pll_set,
 };
 
+
+/* SkyStar2 rev2.7 (a/u) */
+static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
+	.demod_address = 0x53,
+	.invert = 1,
+	.repeated_start_workaround = 1,
+};
+
+static struct itd1000_config skystar2_rev2_7_itd1000_config = {
+	.i2c_address = 0x61,
+};
+
+/* SkyStar2 rev2.8 */
+static struct cx24123_config skystar2_rev2_8_cx24123_config = {
+	.demod_address = 0x55,
+	.dont_use_pll = 1,
+	.agc_callback = cx24113_agc_callback,
+};
+
+static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
+	.i2c_addr = 0x54,
+	.xtal_khz = 10111,
+};
+
 /* try to figure out the frontend, each card/box can have on of the following list */
 int flexcop_frontend_init(struct flexcop_device *fc)
 {
 	struct dvb_frontend_ops *ops;
+	struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap;
+	struct i2c_adapter *i2c_tuner;
+
+	/* enable no_base_addr - no repeated start when reading */
+	fc->fc_i2c_adap[0].no_base_addr = 1;
+	fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, i2c);
+	if (fc->fe != NULL) {
+		flexcop_ibi_value r108;
+		i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
+		ops = &fc->fe->ops;
+
+		fc->fe_sleep = ops->sleep;
+		ops->sleep   = flexcop_sleep;
+
+		fc->dev_type = FC_SKY_REV27;
+
+		/* enable no_base_addr - no repeated start when reading */
+		fc->fc_i2c_adap[2].no_base_addr = 1;
+		if (dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL)
+			err("ISL6421 could NOT be attached");
+		else
+			info("ISL6421 successfully attached");
+
+		/* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */
+		r108.raw = 0x00000506;
+		fc->write_ibi_reg(fc, tw_sm_c_108, r108);
+		if (i2c_tuner) {
+			if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, &skystar2_rev2_7_itd1000_config) == NULL)
+				err("ITD1000 could NOT be attached");
+			else
+				info("ITD1000 successfully attached");
+		}
+		goto fe_found;
+	}
+	fc->fc_i2c_adap[0].no_base_addr = 0; /* for the next devices we need it again */
+
+	/* try the sky v2.8 (cx24123, isl6421) */
+	fc->fe = dvb_attach(cx24123_attach,
+		&skystar2_rev2_8_cx24123_config, i2c);
+	if (fc->fe != NULL) {
+		i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
+		if (i2c_tuner != NULL) {
+			if (dvb_attach(cx24113_attach, fc->fe,
+					&skystar2_rev2_8_cx24113_config,
+					i2c_tuner) == NULL)
+				err("CX24113 could NOT be attached");
+			else
+				info("CX24113 successfully attached");
+		}
+
+		fc->dev_type = FC_SKY_REV28;
+
+		fc->fc_i2c_adap[2].no_base_addr = 1;
+		if (dvb_attach(isl6421_attach, fc->fe,
+		       &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL)
+			err("ISL6421 could NOT be attached");
+		else
+			info("ISL6421 successfully attached");
+
+		/* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
+		 * IR-receiver (PIC16F818) - but the card has no input for
+		 * that ??? */
+
+		goto fe_found;
+    }
 
 	/* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
-	if ((fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
+	fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
+	if (fc->fe != NULL) {
 		ops = &fc->fe->ops;
 
 		ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
 
 		ops->set_voltage = flexcop_set_voltage;
 
-		fc->fe_sleep             = ops->sleep;
-		ops->sleep               = flexcop_sleep;
+		fc->fe_sleep = ops->sleep;
+		ops->sleep = flexcop_sleep;
+
+		fc->dev_type = FC_SKY;
+		goto fe_found;
+	}
 
-		fc->dev_type          = FC_SKY;
-		info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
-	} else
 	/* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
-	if ((fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
-		fc->dev_type          = FC_AIR_DVB;
+	fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
+	if (fc->fe != NULL) {
+		fc->dev_type = FC_AIR_DVB;
 		fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
-		info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
-	} else
+		goto fe_found;
+	}
+
 	/* try the air atsc 2nd generation (nxt2002) */
-	if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
-		fc->dev_type          = FC_AIR_ATSC2;
+	fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
+	if (fc->fe != NULL) {
+		fc->dev_type = FC_AIR_ATSC2;
 		dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV);
-		info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
-	} else
-	/* try the air atsc 3nd generation (lgdt3303) */
-	if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
-		fc->dev_type          = FC_AIR_ATSC3;
-		dvb_attach(dvb_pll_attach, fc->fe, 0x61, &fc->i2c_adap, DVB_PLL_LG_TDVS_H06XF);
-		info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
-	} else
+		goto fe_found;
+	}
+
+	fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
+	if (fc->fe != NULL) {
+		fc->dev_type = FC_AIR_ATSC3;
+		dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
+				TUNER_LG_TDVS_H06XF);
+		goto fe_found;
+	}
+
 	/* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
-	if ((fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
-		fc->dev_type          = FC_AIR_ATSC1;
-		info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
-	} else
+	fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
+	if (fc->fe != NULL) {
+		fc->dev_type = FC_AIR_ATSC1;
+		goto fe_found;
+	}
+
 	/* try the cable dvb (stv0297) */
-	if ((fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
-		fc->dev_type                        = FC_CABLE;
+	fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
+	if (fc->fe != NULL) {
+		fc->dev_type = FC_CABLE;
 		fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
-		info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
-	} else
+		goto fe_found;
+	}
+
 	/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
-	if ((fc->fe = dvb_attach(vp310_mt312_attach, &skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
+	fc->fe = dvb_attach(vp310_mt312_attach,
+		&skystar23_samsung_tbdu18132_config, i2c);
+	if (fc->fe != NULL) {
 		ops = &fc->fe->ops;
 
 		ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
@@ -535,19 +650,21 @@ int flexcop_frontend_init(struct flexcop_device *fc)
 		ops->sleep                  = flexcop_sleep;
 
 		fc->dev_type                = FC_SKY_OLD;
-		info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
+		goto fe_found;
 	}
 
-	if (fc->fe == NULL) {
-		err("no frontend driver found for this B2C2/FlexCop adapter");
-		return -ENODEV;
-	} else {
-		if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
-			err("frontend registration failed!");
-			dvb_frontend_detach(fc->fe);
-			fc->fe = NULL;
-			return -EINVAL;
-		}
+	err("no frontend driver found for this B2C2/FlexCop adapter");
+	return -ENODEV;
+
+fe_found:
+	info("found '%s' .", fc->fe->ops.info.name);
+	if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
+		err("frontend registration failed!");
+		ops = &fc->fe->ops;
+		if (ops->release != NULL)
+			ops->release(fc->fe);
+		fc->fe = NULL;
+		return -EINVAL;
 	}
 	fc->init_state |= FC_STATE_FE_INIT;
 	return 0;

+ 122 - 58
drivers/media/dvb/b2c2/flexcop-i2c.c

@@ -9,6 +9,8 @@
 
 #define FC_MAX_I2C_RETRIES 100000
 
+/* #define DUMP_I2C_MESSAGES */
+
 static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100)
 {
 	int i;
@@ -38,30 +40,25 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
 	return -EREMOTEIO;
 }
 
-static int flexcop_i2c_read4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf)
+static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
+	flexcop_ibi_value r100, u8 *buf)
 {
 	flexcop_ibi_value r104;
 	int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */
 		ret;
 
-	if ((ret = flexcop_i2c_operation(fc,&r100)) != 0) {
-		/* The Cablestar needs a different kind of i2c-transfer (does not
-		 * support "Repeat Start"):
-		 * wait for the ACK failure,
-		 * and do a subsequent read with the Bit 30 enabled
-		 */
-		r100.tw_sm_c_100.no_base_addr_ack_error = 1;
-		if ((ret = flexcop_i2c_operation(fc,&r100)) != 0) {
-			deb_i2c("no_base_addr read failed. %d\n",ret);
-			return ret;
-		}
+	r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
+	ret = flexcop_i2c_operation(i2c->fc, &r100);
+	if (ret != 0) {
+		deb_i2c("read failed. %d\n", ret);
+		return ret;
 	}
 
 	buf[0] = r100.tw_sm_c_100.data1_reg;
 
 	if (len > 0) {
-		r104 = fc->read_ibi_reg(fc,tw_sm_c_104);
-		deb_i2c("read: r100: %08x, r104: %08x\n",r100.raw,r104.raw);
+		r104 = i2c->fc->read_ibi_reg(i2c->fc, tw_sm_c_104);
+		deb_i2c("read: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
 
 		/* there is at least one more byte, otherwise we wouldn't be here */
 		buf[1] = r104.tw_sm_c_104.data2_reg;
@@ -85,17 +82,22 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
 	r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
 	r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
 
-	deb_i2c("write: r100: %08x, r104: %08x\n",r100.raw,r104.raw);
+	deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
 
 	/* write the additional i2c data before doing the actual i2c operation */
-	fc->write_ibi_reg(fc,tw_sm_c_104,r104);
-	return flexcop_i2c_operation(fc,&r100);
+	fc->write_ibi_reg(fc, tw_sm_c_104, r104);
+	return flexcop_i2c_operation(fc, &r100);
 }
 
-int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op,
-		flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
+	flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
 {
 	int ret;
+
+#ifdef DUMP_I2C_MESSAGES
+	int i;
+#endif
+
 	u16 bytes_to_transfer;
 	flexcop_ibi_value r100;
 
@@ -103,7 +105,25 @@ int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op,
 	r100.raw = 0;
 	r100.tw_sm_c_100.chipaddr = chipaddr;
 	r100.tw_sm_c_100.twoWS_rw = op;
-	r100.tw_sm_c_100.twoWS_port_reg = port;
+	r100.tw_sm_c_100.twoWS_port_reg = i2c->port;
+
+#ifdef DUMP_I2C_MESSAGES
+	printk(KERN_DEBUG "%d ", i2c->port);
+	if (op == FC_READ)
+		printk("rd(");
+	else
+		printk("wr(");
+
+	printk("%02x): %02x ", chipaddr, addr);
+#endif
+
+	/* in that case addr is the only value ->
+	 * we write it twice as baseaddr and val0
+	 * BBTI is doing it like that for ISL6421 at least */
+	if (i2c->no_base_addr && len == 0 && op == FC_WRITE) {
+		buf = &addr;
+		len = 1;
+	}
 
 	while (len != 0) {
 		bytes_to_transfer = len > 4 ? 4 : len;
@@ -112,9 +132,14 @@ int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op,
 		r100.tw_sm_c_100.baseaddr = addr;
 
 		if (op == FC_READ)
-			ret = flexcop_i2c_read4(fc, r100, buf);
+			ret = flexcop_i2c_read4(i2c, r100, buf);
 		else
-			ret = flexcop_i2c_write4(fc,r100, buf);
+			ret = flexcop_i2c_write4(i2c->fc, r100, buf);
+
+#ifdef DUMP_I2C_MESSAGES
+		for (i = 0; i < bytes_to_transfer; i++)
+			printk("%02x ", buf[i]);
+#endif
 
 		if (ret < 0)
 			return ret;
@@ -122,7 +147,11 @@ int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op,
 		buf  += bytes_to_transfer;
 		addr += bytes_to_transfer;
 		len  -= bytes_to_transfer;
-	};
+	}
+
+#ifdef DUMP_I2C_MESSAGES
+	printk("\n");
+#endif
 
 	return 0;
 }
@@ -132,7 +161,7 @@ EXPORT_SYMBOL(flexcop_i2c_request);
 /* master xfer callback for demodulator */
 static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
 {
-	struct flexcop_device *fc = i2c_get_adapdata(i2c_adap);
+	struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
 	int i, ret = 0;
 
 	/* Some drivers use 1 byte or 0 byte reads as probes, which this
@@ -142,34 +171,29 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
 	if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1)
 		return 1;
 
-	if (mutex_lock_interruptible(&fc->i2c_mutex))
+	if (mutex_lock_interruptible(&i2c->fc->i2c_mutex))
 		return -ERESTARTSYS;
 
-	/* reading */
-	if (num == 2 &&
-		msgs[0].flags == 0 &&
-		msgs[1].flags == I2C_M_RD &&
-		msgs[0].buf != NULL &&
-		msgs[1].buf != NULL) {
-
-		ret = fc->i2c_request(fc, FC_READ, FC_I2C_PORT_DEMOD, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
-
-	} else for (i = 0; i < num; i++) { /* writing command */
-		if (msgs[i].flags != 0 || msgs[i].buf == NULL || msgs[i].len < 2) {
-			ret = -EINVAL;
+	for (i = 0; i < num; i++) {
+		/* reading */
+		if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
+			ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
+				msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len);
+			i++; /* skip the following message */
+		} else /* writing */
+			ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
+				msgs[i].buf[0], &msgs[i].buf[1],
+				msgs[i].len - 1);
+		if (ret < 0) {
+			err("i2c master_xfer failed");
 			break;
 		}
-
-		ret = fc->i2c_request(fc, FC_WRITE, FC_I2C_PORT_DEMOD, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
 	}
 
-	if (ret < 0)
-		err("i2c master_xfer failed");
-	else
-		ret = num;
-
-	mutex_unlock(&fc->i2c_mutex);
+	mutex_unlock(&i2c->fc->i2c_mutex);
 
+	if (ret == 0)
+		ret = num;
 	return ret;
 }
 
@@ -189,28 +213,68 @@ int flexcop_i2c_init(struct flexcop_device *fc)
 
 	mutex_init(&fc->i2c_mutex);
 
-	memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter));
-	strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",
-		sizeof(fc->i2c_adap.name));
-
-	i2c_set_adapdata(&fc->i2c_adap,fc);
+	fc->fc_i2c_adap[0].fc = fc;
+	fc->fc_i2c_adap[1].fc = fc;
+	fc->fc_i2c_adap[2].fc = fc;
+
+	fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
+	fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
+	fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
+
+	strncpy(fc->fc_i2c_adap[0].i2c_adap.name,
+		"B2C2 FlexCop I2C to demod", I2C_NAME_SIZE);
+	strncpy(fc->fc_i2c_adap[1].i2c_adap.name,
+		"B2C2 FlexCop I2C to eeprom", I2C_NAME_SIZE);
+	strncpy(fc->fc_i2c_adap[2].i2c_adap.name,
+		"B2C2 FlexCop I2C to tuner", I2C_NAME_SIZE);
+
+	i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
+	i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
+	i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]);
+
+	fc->fc_i2c_adap[0].i2c_adap.class =
+		fc->fc_i2c_adap[1].i2c_adap.class =
+		fc->fc_i2c_adap[2].i2c_adap.class = I2C_CLASS_TV_DIGITAL;
+	fc->fc_i2c_adap[0].i2c_adap.algo =
+		fc->fc_i2c_adap[1].i2c_adap.algo =
+		fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo;
+	fc->fc_i2c_adap[0].i2c_adap.algo_data =
+		fc->fc_i2c_adap[1].i2c_adap.algo_data =
+		fc->fc_i2c_adap[2].i2c_adap.algo_data = NULL;
+	fc->fc_i2c_adap[0].i2c_adap.dev.parent =
+		fc->fc_i2c_adap[1].i2c_adap.dev.parent =
+		fc->fc_i2c_adap[2].i2c_adap.dev.parent = fc->dev;
+
+	ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap);
+	if (ret < 0)
+		return ret;
 
-	fc->i2c_adap.class	    = I2C_CLASS_TV_DIGITAL;
-	fc->i2c_adap.algo       = &flexcop_algo;
-	fc->i2c_adap.algo_data  = NULL;
-	fc->i2c_adap.dev.parent	= fc->dev;
+	ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap);
+	if (ret < 0)
+		goto adap_1_failed;
 
-	if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0)
-		return ret;
+	ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap);
+	if (ret < 0)
+		goto adap_2_failed;
 
 	fc->init_state |= FC_STATE_I2C_INIT;
 	return 0;
+
+adap_2_failed:
+	i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
+adap_1_failed:
+	i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
+
+	return ret;
 }
 
 void flexcop_i2c_exit(struct flexcop_device *fc)
 {
-	if (fc->init_state & FC_STATE_I2C_INIT)
-		i2c_del_adapter(&fc->i2c_adap);
+	if (fc->init_state & FC_STATE_I2C_INIT) {
+		i2c_del_adapter(&fc->fc_i2c_adap[2].i2c_adap);
+		i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
+		i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
+	}
 
 	fc->init_state &= ~FC_STATE_I2C_INIT;
 }

+ 2 - 0
drivers/media/dvb/b2c2/flexcop-misc.c

@@ -52,6 +52,8 @@ static const char *flexcop_device_names[] = {
 	"Sky2PC/SkyStar 2 DVB-S (old version)",
 	"Cable2PC/CableStar 2 DVB-C",
 	"Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
+	"Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
+	"Sky2PC/SkyStar 2 DVB-S rev 2.8",
 };
 
 static const char *flexcop_bus_names[] = {

+ 1 - 1
drivers/media/dvb/b2c2/flexcop-pci.c

@@ -32,7 +32,7 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently jus
 #define deb_irq(args...)   dprintk(0x08,args)
 #define deb_chk(args...)   dprintk(0x10,args)
 
-static int debug = 0;
+static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS);
 

+ 2 - 0
drivers/media/dvb/b2c2/flexcop-reg.h

@@ -25,6 +25,8 @@ typedef enum {
 	FC_SKY_OLD,
 	FC_CABLE,
 	FC_AIR_ATSC3,
+	FC_SKY_REV27,
+	FC_SKY_REV28,
 } flexcop_device_type_t;
 
 typedef enum {

+ 14 - 14
drivers/media/dvb/b2c2/flexcop-sram.c

@@ -90,7 +90,7 @@ static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *
 		};
 
 		if (retries == 0)
-			printk("%s: SRAM timeout\n", __FUNCTION__);
+			printk("%s: SRAM timeout\n", __func__);
 
 		write_reg_dw(adapter, 0x700, command);
 
@@ -115,7 +115,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf,
 		};
 
 		if (retries == 0)
-			printk("%s: SRAM timeout\n", __FUNCTION__);
+			printk("%s: SRAM timeout\n", __func__);
 
 		write_reg_dw(adapter, 0x700, command);
 
@@ -127,7 +127,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf,
 		};
 
 		if (retries == 0)
-			printk("%s: SRAM timeout\n", __FUNCTION__);
+			printk("%s: SRAM timeout\n", __func__);
 
 		value = read_reg_dw(adapter, 0x700) >> 0x10;
 
@@ -240,13 +240,13 @@ static void sram_init(struct adapter *adapter)
 
 		adapter->dw_sram_type = tmp & 0x30000;
 
-		ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
+		ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
 
 	} else {
 
 		adapter->dw_sram_type = 0x10000;
 
-		ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
+		ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
 	}
 
 	/* return value is never used? */
@@ -257,7 +257,7 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
 {
 	u8 tmp1, tmp2;
 
-	dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
+	dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
 
 	sram_set_size(adapter, mask);
 	sram_init(adapter);
@@ -275,7 +275,7 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
 	sram_read(adapter, addr, &tmp2, 1);
 	sram_read(adapter, addr, &tmp2, 1);
 
-	dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
+	dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2);
 
 	if (tmp2 != 0xa5)
 		return 0;
@@ -293,7 +293,7 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
 	sram_read(adapter, addr, &tmp2, 1);
 	sram_read(adapter, addr, &tmp2, 1);
 
-	dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
+	dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2);
 
 	if (tmp2 != 0x5a)
 		return 0;
@@ -340,7 +340,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
 
 	tmp3 = read_reg_dw(adapter, 0x71c);
 
-	dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
+	dprintk("%s: tmp3 = %x\n", __func__, tmp3);
 
 	write_reg_dw(adapter, 0x71c, tmp2);
 
@@ -351,7 +351,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
 		sram_init(adapter);
 		write_reg_dw(adapter, 0x208, tmp);
 
-		dprintk("%s: sram size = 32K\n", __FUNCTION__);
+		dprintk("%s: sram size = 32K\n", __func__);
 
 		return 32;
 	}
@@ -361,7 +361,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
 		sram_init(adapter);
 		write_reg_dw(adapter, 0x208, tmp);
 
-		dprintk("%s: sram size = 128K\n", __FUNCTION__);
+		dprintk("%s: sram size = 128K\n", __func__);
 
 		return 128;
 	}
@@ -371,7 +371,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
 		sram_init(adapter);
 		write_reg_dw(adapter, 0x208, tmp);
 
-		dprintk("%s: sram size = 64K\n", __FUNCTION__);
+		dprintk("%s: sram size = 64K\n", __func__);
 
 		return 64;
 	}
@@ -381,7 +381,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
 		sram_init(adapter);
 		write_reg_dw(adapter, 0x208, tmp);
 
-		dprintk("%s: sram size = 32K\n", __FUNCTION__);
+		dprintk("%s: sram size = 32K\n", __func__);
 
 		return 32;
 	}
@@ -390,7 +390,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
 	sram_init(adapter);
 	write_reg_dw(adapter, 0x208, tmp);
 
-	dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
+	dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
 
 	return 0;
 }

+ 10 - 7
drivers/media/dvb/b2c2/flexcop-usb.c

@@ -211,10 +211,11 @@ static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
 #endif
 
 /* usb i2c stuff */
-static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb,
+static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
 		flexcop_usb_request_t req, flexcop_usb_i2c_function_t func,
-		flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u8 buflen)
+		u8 chipaddr, u8 addr, u8 *buf, u8 buflen)
 {
+	struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
 	u16 wValue, wIndex;
 	int nWaitTime,pipe,len;
 //	u8 dwRequestType;
@@ -242,7 +243,7 @@ static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb,
 			deb_info("unsupported function for i2c_req %x\n",func);
 			return -EINVAL;
 	}
-	wValue = (func << 8 ) | (port << 4);
+	wValue = (func << 8) | (i2c->port << 4);
 	wIndex = (chipaddr << 8 ) | addr;
 
 	deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req,
@@ -274,13 +275,15 @@ static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_regi
 	return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0);
 }
 
-static int flexcop_usb_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op,
-		flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c,
+	flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
 {
 	if (op == FC_READ)
-		return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_READ,port,chipaddr,addr,buf,len);
+		return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
+			USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
 	else
-		return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len);
+		return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
+			USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
 }
 
 static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length)

+ 12 - 6
drivers/media/dvb/b2c2/flexcop.c

@@ -49,6 +49,8 @@ module_param_named(debug, b2c2_flexcop_debug,  int, 0644);
 MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
 #undef DEBSTATUS
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 /* global zero for ibi values */
 flexcop_ibi_value ibi_zero;
 
@@ -66,8 +68,10 @@ static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
 
 static int flexcop_dvb_init(struct flexcop_device *fc)
 {
-	int ret;
-	if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner,fc->dev)) < 0) {
+	int ret = dvb_register_adapter(&fc->dvb_adapter,
+				       "FlexCop Digital TV device", fc->owner,
+				       fc->dev, adapter_nr);
+	if (ret < 0) {
 		err("error registering DVB adapter");
 		return ret;
 	}
@@ -257,6 +261,12 @@ int flexcop_device_initialize(struct flexcop_device *fc)
 	if ((ret = flexcop_dvb_init(fc)))
 		goto error;
 
+	/* i2c has to be done before doing EEProm stuff -
+	 * because the EEProm is accessed via i2c */
+	ret = flexcop_i2c_init(fc);
+	if (ret)
+		goto error;
+
 	/* do the MAC address reading after initializing the dvb_adapter */
 	if (fc->get_mac_addr(fc, 0) == 0) {
 		u8 *b = fc->dvb_adapter.proposed_mac;
@@ -266,10 +276,6 @@ int flexcop_device_initialize(struct flexcop_device *fc)
 	} else
 		warn("reading of MAC address failed.\n");
 
-
-	if ((ret = flexcop_i2c_init(fc)))
-		goto error;
-
 	if ((ret = flexcop_frontend_init(fc)))
 		goto error;
 

+ 1 - 1
drivers/media/dvb/bt8xx/Kconfig

@@ -7,8 +7,8 @@ config DVB_BT8XX
 	select DVB_CX24110 if !DVB_FE_CUSTOMISE
 	select DVB_OR51211 if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
-	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+	select TUNER_SIMPLE if !DVB_FE_CUSTOMISE
 	select FW_LOADER
 	help
 	  Support for PCI cards based on the Bt8xx PCI bridge. Examples are

+ 4 - 1
drivers/media/dvb/bt8xx/Makefile

@@ -1,3 +1,6 @@
 obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
 
-EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video/bt8xx -Idrivers/media/dvb/frontends
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+EXTRA_CFLAGS += -Idrivers/media/video/bt8xx
+EXTRA_CFLAGS += -Idrivers/media/video

+ 1 - 1
drivers/media/dvb/bt8xx/dst.c

@@ -1290,7 +1290,7 @@ static int dst_get_signal(struct dst_state *state)
 {
 	int retval;
 	u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
-	//dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
+	//dprintk("%s: Getting Signal strength and other parameters\n", __func__);
 	if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
 		state->decode_lock = state->decode_strength = state->decode_snr = 0;
 		return 0;

+ 5 - 5
drivers/media/dvb/bt8xx/dst_ca.c

@@ -36,13 +36,13 @@
 #define dprintk(x, y, z, format, arg...) do {						\
 	if (z) {									\
 		if	((x > DST_CA_ERROR) && (x > y))					\
-			printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg);	\
+			printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);	\
 		else if	((x > DST_CA_NOTICE) && (x > y))				\
-			printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg);	\
+			printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);	\
 		else if ((x > DST_CA_INFO) && (x > y))					\
-			printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg);	\
+			printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);	\
 		else if ((x > DST_CA_DEBUG) && (x > y))					\
-			printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg);	\
+			printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);	\
 	} else {									\
 		if (x > y)								\
 			printk(format, ## arg);						\
@@ -162,7 +162,7 @@ static int ca_get_app_info(struct dst_state *state)
 	dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================");
 	dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]",
 		state->messages[7], (state->messages[8] << 8) | state->messages[9],
-		(state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12]));
+		(state->messages[10] << 8) | state->messages[11], __func__, (char *)(&state->messages[12]));
 	dprintk(verbose, DST_CA_INFO, 1, " ==================================================================================================");
 
 	// Transform dst message to correct application_info message

+ 15 - 8
drivers/media/dvb/bt8xx/dvb-bt8xx.c

@@ -40,10 +40,12 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 #define dprintk( args... ) \
-	do \
+	do { \
 		if (debug) printk(KERN_DEBUG args); \
-	while (0)
+	} while (0)
 
 #define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
 
@@ -609,8 +611,9 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
 		lgdt330x_reset(card);
 		card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
 		if (card->fe != NULL) {
-			dvb_attach(dvb_pll_attach, card->fe, 0x61,
-				   card->i2c_adapter, DVB_PLL_LG_TDVS_H06XF);
+			dvb_attach(simple_tuner_attach, card->fe,
+				   card->i2c_adapter, 0x61,
+				   TUNER_LG_TDVS_H06XF);
 			dprintk ("dvb_bt8xx: lgdt330x detected\n");
 		}
 		break;
@@ -670,7 +673,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
 		state->dst_ca = NULL;
 		/*	DST is not a frontend, attaching the ASIC	*/
 		if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) {
-			printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__);
+			printk("%s: Could not find a Twinhan DST.\n", __func__);
 			break;
 		}
 		/*	Attach other DST peripherals if any		*/
@@ -692,8 +695,9 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
 	case BTTV_BOARD_PC_HDTV:
 		card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter);
 		if (card->fe != NULL)
-			dvb_attach(dvb_pll_attach, card->fe, 0x61,
-				   card->i2c_adapter, DVB_PLL_FCV1236D);
+			dvb_attach(simple_tuner_attach, card->fe,
+				   card->i2c_adapter, 0x61,
+				   TUNER_PHILIPS_FCV1236D);
 		break;
 	}
 
@@ -715,7 +719,10 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
 {
 	int result;
 
-	if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE, &card->bt->dev->dev)) < 0) {
+	result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
+				      THIS_MODULE, &card->bt->dev->dev,
+				      adapter_nr);
+	if (result < 0) {
 		printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
 		return result;
 	}

+ 1 - 1
drivers/media/dvb/bt8xx/dvb-bt8xx.h

@@ -38,7 +38,7 @@
 #include "or51211.h"
 #include "lgdt330x.h"
 #include "zl10353.h"
-#include "dvb-pll.h"
+#include "tuner-simple.h"
 
 struct dvb_bt8xx_card {
 	struct mutex lock;

+ 7 - 2
drivers/media/dvb/cinergyT2/cinergyT2.c

@@ -58,11 +58,13 @@ static int debug;
 module_param_named(debug, debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 #define dprintk(level, args...)						\
 do {									\
 	if ((debug & level)) {						\
 		printk("%s: %s(): ", KBUILD_MODNAME,			\
-		       __FUNCTION__);					\
+		       __func__);					\
 		printk(args); }						\
 } while (0)
 
@@ -938,7 +940,10 @@ static int cinergyt2_probe (struct usb_interface *intf,
 		return -ENOMEM;
 	}
 
-	if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE, &cinergyt2->udev->dev)) < 0) {
+	err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME,
+				   THIS_MODULE, &cinergyt2->udev->dev,
+				   adapter_nr);
+	if (err < 0) {
 		kfree(cinergyt2);
 		return err;
 	}

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

@@ -80,6 +80,8 @@ enum dmx_success {
 #define	TS_PAYLOAD_ONLY 2   /* in case TS_PACKET is set, only send the TS
 			       payload (<=184 bytes per packet) to callback */
 #define TS_DECODER      4   /* send stream to built-in decoder (if present) */
+#define TS_DEMUX        8   /* in case TS_PACKET is set, send the TS to
+			       the demux device, not to the dvr device */
 
 /* PES type for filters which write to built-in decoder */
 /* these should be kept identical to the types in dmx.h */

+ 63 - 24
drivers/media/dvb/dvb-core/dmxdev.c

@@ -126,7 +126,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
 	struct dmxdev *dmxdev = dvbdev->priv;
 	struct dmx_frontend *front;
 
-	dprintk("function : %s\n", __FUNCTION__);
+	dprintk("function : %s\n", __func__);
 
 	if (mutex_lock_interruptible(&dmxdev->mutex))
 		return -ERESTARTSYS;
@@ -259,6 +259,39 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
 	return ret;
 }
 
+static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev,
+				      unsigned long size)
+{
+	struct dvb_ringbuffer *buf = &dmxdev->dvr_buffer;
+	void *newmem;
+	void *oldmem;
+
+	dprintk("function : %s\n", __func__);
+
+	if (buf->size == size)
+		return 0;
+	if (!size)
+		return -EINVAL;
+
+	newmem = vmalloc(size);
+	if (!newmem)
+		return -ENOMEM;
+
+	oldmem = buf->data;
+
+	spin_lock_irq(&dmxdev->lock);
+	buf->data = newmem;
+	buf->size = size;
+
+	/* reset and not flush in case the buffer shrinks */
+	dvb_ringbuffer_reset(buf);
+	spin_unlock_irq(&dmxdev->lock);
+
+	vfree(oldmem);
+
+	return 0;
+}
+
 static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter
 					       *dmxdevfilter, int state)
 {
@@ -271,28 +304,32 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
 				      unsigned long size)
 {
 	struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;
-	void *mem;
+	void *newmem;
+	void *oldmem;
 
 	if (buf->size == size)
 		return 0;
+	if (!size)
+		return -EINVAL;
 	if (dmxdevfilter->state >= DMXDEV_STATE_GO)
 		return -EBUSY;
+
+	newmem = vmalloc(size);
+	if (!newmem)
+		return -ENOMEM;
+
+	oldmem = buf->data;
+
 	spin_lock_irq(&dmxdevfilter->dev->lock);
-	mem = buf->data;
-	buf->data = NULL;
+	buf->data = newmem;
 	buf->size = size;
-	dvb_ringbuffer_flush(buf);
+
+	/* reset and not flush in case the buffer shrinks */
+	dvb_ringbuffer_reset(buf);
 	spin_unlock_irq(&dmxdevfilter->dev->lock);
-	vfree(mem);
 
-	if (buf->size) {
-		mem = vmalloc(dmxdevfilter->buffer.size);
-		if (!mem)
-			return -ENOMEM;
-		spin_lock_irq(&dmxdevfilter->dev->lock);
-		buf->data = mem;
-		spin_unlock_irq(&dmxdevfilter->dev->lock);
-	}
+	vfree(oldmem);
+
 	return 0;
 }
 
@@ -374,7 +411,8 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
 		return 0;
 	}
 
-	if (dmxdevfilter->params.pes.output == DMX_OUT_TAP)
+	if (dmxdevfilter->params.pes.output == DMX_OUT_TAP
+	    || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP)
 		buffer = &dmxdevfilter->buffer;
 	else
 		buffer = &dmxdevfilter->dev->dvr_buffer;
@@ -550,7 +588,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 								   dvb_dmxdev_section_callback);
 			if (ret < 0) {
 				printk("DVB (%s): could not alloc feed\n",
-				       __FUNCTION__);
+				       __func__);
 				return ret;
 			}
 
@@ -558,7 +596,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 					      (para->flags & DMX_CHECK_CRC) ? 1 : 0);
 			if (ret < 0) {
 				printk("DVB (%s): could not set feed\n",
-				       __FUNCTION__);
+				       __func__);
 				dvb_dmxdev_feed_restart(filter);
 				return ret;
 			}
@@ -620,9 +658,10 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 
 		if (otype == DMX_OUT_TS_TAP)
 			ts_type |= TS_PACKET;
-
-		if (otype == DMX_OUT_TAP)
-			ts_type |= TS_PAYLOAD_ONLY | TS_PACKET;
+		else if (otype == DMX_OUT_TSDEMUX_TAP)
+			ts_type |= TS_PACKET | TS_DEMUX;
+		else if (otype == DMX_OUT_TAP)
+			ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
 
 		ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux,
 						      tsfeed,
@@ -732,7 +771,7 @@ static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
 				 struct dmxdev_filter *dmxdevfilter,
 				 struct dmx_sct_filter_params *params)
 {
-	dprintk("function : %s\n", __FUNCTION__);
+	dprintk("function : %s\n", __func__);
 
 	dvb_dmxdev_filter_stop(dmxdevfilter);
 
@@ -1007,6 +1046,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dmxdev *dmxdev = dvbdev->priv;
+	unsigned long arg = (unsigned long)parg;
 	int ret;
 
 	if (mutex_lock_interruptible(&dmxdev->mutex))
@@ -1014,8 +1054,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
 
 	switch (cmd) {
 	case DMX_SET_BUFFER_SIZE:
-		// FIXME: implement
-		ret = 0;
+		ret = dvb_dvr_set_buffer_size(dmxdev, arg);
 		break;
 
 	default:
@@ -1038,7 +1077,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
 	struct dmxdev *dmxdev = dvbdev->priv;
 	unsigned int mask = 0;
 
-	dprintk("function : %s\n", __FUNCTION__);
+	dprintk("function : %s\n", __func__);
 
 	poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
 

+ 18 - 18
drivers/media/dvb/dvb-core/dvb_ca_en50221.c

@@ -250,7 +250,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
 	unsigned long timeout;
 	unsigned long start;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* loop until timeout elapsed */
 	start = jiffies;
@@ -263,7 +263,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
 
 		/* if we got the flags, it was successful! */
 		if (res & waitfor) {
-			dprintk("%s succeeded timeout:%lu\n", __FUNCTION__, jiffies - start);
+			dprintk("%s succeeded timeout:%lu\n", __func__, jiffies - start);
 			return 0;
 		}
 
@@ -276,7 +276,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
 		msleep(1);
 	}
 
-	dprintk("%s failed timeout:%lu\n", __FUNCTION__, jiffies - start);
+	dprintk("%s failed timeout:%lu\n", __func__, jiffies - start);
 
 	/* if we get here, we've timed out */
 	return -ETIMEDOUT;
@@ -297,7 +297,7 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
 	int buf_size;
 	u8 buf[2];
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* we'll be determining these during this function */
 	ca->slot_info[slot].da_irq_supported = 0;
@@ -549,7 +549,7 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
 {
 	int configoption;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* set the config option */
 	ca->pub->write_attribute_mem(ca->pub, slot,
@@ -587,7 +587,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
 	u8 buf[HOST_LINK_BUF_SIZE];
 	int i;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* check if we have space for a link buf in the rx_buffer */
 	if (ebuf == NULL) {
@@ -708,7 +708,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
 	int status;
 	int i;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 
 	// sanity check
@@ -785,7 +785,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
  */
 static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
 {
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	ca->pub->slot_shutdown(ca->pub, slot);
 	ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
@@ -892,7 +892,7 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
 static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
 {
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	ca->wakeup = 1;
 	mb();
@@ -964,7 +964,7 @@ static int dvb_ca_en50221_thread(void *data)
 	int pktcount;
 	void *rxbuf;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* choose the correct initial delay */
 	dvb_ca_en50221_thread_update_delay(ca);
@@ -1172,7 +1172,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
 	int err = 0;
 	int slot;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	switch (cmd) {
 	case CA_RESET:
@@ -1266,7 +1266,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
 	unsigned long timeout;
 	int written;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* Incoming packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
 	if (count < 2)
@@ -1401,7 +1401,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
 	int pktlen;
 	int dispose = 0;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* Outgoing packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
 	if (count < 2)
@@ -1490,7 +1490,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
 	int err;
 	int i;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	if (!try_module_get(ca->pub->owner))
 		return -EIO;
@@ -1534,7 +1534,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
 	struct dvb_ca_private *ca = dvbdev->priv;
 	int err;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* mark the CA device as closed */
 	ca->open = 0;
@@ -1564,7 +1564,7 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
 	int slot;
 	int result = 0;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
 		mask |= POLLIN;
@@ -1626,7 +1626,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 	struct dvb_ca_private *ca = NULL;
 	int i;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	if (slot_count < 1)
 		return -EINVAL;
@@ -1704,7 +1704,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
 	struct dvb_ca_private *ca = pubca->private;
 	int i;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	/* shutdown the thread if there was one */
 	kthread_stop(ca->thread);

+ 3 - 3
drivers/media/dvb/dvb-core/dvb_demux.c

@@ -368,7 +368,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
 #define DVR_FEED(f)							\
 	(((f)->type == DMX_TYPE_TS) &&					\
 	((f)->feed.ts.is_filtering) &&					\
-	(((f)->ts_type & (TS_PACKET|TS_PAYLOAD_ONLY)) == TS_PACKET))
+	(((f)->ts_type & (TS_PACKET | TS_DEMUX)) == TS_PACKET))
 
 static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
 {
@@ -553,7 +553,7 @@ static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
 	spin_lock_irq(&feed->demux->lock);
 	if (dvb_demux_feed_find(feed)) {
 		printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
-		       __FUNCTION__, feed->type, feed->state, feed->pid);
+		       __func__, feed->type, feed->state, feed->pid);
 		goto out;
 	}
 
@@ -567,7 +567,7 @@ static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
 	spin_lock_irq(&feed->demux->lock);
 	if (!(dvb_demux_feed_find(feed))) {
 		printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
-		       __FUNCTION__, feed->type, feed->state, feed->pid);
+		       __func__, feed->type, feed->state, feed->pid);
 		goto out;
 	}
 

+ 15 - 15
drivers/media/dvb/dvb-core/dvb_frontend.c

@@ -135,7 +135,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
 	struct dvb_frontend_event *e;
 	int wp;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (mutex_lock_interruptible (&events->mtx))
 		return;
@@ -171,7 +171,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	struct dvb_fe_events *events = &fepriv->events;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (events->overflow) {
 		events->overflow = 0;
@@ -237,7 +237,7 @@ static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepr
 {
 	int q2;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (locked)
 		(fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256;
@@ -329,7 +329,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
 
 	dprintk("%s: drift:%i inversion:%i auto_step:%i "
 		"auto_sub_step:%i started_auto_step:%i\n",
-		__FUNCTION__, fepriv->lnb_drift, fepriv->inversion,
+		__func__, fepriv->lnb_drift, fepriv->inversion,
 		fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
 
 	/* set the frontend itself */
@@ -511,7 +511,7 @@ static int dvb_frontend_thread(void *data)
 	fe_status_t s;
 	struct dvb_frontend_parameters *params;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 
 	fepriv->check_wrapped = 0;
 	fepriv->quality = 0;
@@ -597,7 +597,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
 {
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	fepriv->exit = 1;
 	mb();
@@ -665,7 +665,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	struct task_struct *fe_thread;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (fepriv->thread) {
 		if (!fepriv->exit)
@@ -763,7 +763,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	int err = -EOPNOTSUPP;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (fepriv->exit)
 		return -ENODEV;
@@ -895,7 +895,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
 			int i;
 			u8 last = 1;
 			if (dvb_frontend_debug)
-				printk("%s switch command: 0x%04lx\n", __FUNCTION__, cmd);
+				printk("%s switch command: 0x%04lx\n", __func__, cmd);
 			do_gettimeofday(&nexttime);
 			if (dvb_frontend_debug)
 				memcpy(&tv[0], &nexttime, sizeof(struct timeval));
@@ -919,7 +919,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
 			}
 			if (dvb_frontend_debug) {
 				printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
-					__FUNCTION__, fe->dvb->num);
+					__func__, fe->dvb->num);
 				for (i = 1; i < 10; i++)
 					printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
 			}
@@ -1037,7 +1037,7 @@ static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struc
 	struct dvb_frontend *fe = dvbdev->priv;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	poll_wait (file, &fepriv->events.wait_queue, wait);
 
@@ -1054,7 +1054,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	int ret;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
 		if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
@@ -1095,7 +1095,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	int ret;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if ((file->f_flags & O_ACCMODE) != O_RDONLY)
 		fepriv->release_jiffies = jiffies;
@@ -1135,7 +1135,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 		.kernel_ioctl = dvb_frontend_ioctl
 	};
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (mutex_lock_interruptible(&frontend_mutex))
 		return -ERESTARTSYS;
@@ -1169,7 +1169,7 @@ EXPORT_SYMBOL(dvb_register_frontend);
 int dvb_unregister_frontend(struct dvb_frontend* fe)
 {
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	mutex_lock(&frontend_mutex);
 	dvb_frontend_stop (fe);

+ 16 - 16
drivers/media/dvb/dvb-core/dvb_net.c

@@ -354,7 +354,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
 #ifdef ULE_DEBUG
 	/* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
 	static unsigned char ule_hist[100*TS_SZ];
-	static unsigned char *ule_where = ule_hist, ule_dump = 0;
+	static unsigned char *ule_where = ule_hist, ule_dump;
 #endif
 
 	/* For all TS cells in current buffer.
@@ -965,17 +965,17 @@ static int dvb_net_feed_start(struct net_device *dev)
 	struct dmx_demux *demux = priv->demux;
 	unsigned char *mac = (unsigned char *) dev->dev_addr;
 
-	dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
+	dprintk("%s: rx_mode %i\n", __func__, priv->rx_mode);
 	mutex_lock(&priv->mutex);
 	if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
-		printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
+		printk("%s: BUG %d\n", __func__, __LINE__);
 
 	priv->secfeed=NULL;
 	priv->secfilter=NULL;
 	priv->tsfeed = NULL;
 
 	if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
-		dprintk("%s: alloc secfeed\n", __FUNCTION__);
+		dprintk("%s: alloc secfeed\n", __func__);
 		ret=demux->allocate_section_feed(demux, &priv->secfeed,
 					 dvb_net_sec_callback);
 		if (ret<0) {
@@ -993,38 +993,38 @@ static int dvb_net_feed_start(struct net_device *dev)
 		}
 
 		if (priv->rx_mode != RX_MODE_PROMISC) {
-			dprintk("%s: set secfilter\n", __FUNCTION__);
+			dprintk("%s: set secfilter\n", __func__);
 			dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_normal);
 		}
 
 		switch (priv->rx_mode) {
 		case RX_MODE_MULTI:
 			for (i = 0; i < priv->multi_num; i++) {
-				dprintk("%s: set multi_secfilter[%d]\n", __FUNCTION__, i);
+				dprintk("%s: set multi_secfilter[%d]\n", __func__, i);
 				dvb_net_filter_sec_set(dev, &priv->multi_secfilter[i],
 						       priv->multi_macs[i], mask_normal);
 			}
 			break;
 		case RX_MODE_ALL_MULTI:
 			priv->multi_num=1;
-			dprintk("%s: set multi_secfilter[0]\n", __FUNCTION__);
+			dprintk("%s: set multi_secfilter[0]\n", __func__);
 			dvb_net_filter_sec_set(dev, &priv->multi_secfilter[0],
 					       mac_allmulti, mask_allmulti);
 			break;
 		case RX_MODE_PROMISC:
 			priv->multi_num=0;
-			dprintk("%s: set secfilter\n", __FUNCTION__);
+			dprintk("%s: set secfilter\n", __func__);
 			dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_promisc);
 			break;
 		}
 
-		dprintk("%s: start filtering\n", __FUNCTION__);
+		dprintk("%s: start filtering\n", __func__);
 		priv->secfeed->start_filtering(priv->secfeed);
 	} else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
 		struct timespec timeout = { 0, 10000000 }; // 10 msec
 
 		/* we have payloads encapsulated in TS */
-		dprintk("%s: alloc tsfeed\n", __FUNCTION__);
+		dprintk("%s: alloc tsfeed\n", __func__);
 		ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback);
 		if (ret < 0) {
 			printk("%s: could not allocate ts feed\n", dev->name);
@@ -1048,7 +1048,7 @@ static int dvb_net_feed_start(struct net_device *dev)
 			goto error;
 		}
 
-		dprintk("%s: start filtering\n", __FUNCTION__);
+		dprintk("%s: start filtering\n", __func__);
 		priv->tsfeed->start_filtering(priv->tsfeed);
 	} else
 		ret = -EINVAL;
@@ -1063,17 +1063,17 @@ static int dvb_net_feed_stop(struct net_device *dev)
 	struct dvb_net_priv *priv = dev->priv;
 	int i, ret = 0;
 
-	dprintk("%s\n", __FUNCTION__);
+	dprintk("%s\n", __func__);
 	mutex_lock(&priv->mutex);
 	if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
 		if (priv->secfeed) {
 			if (priv->secfeed->is_filtering) {
-				dprintk("%s: stop secfeed\n", __FUNCTION__);
+				dprintk("%s: stop secfeed\n", __func__);
 				priv->secfeed->stop_filtering(priv->secfeed);
 			}
 
 			if (priv->secfilter) {
-				dprintk("%s: release secfilter\n", __FUNCTION__);
+				dprintk("%s: release secfilter\n", __func__);
 				priv->secfeed->release_filter(priv->secfeed,
 							      priv->secfilter);
 				priv->secfilter=NULL;
@@ -1082,7 +1082,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
 			for (i=0; i<priv->multi_num; i++) {
 				if (priv->multi_secfilter[i]) {
 					dprintk("%s: release multi_filter[%d]\n",
-						__FUNCTION__, i);
+						__func__, i);
 					priv->secfeed->release_filter(priv->secfeed,
 								      priv->multi_secfilter[i]);
 					priv->multi_secfilter[i] = NULL;
@@ -1096,7 +1096,7 @@ static int dvb_net_feed_stop(struct net_device *dev)
 	} else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
 		if (priv->tsfeed) {
 			if (priv->tsfeed->is_filtering) {
-				dprintk("%s: stop tsfeed\n", __FUNCTION__);
+				dprintk("%s: stop tsfeed\n", __func__);
 				priv->tsfeed->stop_filtering(priv->tsfeed);
 			}
 			priv->demux->release_ts_feed(priv->demux, priv->tsfeed);

+ 5 - 1
drivers/media/dvb/dvb-core/dvb_ringbuffer.c

@@ -90,7 +90,11 @@ void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
 	rbuf->error = 0;
 }
 
-
+void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
+{
+	rbuf->pread = rbuf->pwrite = 0;
+	rbuf->error = 0;
+}
 
 void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
 {

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

@@ -69,6 +69,7 @@ struct dvb_ringbuffer {
 **     to lock read or write operations.
 **     Two or more readers must be locked against each other.
 **     Flushing the buffer counts as a read operation.
+**     Resetting the buffer counts as a read and write operation.
 **     Two or more writers must be locked against each other.
 */
 
@@ -85,6 +86,13 @@ extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf);
 extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
 
 
+/*
+** Reset the read and write pointers to zero and flush the buffer
+** This counts as a read and write operation
+*/
+extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf);
+
+
 /* read routines & macros */
 /* ---------------------- */
 /* flush buffer */

+ 34 - 13
drivers/media/dvb/dvb-core/dvbdev.c

@@ -49,7 +49,6 @@ static const char * const dnames[] = {
 	"net", "osd"
 };
 
-#define DVB_MAX_ADAPTERS	8
 #define DVB_MAX_IDS		4
 #define nums2minor(num,type,id)	((num << 6) | (id << 4) | type)
 #define MAX_DVB_MINORS		(DVB_MAX_ADAPTERS*64)
@@ -97,7 +96,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
 }
 
 
-static struct file_operations dvb_device_fops =
+static const struct file_operations dvb_device_fops =
 {
 	.owner =	THIS_MODULE,
 	.open =		dvb_device_open,
@@ -196,7 +195,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 	if ((id = dvbdev_get_free_id (adap, type)) < 0){
 		mutex_unlock(&dvbdev_register_lock);
 		*pdvbdev = NULL;
-		printk(KERN_ERR "%s: couldn't find free device id\n", __FUNCTION__);
+		printk(KERN_ERR "%s: couldn't find free device id\n", __func__);
 		return -ENFILE;
 	}
 
@@ -235,7 +234,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 			       "dvb%d.%s%d", adap->num, dnames[type], id);
 	if (IS_ERR(clsdev)) {
 		printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
-		       __FUNCTION__, adap->num, dnames[type], id, PTR_ERR(clsdev));
+		       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
 		return PTR_ERR(clsdev);
 	}
 
@@ -262,18 +261,25 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
 }
 EXPORT_SYMBOL(dvb_unregister_device);
 
+static int dvbdev_check_free_adapter_num(int num)
+{
+	struct list_head *entry;
+	list_for_each(entry, &dvb_adapter_list) {
+		struct dvb_adapter *adap;
+		adap = list_entry(entry, struct dvb_adapter, list_head);
+		if (adap->num == num)
+			return 0;
+	}
+	return 1;
+}
 
 static int dvbdev_get_free_adapter_num (void)
 {
 	int num = 0;
 
 	while (num < DVB_MAX_ADAPTERS) {
-		struct dvb_adapter *adap;
-		list_for_each_entry(adap, &dvb_adapter_list, list_head)
-			if (adap->num == num)
-				goto skip;
-		return num;
-skip:
+		if (dvbdev_check_free_adapter_num(num))
+			return num;
 		num++;
 	}
 
@@ -281,13 +287,28 @@ skip:
 }
 
 
-int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module, struct device *device)
+int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
+			 struct module *module, struct device *device,
+			 short *adapter_nums)
 {
-	int num;
+	int i, num;
 
 	mutex_lock(&dvbdev_register_lock);
 
-	if ((num = dvbdev_get_free_adapter_num ()) < 0) {
+	for (i = 0; i < DVB_MAX_ADAPTERS; ++i) {
+		num = adapter_nums[i];
+		if (num >= 0  &&  num < DVB_MAX_ADAPTERS) {
+		/* use the one the driver asked for */
+			if (dvbdev_check_free_adapter_num(num))
+				break;
+		} else {
+			num = dvbdev_get_free_adapter_num();
+			break;
+		}
+		num = -1;
+	}
+
+	if (num < 0) {
 		mutex_unlock(&dvbdev_register_lock);
 		return -ENFILE;
 	}

+ 12 - 1
drivers/media/dvb/dvb-core/dvbdev.h

@@ -31,6 +31,10 @@
 
 #define DVB_MAJOR 212
 
+#define DVB_MAX_ADAPTERS 8
+
+#define DVB_UNSET (-1)
+
 #define DVB_DEVICE_VIDEO      0
 #define DVB_DEVICE_AUDIO      1
 #define DVB_DEVICE_SEC        2
@@ -41,6 +45,11 @@
 #define DVB_DEVICE_NET        7
 #define DVB_DEVICE_OSD        8
 
+#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \
+	static short adapter_nr[] = \
+		{[0 ... (DVB_MAX_ADAPTERS - 1)] = DVB_UNSET }; \
+	module_param_array(adapter_nr, short, NULL, 0444); \
+	MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
 
 struct dvb_adapter {
 	int num;
@@ -78,7 +87,9 @@ struct dvb_device {
 };
 
 
-extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module, struct device *device);
+extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
+				struct module *module, struct device *device,
+				short *adapter_nums);
 extern int dvb_unregister_adapter (struct dvb_adapter *adap);
 
 extern int dvb_register_device (struct dvb_adapter *adap,

+ 1 - 0
drivers/media/dvb/dvb-usb/Kconfig

@@ -105,6 +105,7 @@ config DVB_USB_CXUSB
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+	select TUNER_SIMPLE if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the Conexant USB2.0 hybrid reference design.
 	  Currently, only DVB and ATSC modes are supported, analog mode

+ 5 - 1
drivers/media/dvb/dvb-usb/a800.c

@@ -18,6 +18,9 @@
 static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 #define deb_rc(args...)   dprintk(debug,0x01,args)
 
 static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
@@ -94,7 +97,8 @@ static struct dvb_usb_device_properties a800_properties;
 static int a800_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE,NULL);
+	return dvb_usb_device_init(intf, &a800_properties,
+				   THIS_MODULE, NULL, adapter_nr);
 }
 
 /* do not change the order of the ID table */

+ 4 - 1
drivers/media/dvb/dvb-usb/af9005.c

@@ -39,6 +39,8 @@ int dvb_usb_af9005_dump_eeprom = 0;
 module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
 MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 /* remote control decoder */
 int (*rc_decode) (struct dvb_usb_device * d, u8 * data, int len, u32 * event,
 		  int *state);
@@ -1020,7 +1022,8 @@ static struct dvb_usb_device_properties af9005_properties;
 static int af9005_usb_probe(struct usb_interface *intf,
 			    const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf, &af9005_properties, THIS_MODULE, NULL);
+	return dvb_usb_device_init(intf, &af9005_properties,
+				   THIS_MODULE, NULL, adapter_nr);
 }
 
 static struct usb_device_id af9005_usb_table[] = {

+ 5 - 1
drivers/media/dvb/dvb-usb/au6610.c

@@ -19,6 +19,8 @@ static int dvb_usb_au6610_debug;
 module_param_named(debug, dvb_usb_au6610_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
 			  u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
 {
@@ -163,7 +165,9 @@ static int au6610_probe(struct usb_interface *intf,
 	if (intf->num_altsetting < AU6610_ALTSETTING_COUNT)
 		return -ENODEV;
 
-	if ((ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d)) == 0) {
+	ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d,
+				  adapter_nr);
+	if (ret == 0) {
 		alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING);
 
 		if (alt == NULL) {

+ 32 - 19
drivers/media/dvb/dvb-usb/cxusb.c

@@ -23,6 +23,8 @@
  *
  * see Documentation/dvb/README.dvb-usb for more information
  */
+#include <media/tuner.h>
+
 #include "cxusb.h"
 
 #include "cx22702.h"
@@ -31,12 +33,15 @@
 #include "mt352_priv.h"
 #include "zl10353.h"
 #include "tuner-xc2028.h"
-#include "tuner-xc2028-types.h"
+#include "tuner-simple.h"
 
 /* debug */
 static int dvb_usb_cxusb_debug;
 module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 #define deb_info(args...)   dprintk(dvb_usb_cxusb_debug,0x01,args)
 #define deb_i2c(args...)    if (d->udev->descriptor.idVendor == USB_VID_MEDION) \
 				dprintk(dvb_usb_cxusb_debug,0x01,args)
@@ -450,8 +455,9 @@ static struct mt352_config cxusb_mt352_xc3028_config = {
 /* Callbacks for DVB USB */
 static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap,
-		   DVB_PLL_FMD1216ME);
+	dvb_attach(simple_tuner_attach, adap->fe,
+		   &adap->dev->i2c_adap, 0x61,
+		   TUNER_PHILIPS_FMD1216ME_MK3);
 	return 0;
 }
 
@@ -477,8 +483,8 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
 
 static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap,
-		   DVB_PLL_LG_TDVS_H06XF);
+	dvb_attach(simple_tuner_attach, adap->fe,
+		   &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
 	return 0;
 }
 
@@ -488,14 +494,14 @@ static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg)
 
 	switch (command) {
 	case XC2028_TUNER_RESET:
-		deb_info("%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg);
+		deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
 		cxusb_bluebird_gpio_pulse(d, 0x01, 1);
 		break;
 	case XC2028_RESET_CLK:
-		deb_info("%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg);
+		deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
 		break;
 	default:
-		deb_info("%s: unknown command %d, arg %d\n", __FUNCTION__,
+		deb_info("%s: unknown command %d, arg %d\n", __func__,
 			 command, arg);
 		return -EINVAL;
 	}
@@ -509,13 +515,12 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
 	struct xc2028_config	  cfg = {
 		.i2c_adap  = &adap->dev->i2c_adap,
 		.i2c_addr  = 0x61,
-		.video_dev = adap->dev,
 		.callback  = dvico_bluebird_xc2028_callback,
 	};
 	static struct xc2028_ctrl ctl = {
 		.fname       = "xc3028-dvico-au-01.fw",
 		.max_len     = 64,
-		.scode_table = ZARLINK456,
+		.scode_table = XC3028_FE_ZARLINK456,
 	};
 
 	fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
@@ -720,16 +725,24 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
 static int cxusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
-	if (dvb_usb_device_init(intf,&cxusb_medion_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&cxusb_bluebird_lgh064f_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&cxusb_bluebird_dee1601_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&cxusb_bluebird_lgz201_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&cxusb_bluebird_dtt7579_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&cxusb_bluebird_dualdig4_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&cxusb_bluebird_nano2_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&cxusb_bluebird_nano2_needsfirmware_properties,THIS_MODULE,NULL) == 0) {
+	if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf,
+				&cxusb_bluebird_nano2_needsfirmware_properties,
+				     THIS_MODULE, NULL, adapter_nr))
 		return 0;
-	}
 
 	return -EINVAL;
 }

+ 4 - 0
drivers/media/dvb/dvb-usb/dib0700.h

@@ -37,6 +37,7 @@ struct dib0700_state {
 	u8 channel_state;
 	u16 mt2060_if1[2];
 	u8 rc_toggle;
+	u8 rc_counter;
 	u8 is_dib7000pc;
 };
 
@@ -44,12 +45,15 @@ extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8
 extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
 extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
 extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
+extern int dib0700_rc_setup(struct dvb_usb_device *d);
 extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
 extern struct i2c_algorithm dib0700_i2c_algo;
 extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
 			struct dvb_usb_device_description **desc, int *cold);
 
 extern int dib0700_device_count;
+extern int dvb_usb_dib0700_ir_proto;
 extern struct dvb_usb_device_properties dib0700_devices[];
 extern struct usb_device_id dib0700_usb_id_table[];
+
 #endif

+ 6 - 3
drivers/media/dvb/dvb-usb/dib0700_core.c

@@ -13,10 +13,12 @@ int dvb_usb_dib0700_debug;
 module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
 
-static int dvb_usb_dib0700_ir_proto = 1;
+int dvb_usb_dib0700_ir_proto = 1;
 module_param(dvb_usb_dib0700_ir_proto, int, 0644);
 MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 /* expecting rx buffer: request data[0] data[1] ... data[2] */
 static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
 {
@@ -261,7 +263,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 	return dib0700_ctrl_wr(adap->dev, b, 4);
 }
 
-static int dib0700_rc_setup(struct dvb_usb_device *d)
+int dib0700_rc_setup(struct dvb_usb_device *d)
 {
 	u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
 	int i = dib0700_ctrl_wr(d, rc_setup, 3);
@@ -279,7 +281,8 @@ static int dib0700_probe(struct usb_interface *intf,
 	struct dvb_usb_device *dev;
 
 	for (i = 0; i < dib0700_device_count; i++)
-		if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, &dev) == 0)
+		if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
+					&dev, adapter_nr) == 0)
 		{
 			dib0700_rc_setup(dev);
 			return 0;

+ 293 - 32
drivers/media/dvb/dvb-usb/dib0700_devices.c

@@ -13,6 +13,7 @@
 #include "dib7000p.h"
 #include "mt2060.h"
 #include "mt2266.h"
+#include "tuner-xc2028.h"
 #include "dib0070.h"
 
 static int force_lna_activation;
@@ -297,10 +298,156 @@ static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
 		&stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;;
 }
 
+/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
+struct dibx000_agc_config xc3028_agc_config = {
+	BAND_VHF | BAND_UHF,       /* band_caps */
+
+	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
+	 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+	 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
+	(0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
+	(3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
+
+	712,	/* inv_gain */
+	21,	/* time_stabiliz */
+
+	0,	/* alpha_level */
+	118,	/* thlock */
+
+	0,	/* wbd_inv */
+	2867,	/* wbd_ref */
+	0,	/* wbd_sel */
+	2,	/* wbd_alpha */
+
+	0,	/* agc1_max */
+	0,	/* agc1_min */
+	39718,	/* agc2_max */
+	9930,	/* agc2_min */
+	0,	/* agc1_pt1 */
+	0,	/* agc1_pt2 */
+	0,	/* agc1_pt3 */
+	0,	/* agc1_slope1 */
+	0,	/* agc1_slope2 */
+	0,	/* agc2_pt1 */
+	128,	/* agc2_pt2 */
+	29,	/* agc2_slope1 */
+	29,	/* agc2_slope2 */
+
+	17,	/* alpha_mant */
+	27,	/* alpha_exp */
+	23,	/* beta_mant */
+	51,	/* beta_exp */
+
+	1,	/* perform_agc_softsplit */
+};
+
+/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
+struct dibx000_bandwidth_config xc3028_bw_config = {
+	60000, 30000, /* internal, sampling */
+	1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
+	0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
+			  modulo */
+	(3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
+	(1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
+	20452225, /* timf */
+	30000000, /* xtal_hz */
+};
+
+static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
+	.output_mpeg2_in_188_bytes = 1,
+	.tuner_is_baseband = 1,
+
+	.agc_config_count = 1,
+	.agc = &xc3028_agc_config,
+	.bw  = &xc3028_bw_config,
+
+	.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+	.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+	.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+};
+
+static int stk7700ph_xc3028_callback(void *ptr, int command, int arg)
+{
+	struct dvb_usb_adapter *adap = ptr;
+
+	switch (command) {
+	case XC2028_TUNER_RESET:
+		/* Send the tuner in then out of reset */
+		dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10);
+		dib7000p_set_gpio(adap->fe, 8, 0, 1);
+		break;
+	case XC2028_RESET_CLK:
+		break;
+	default:
+		err("%s: unknown command %d, arg %d\n", __func__,
+			command, arg);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
+	.fname = XC2028_DEFAULT_FIRMWARE,
+	.max_len = 64,
+	.demod = XC3028_FE_DIBCOM52,
+};
+
+static struct xc2028_config stk7700ph_xc3028_config = {
+	.i2c_addr = 0x61,
+	.callback = stk7700ph_xc3028_callback,
+	.ctrl = &stk7700ph_xc3028_ctrl,
+};
+
+static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
+
+	if (desc->idVendor  == USB_VID_PINNACLE &&
+	    desc->idProduct == USB_PID_PINNACLE_EXPRESSCARD_320CX)
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+	else
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+	msleep(10);
+
+	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+		&stk7700ph_dib7700_xc3028_config);
+
+	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+		&stk7700ph_dib7700_xc3028_config);
+
+	return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct i2c_adapter *tun_i2c;
+
+	tun_i2c = dib7000p_get_i2c_master(adap->fe,
+		DIBX000_I2C_INTERFACE_TUNER, 1);
+
+	stk7700ph_xc3028_config.i2c_adap = tun_i2c;
+	stk7700ph_xc3028_config.video_dev = adap;
+
+	return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
+		== NULL ? -ENODEV : 0;
+}
+
 #define DEFAULT_RC_INTERVAL 150
 
 static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
 
+/* Number of keypresses to ignore before start repeating */
+#define RC_REPEAT_DELAY 2
+
 static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
 	u8 key[4];
@@ -314,18 +461,67 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 		err("RC Query Failed");
 		return -1;
 	}
+
+	/* losing half of KEY_0 events from Philipps rc5 remotes.. */
 	if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
-	if (key[3-1]!=st->rc_toggle) {
+
+	/* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]);  */
+
+	dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
+
+	switch (dvb_usb_dib0700_ir_proto) {
+	case 0: {
+		/* NEC protocol sends repeat code as 0 0 0 FF */
+		if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
+		    (key[3] == 0xFF)) {
+			st->rc_counter++;
+			if (st->rc_counter > RC_REPEAT_DELAY) {
+				*event = d->last_event;
+				*state = REMOTE_KEY_PRESSED;
+				st->rc_counter = RC_REPEAT_DELAY;
+			}
+			return 0;
+		}
 		for (i=0;i<d->props.rc_key_map_size; i++) {
 			if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
+				st->rc_counter = 0;
+				*event = keymap[i].event;
+				*state = REMOTE_KEY_PRESSED;
+				d->last_event = keymap[i].event;
+				return 0;
+			}
+		}
+		break;
+	}
+	default: {
+		/* RC-5 protocol changes toggle bit on new keypress */
+		for (i = 0; i < d->props.rc_key_map_size; i++) {
+			if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
+				if (d->last_event == keymap[i].event &&
+					key[3-1] == st->rc_toggle) {
+					st->rc_counter++;
+					/* prevents unwanted double hits */
+					if (st->rc_counter > RC_REPEAT_DELAY) {
+						*event = d->last_event;
+						*state = REMOTE_KEY_PRESSED;
+						st->rc_counter = RC_REPEAT_DELAY;
+					}
+
+					return 0;
+				}
+				st->rc_counter = 0;
 				*event = keymap[i].event;
 				*state = REMOTE_KEY_PRESSED;
-				st->rc_toggle=key[3-1];
+				st->rc_toggle = key[3-1];
+				d->last_event = keymap[i].event;
 				return 0;
 			}
 		}
-		err("Unknown remote controller key : %2X %2X",(int)key[3-2],(int)key[3-3]);
+		break;
 	}
+	}
+	err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]);
+	d->last_event = 0;
 	return 0;
 }
 
@@ -794,6 +990,10 @@ static struct dib7000p_config dib7070p_dib7000p_config = {
 /* STK7070P */
 static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
 {
+	if (adap->dev->udev->descriptor.idVendor  == USB_VID_PINNACLE &&
+	adap->dev->udev->descriptor.idProduct == USB_PID_PINNACLE_PCTV72E)
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+	else
 	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
 	msleep(10);
 	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
@@ -808,9 +1008,11 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
 	msleep(10);
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
-	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &dib7070p_dib7000p_config);
+	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+		&dib7070p_dib7000p_config);
 
-	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config);
+	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+		&dib7070p_dib7000p_config);
 	return adap->fe == NULL ? -ENODEV : 0;
 }
 
@@ -878,34 +1080,43 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
 /* DVB-USB and USB stuff follows */
 struct usb_device_id dib0700_usb_id_table[] = {
 /* 0 */	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
-		{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
-
-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
 /* 5 */	{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
-		{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
-		{ USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
-		{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
+	{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
+	{ USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
+	{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
 /* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
-		{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
-		{ USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
-		{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
+	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
+	{ USB_DEVICE(USB_VID_TERRATEC,
+			USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
 /* 15 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070P) },
-		{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
-		{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
-		{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
-		{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
+	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
+	{ USB_DEVICE(USB_VID_PINNACLE,
+			USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
+	{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
 /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
-		{ USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
-		{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
-		{ USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
-		{ USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
-/* 25 */	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
-		{ 0 }		/* Terminating entry */
+	{ USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
+	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
+	{ USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
+	{ USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
+/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
+	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
+	{ USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
+	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_EXPRESSCARD_320CX) },
+	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV72E) },
+/* 30 */{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV73E) },
+	{ USB_DEVICE(USB_VID_YUAN,	USB_PID_YUAN_EC372S) },
+	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
+	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_T_XXS) },
+	{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
+	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
 
@@ -969,7 +1180,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 				{ NULL },
 			},
 			{   "Leadtek Winfast DTV Dongle (STK7700P based)",
-				{ &dib0700_usb_id_table[8], NULL },
+				{ &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
 				{ NULL },
 			},
 			{   "AVerMedia AVerTV DVB-T Express",
@@ -1069,12 +1280,16 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			},
 		},
 
-		.num_device_descs = 1,
+		.num_device_descs = 2,
 		.devices = {
 			{   "ASUS My Cinema U3000 Mini DVBT Tuner",
 				{ &dib0700_usb_id_table[23], NULL },
 				{ NULL },
 			},
+			{   "Yuan EC372S",
+				{ &dib0700_usb_id_table[31], NULL },
+				{ NULL },
+			}
 		}
 	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
 
@@ -1090,7 +1305,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			},
 		},
 
-		.num_device_descs = 6,
+		.num_device_descs = 9,
 		.devices = {
 			{   "DiBcom STK7070P reference design",
 				{ &dib0700_usb_id_table[15], NULL },
@@ -1116,6 +1331,18 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 				{ &dib0700_usb_id_table[26], NULL },
 				{ NULL },
 			},
+			{   "Pinnacle PCTV 72e",
+				{ &dib0700_usb_id_table[29], NULL },
+				{ NULL },
+			},
+			{   "Pinnacle PCTV 73e",
+				{ &dib0700_usb_id_table[30], NULL },
+				{ NULL },
+			},
+			{   "Terratec Cinergy T USB XXS",
+				{ &dib0700_usb_id_table[33], NULL },
+				{ NULL },
+			},
 		},
 
 		.rc_interval      = DEFAULT_RC_INTERVAL,
@@ -1155,6 +1382,40 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 				{ NULL },
 			}
 		}
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.frontend_attach  = stk7700ph_frontend_attach,
+				.tuner_attach     = stk7700ph_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+				.size_of_priv = sizeof(struct
+						dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 3,
+		.devices = {
+			{   "Terratec Cinergy HT USB XE",
+				{ &dib0700_usb_id_table[27], NULL },
+				{ NULL },
+			},
+			{   "Pinnacle Expresscard 320cx",
+				{ &dib0700_usb_id_table[28], NULL },
+				{ NULL },
+			},
+			{   "Terratec Cinergy HT Express",
+				{ &dib0700_usb_id_table[32], NULL },
+				{ NULL },
+			},
+		},
+		.rc_interval      = DEFAULT_RC_INTERVAL,
+		.rc_key_map       = dib0700_rc_keys,
+		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+		.rc_query         = dib0700_rc_query
 	},
 };
 

+ 10 - 4
drivers/media/dvb/dvb-usb/dibusb-mb.c

@@ -14,6 +14,8 @@
  */
 #include "dibusb.h"
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
 {
 	struct dvb_usb_adapter *adap = fe->dvb->priv;
@@ -107,10 +109,14 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties;
 static int dibusb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&artec_t1_usb2_properties,THIS_MODULE,NULL) == 0)
+	if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,
+				     THIS_MODULE, NULL, adapter_nr))
 		return 0;
 
 	return -EINVAL;

+ 4 - 1
drivers/media/dvb/dvb-usb/dibusb-mc.c

@@ -14,13 +14,16 @@
  */
 #include "dibusb.h"
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 /* USB Driver stuff */
 static struct dvb_usb_device_properties dibusb_mc_properties;
 
 static int dibusb_mc_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE,NULL);
+	return dvb_usb_device_init(intf, &dibusb_mc_properties, THIS_MODULE,
+				   NULL, adapter_nr);
 }
 
 /* do not change the order of the ID table */

+ 6 - 2
drivers/media/dvb/dvb-usb/digitv.c

@@ -20,6 +20,9 @@
 static int dvb_usb_digitv_debug;
 module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 #define deb_rc(args...)   dprintk(dvb_usb_digitv_debug,0x01,args)
 
 static int digitv_ctrl_msg(struct dvb_usb_device *d,
@@ -256,8 +259,9 @@ static int digitv_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
 	struct dvb_usb_device *d;
-	int ret;
-	if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) {
+	int ret = dvb_usb_device_init(intf, &digitv_properties, THIS_MODULE, &d,
+				      adapter_nr);
+	if (ret == 0) {
 		u8 b[4] = { 0 };
 
 		if (d != NULL) { /* do that only when the firmware is loaded */

+ 12 - 5
drivers/media/dvb/dvb-usb/dtt200u.c

@@ -18,6 +18,8 @@ int dvb_usb_dtt200u_debug;
 module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
 	u8 b = SET_INIT;
@@ -101,11 +103,16 @@ static struct dvb_usb_device_properties wt220u_miglia_properties;
 static int dtt200u_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&wt220u_fc_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0 ||
-		dvb_usb_device_init(intf,&wt220u_miglia_properties,THIS_MODULE,NULL) == 0)
+	if (0 == dvb_usb_device_init(intf, &dtt200u_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &wt220u_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &wt220u_fc_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &wt220u_miglia_properties,
+				     THIS_MODULE, NULL, adapter_nr))
 		return 0;
 
 	return -ENODEV;

+ 2 - 1
drivers/media/dvb/dvb-usb/dvb-usb-common.h

@@ -40,7 +40,8 @@ extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap);
 extern int dvb_usb_i2c_init(struct dvb_usb_device *);
 extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
 
-extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap);
+extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap,
+				    short *adapter_nums);
 extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap);
 extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap);
 extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap);

+ 5 - 4
drivers/media/dvb/dvb-usb/dvb-usb-dvb.c

@@ -77,12 +77,13 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
 	return dvb_usb_ctrl_feed(dvbdmxfeed,0);
 }
 
-int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap)
+int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
 {
-	int ret;
+	int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
+				       adap->dev->owner, &adap->dev->udev->dev,
+				       adapter_nums);
 
-	if ((ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
-			adap->dev->owner, &adap->dev->udev->dev)) < 0) {
+	if (ret < 0) {
 		deb_info("dvb_register_adapter failed: error %d", ret);
 		goto err;
 	}

+ 11 - 2
drivers/media/dvb/dvb-usb/dvb-usb-ids.h

@@ -40,14 +40,15 @@
 #define USB_VID_MSI				0x0db0
 #define USB_VID_OPERA1				0x695c
 #define USB_VID_PINNACLE			0x2304
+#define USB_VID_TECHNOTREND			0x0b48
 #define USB_VID_TERRATEC			0x0ccd
 #define USB_VID_VISIONPLUS			0x13d3
 #define USB_VID_TWINHAN				0x1822
 #define USB_VID_ULTIMA_ELECTRONIC		0x05d8
 #define USB_VID_UNIWILL				0x1584
 #define USB_VID_WIDEVIEW			0x14aa
-/* dom : pour gigabyte u7000 */
 #define USB_VID_GIGABYTE			0x1044
+#define USB_VID_YUAN				0x1164
 
 
 /* Product IDs */
@@ -134,10 +135,17 @@
 #define USB_PID_AVERMEDIA_EXPRESS			0xb568
 #define USB_PID_AVERMEDIA_VOLAR				0xa807
 #define USB_PID_AVERMEDIA_VOLAR_2			0xb808
+#define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
+#define USB_PID_TERRATEC_CINERGY_HT_USB_XE		0x0058
+#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS		0x0060
+#define USB_PID_TERRATEC_CINERGY_T_XXS			0x0078
+#define USB_PID_PINNACLE_EXPRESSCARD_320CX		0x022e
 #define USB_PID_PINNACLE_PCTV2000E			0x022c
 #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH		0x0228
 #define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T	0x0229
+#define USB_PID_PINNACLE_PCTV72E			0x0236
+#define USB_PID_PINNACLE_PCTV73E			0x0237
 #define USB_PID_PCTV_200E				0x020e
 #define USB_PID_PCTV_400E				0x020f
 #define USB_PID_PCTV_450E				0x0222
@@ -172,6 +180,7 @@
 #define USB_PID_WINFAST_DTV_DONGLE_COLD			0x6025
 #define USB_PID_WINFAST_DTV_DONGLE_WARM			0x6026
 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P		0x6f00
+#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2		0x6f01
 #define USB_PID_GENPIX_8PSK_REV_1_COLD			0x0200
 #define USB_PID_GENPIX_8PSK_REV_1_WARM			0x0201
 #define USB_PID_GENPIX_8PSK_REV_2			0x0202
@@ -183,9 +192,9 @@
 #define USB_PID_OPERA1_WARM				0x3829
 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD		0x0514
 #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM		0x0513
-/* dom pour gigabyte u7000 */
 #define USB_PID_GIGABYTE_U7000				0x7001
 #define USB_PID_ASUS_U3000				0x171f
 #define USB_PID_ASUS_U3100				0x173f
+#define USB_PID_YUAN_EC372S				0x1edc
 
 #endif

+ 9 - 7
drivers/media/dvb/dvb-usb/dvb-usb-init.c

@@ -26,7 +26,7 @@ static int dvb_usb_force_pid_filter_usage;
 module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
 MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
 
-static int dvb_usb_adapter_init(struct dvb_usb_device *d)
+static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
 {
 	struct dvb_usb_adapter *adap;
 	int ret,n;
@@ -72,7 +72,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d)
 		}
 
 		if ((ret = dvb_usb_adapter_stream_init(adap)) ||
-			(ret = dvb_usb_adapter_dvb_init(adap)) ||
+			(ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
 			(ret = dvb_usb_adapter_frontend_init(adap))) {
 			return ret;
 		}
@@ -122,7 +122,7 @@ static int dvb_usb_exit(struct dvb_usb_device *d)
 	return 0;
 }
 
-static int dvb_usb_init(struct dvb_usb_device *d)
+static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
 {
 	int ret = 0;
 
@@ -143,7 +143,7 @@ static int dvb_usb_init(struct dvb_usb_device *d)
 	dvb_usb_device_power_ctrl(d, 1);
 
 	if ((ret = dvb_usb_i2c_init(d)) ||
-		(ret = dvb_usb_adapter_init(d))) {
+		(ret = dvb_usb_adapter_init(d, adapter_nums))) {
 		dvb_usb_exit(d);
 		return ret;
 	}
@@ -213,8 +213,10 @@ int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
 /*
  * USB
  */
-int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_device_properties
-		*props, struct module *owner,struct dvb_usb_device **du)
+int dvb_usb_device_init(struct usb_interface *intf,
+			struct dvb_usb_device_properties *props,
+			struct module *owner, struct dvb_usb_device **du,
+			short *adapter_nums)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct dvb_usb_device *d = NULL;
@@ -254,7 +256,7 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_device_proper
 	if (du != NULL)
 		*du = d;
 
-	ret = dvb_usb_init(d);
+	ret = dvb_usb_init(d, adapter_nums);
 
 	if (ret == 0)
 		info("%s successfully initialized and connected.",desc->name);

+ 4 - 1
drivers/media/dvb/dvb-usb/dvb-usb.h

@@ -372,7 +372,10 @@ struct dvb_usb_device {
 	void *priv;
 };
 
-extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_device_properties *, struct module *, struct dvb_usb_device **);
+extern int dvb_usb_device_init(struct usb_interface *,
+			       struct dvb_usb_device_properties *,
+			       struct module *, struct dvb_usb_device **,
+			       short *adapter_nums);
 extern void dvb_usb_device_exit(struct usb_interface *);
 
 /* the generic read/write method for device control */

+ 5 - 1
drivers/media/dvb/dvb-usb/gl861.c

@@ -16,6 +16,8 @@ static int dvb_usb_gl861_debug;
 module_param_named(debug,dvb_usb_gl861_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
 			 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
 {
@@ -140,7 +142,9 @@ static int gl861_probe(struct usb_interface *intf,
 	if (intf->num_altsetting < 2)
 		return -ENODEV;
 
-	if ((ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d)) == 0) {
+	ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d,
+				  adapter_nr);
+	if (ret == 0) {
 		alt = usb_altnum_to_altsetting(intf, 0);
 
 		if (alt == NULL) {

+ 2 - 2
drivers/media/dvb/dvb-usb/gp8psk-fe.c

@@ -152,7 +152,7 @@ static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
 {
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 
 	if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
 			m->msg, m->msg_len)) {
@@ -167,7 +167,7 @@ static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
 	struct gp8psk_fe_state *st = fe->demodulator_priv;
 	u8 cmd;
 
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 
 	/* These commands are certainly wrong */
 	cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;

+ 4 - 1
drivers/media/dvb/dvb-usb/gp8psk.c

@@ -22,6 +22,8 @@ int dvb_usb_gp8psk_debug;
 module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
 {
 	int ret = 0,try = 0;
@@ -190,7 +192,8 @@ static int gp8psk_usb_probe(struct usb_interface *intf,
 {
 	int ret;
 	struct usb_device *udev = interface_to_usbdev(intf);
-	ret =  dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
+	ret = dvb_usb_device_init(intf, &gp8psk_properties,
+				  THIS_MODULE, NULL, adapter_nr);
 	if (ret == 0) {
 		info("found Genpix USB device pID = %x (hex)",
 			le16_to_cpu(udev->descriptor.idProduct));

+ 20 - 14
drivers/media/dvb/dvb-usb/m920x.c

@@ -22,6 +22,8 @@ static int dvb_usb_m920x_debug;
 module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);
 
 static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
@@ -477,7 +479,7 @@ static struct qt1010_config m920x_qt1010_config = {
 /* Callbacks for DVB USB */
 static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	deb("%s\n",__FUNCTION__);
+	deb("%s\n",__func__);
 
 	if ((adap->fe = dvb_attach(mt352_attach,
 				   &m920x_mt352_config,
@@ -489,7 +491,7 @@ static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
 
 static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	deb("%s\n",__FUNCTION__);
+	deb("%s\n",__func__);
 
 	if ((adap->fe = dvb_attach(tda10046_attach,
 				   &m920x_tda10046_08_config,
@@ -501,7 +503,7 @@ static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
 
 static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	deb("%s\n",__FUNCTION__);
+	deb("%s\n",__func__);
 
 	if ((adap->fe = dvb_attach(tda10046_attach,
 				   &m920x_tda10046_0b_config,
@@ -513,7 +515,7 @@ static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
 
 static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	deb("%s\n",__FUNCTION__);
+	deb("%s\n",__func__);
 
 	if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
 		return -ENODEV;
@@ -523,7 +525,7 @@ static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
 
 static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	deb("%s\n",__FUNCTION__);
+	deb("%s\n",__func__);
 
 	if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
 		return -ENODEV;
@@ -533,7 +535,7 @@ static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
 
 static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
 {
-	deb("%s\n",__FUNCTION__);
+	deb("%s\n",__func__);
 
 	if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
 		return -ENODEV;
@@ -618,27 +620,31 @@ static int m920x_probe(struct usb_interface *intf,
 		 * multi-tuner device
 		 */
 
-		if ((ret = dvb_usb_device_init(intf, &megasky_properties,
-					       THIS_MODULE, &d)) == 0) {
+		ret = dvb_usb_device_init(intf, &megasky_properties,
+					  THIS_MODULE, &d, adapter_nr);
+		if (ret == 0) {
 			rc_init_seq = megasky_rc_init;
 			goto found;
 		}
 
-		if ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
-					       THIS_MODULE, &d)) == 0) {
+		ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
+					  THIS_MODULE, &d, adapter_nr);
+		if (ret == 0) {
 			/* No remote control, so no rc_init_seq */
 			goto found;
 		}
 
 		/* This configures both tuners on the TV Walker Twin */
-		if ((ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
-					       THIS_MODULE, &d)) == 0) {
+		ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
+					  THIS_MODULE, &d, adapter_nr);
+		if (ret == 0) {
 			rc_init_seq = tvwalkertwin_rc_init;
 			goto found;
 		}
 
-		if ((ret = dvb_usb_device_init(intf, &dposh_properties,
-					       THIS_MODULE, &d)) == 0) {
+		ret = dvb_usb_device_init(intf, &dposh_properties,
+					  THIS_MODULE, &d, adapter_nr);
+		if (ret == 0) {
 			/* Remote controller not supported yet. */
 			goto found;
 		}

+ 4 - 1
drivers/media/dvb/dvb-usb/nova-t-usb2.c

@@ -15,6 +15,8 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 #define deb_rc(args...) dprintk(debug,0x01,args)
 #define deb_ee(args...) dprintk(debug,0x02,args)
 
@@ -142,7 +144,8 @@ static struct dvb_usb_device_properties nova_t_properties;
 static int nova_t_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE,NULL);
+	return dvb_usb_device_init(intf, &nova_t_properties,
+				   THIS_MODULE, NULL, adapter_nr);
 }
 
 /* do not change the order of the ID table */

+ 6 - 2
drivers/media/dvb/dvb-usb/opera1.c

@@ -46,6 +46,9 @@ MODULE_PARM_DESC(debug,
 		 "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
 		 DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+
 static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
 			    u8 * data, u16 len, int flags)
 {
@@ -243,7 +246,7 @@ static struct stv0299_config opera1_stv0299_config = {
 	.mclk = 88000000UL,
 	.invert = 1,
 	.skip_reinit = 0,
-	.lock_output = STV0229_LOCKOUTPUT_0,
+	.lock_output = STV0299_LOCKOUTPUT_0,
 	.volt13_op0_op1 = STV0299_VOLT13_OP0,
 	.inittab = opera1_inittab,
 	.set_symbol_rate = opera1_stv0299_set_symbol_rate,
@@ -548,7 +551,8 @@ static int opera1_probe(struct usb_interface *intf,
 		return -EINVAL;
 	}
 
-	if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, NULL) != 0)
+	if (0 != dvb_usb_device_init(intf, &opera1_properties,
+				     THIS_MODULE, NULL, adapter_nr))
 		return -EINVAL;
 	return 0;
 }

+ 63 - 4
drivers/media/dvb/dvb-usb/ttusb2.c

@@ -37,6 +37,8 @@ static int dvb_usb_ttusb2_debug;
 module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 struct ttusb2_state {
 	u8 id;
 };
@@ -145,6 +147,7 @@ static struct tda10086_config tda10086_config = {
 	.demod_address = 0x0e,
 	.invert = 0,
 	.diseqc_tone = 1,
+	.xtal_freq = TDA10086_XTAL_16M,
 };
 
 static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap)
@@ -176,17 +179,25 @@ static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap)
 
 /* DVB USB Driver stuff */
 static struct dvb_usb_device_properties ttusb2_properties;
+static struct dvb_usb_device_properties ttusb2_properties_s2400;
 
 static int ttusb2_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf,&ttusb2_properties,THIS_MODULE,NULL);
+	if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
+				     THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
+				     THIS_MODULE, NULL, adapter_nr))
+		return 0;
+	return -ENODEV;
 }
 
 static struct usb_device_id ttusb2_table [] = {
-		{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
-		{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
-		{}		/* Terminating entry */
+	{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
+	{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
+	{ USB_DEVICE(USB_VID_TECHNOTREND,
+		USB_PID_TECHNOTREND_CONNECT_S2400) },
+	{}		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, ttusb2_table);
 
@@ -242,6 +253,54 @@ static struct dvb_usb_device_properties ttusb2_properties = {
 	}
 };
 
+static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-tt-s2400-01.fw",
+
+	.size_of_priv = sizeof(struct ttusb2_state),
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.streaming_ctrl   = NULL,
+
+			.frontend_attach  = ttusb2_frontend_attach,
+			.tuner_attach     = ttusb2_tuner_attach,
+
+			/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_ISOC,
+				.count = 5,
+				.endpoint = 0x02,
+				.u = {
+					.isoc = {
+						.framesperurb = 4,
+						.framesize = 940,
+						.interval = 1,
+					}
+				}
+			}
+		}
+	},
+
+	.power_ctrl       = ttusb2_power_ctrl,
+	.identify_state   = ttusb2_identify_state,
+
+	.i2c_algo         = &ttusb2_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "Technotrend TT-connect S-2400",
+			{ &ttusb2_table[2], NULL },
+			{ NULL },
+		},
+	}
+};
+
 static struct usb_driver ttusb2_driver = {
 	.name		= "dvb_usb_ttusb2",
 	.probe		= ttusb2_probe,

+ 4 - 1
drivers/media/dvb/dvb-usb/umt-010.c

@@ -13,6 +13,8 @@
 
 #include "mt352.h"
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 static int umt_mt352_demod_init(struct dvb_frontend *fe)
 {
 	static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
@@ -75,7 +77,8 @@ static struct dvb_usb_device_properties umt_properties;
 static int umt_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE,NULL) == 0)
+	if (0 == dvb_usb_device_init(intf, &umt_properties,
+				     THIS_MODULE, NULL, adapter_nr))
 		return 0;
 	return -EINVAL;
 }

+ 9 - 9
drivers/media/dvb/dvb-usb/vp702x-fe.c

@@ -67,7 +67,7 @@ static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
 	vp702x_fe_refresh_state(st);
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 
 	if (st->lock == 0)
 		*status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
@@ -121,7 +121,7 @@ static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
 
 static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
 {
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 	tune->min_delay_ms = 2000;
 	return 0;
 }
@@ -183,21 +183,21 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
 static int vp702x_fe_init(struct dvb_frontend *fe)
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 	vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
 	return 0;
 }
 
 static int vp702x_fe_sleep(struct dvb_frontend *fe)
 {
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 	return 0;
 }
 
 static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
 				  struct dvb_frontend_parameters *fep)
 {
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 	return 0;
 }
 
@@ -208,7 +208,7 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
 	u8 cmd[8],ibuf[10];
 	memset(cmd,0,8);
 
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 
 	if (m->msg_len > 4)
 		return -EINVAL;
@@ -230,7 +230,7 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
 
 static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
 {
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 	return 0;
 }
 
@@ -238,7 +238,7 @@ static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
 	u8 ibuf[10];
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 
 	st->tone_mode = tone;
 
@@ -263,7 +263,7 @@ static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
 	u8 ibuf[10];
-	deb_fe("%s\n",__FUNCTION__);
+	deb_fe("%s\n",__func__);
 
 	st->voltage = voltage;
 

+ 4 - 1
drivers/media/dvb/dvb-usb/vp702x.c

@@ -21,6 +21,8 @@ int dvb_usb_vp702x_debug;
 module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
 
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 struct vp702x_state {
 	int pid_filter_count;
 	int pid_filter_can_bypass;
@@ -238,7 +240,8 @@ static struct dvb_usb_device_properties vp702x_properties;
 static int vp702x_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf,&vp702x_properties,THIS_MODULE,NULL);
+	return dvb_usb_device_init(intf, &vp702x_properties,
+				   THIS_MODULE, NULL, adapter_nr);
 }
 
 static struct usb_device_id vp702x_usb_table [] = {

+ 5 - 1
drivers/media/dvb/dvb-usb/vp7045.c

@@ -18,6 +18,9 @@
 static int dvb_usb_vp7045_debug;
 module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
 #define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
 #define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
 #define deb_rc(args...)   dprintk(dvb_usb_vp7045_debug,0x04,args)
@@ -219,7 +222,8 @@ static struct dvb_usb_device_properties vp7045_properties;
 static int vp7045_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE,NULL);
+	return dvb_usb_device_init(intf, &vp7045_properties,
+				   THIS_MODULE, NULL, adapter_nr);
 }
 
 static struct usb_device_id vp7045_usb_table [] = {

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

@@ -188,6 +188,14 @@ config DVB_DIB7000P
 	  A DVB-T tuner module. Designed for mobile usage. Say Y when you want
 	  to support this frontend.
 
+config DVB_TDA10048
+	tristate "Philips TDA10048HN based"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	select FW_LOADER
+	help
+	  A DVB-T tuner module. Say Y when you want to support this frontend.
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
@@ -291,6 +299,14 @@ config DVB_S5H1409
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
 
+config DVB_AU8522
+	tristate "Auvitek AU8522 based"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+	  to support this frontend.
+
 comment "Tuners/PLL support"
 	depends on DVB_CORE
 
@@ -369,6 +385,11 @@ config DVB_TUNER_XC5000
 	  This device is only used inside a SiP called togther with a
 	  demodulator for now.
 
+config DVB_TUNER_ITD1000
+	tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+
 comment "Miscellaneous devices"
 	depends on DVB_CORE
 
@@ -379,6 +400,13 @@ config DVB_LNBP21
 	help
 	  An SEC control chip.
 
+config DVB_ISL6405
+	tristate "ISL6405 SEC controller"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  An SEC control chip.
+
 config DVB_ISL6421
 	tristate "ISL6421 SEC controller"
 	depends on DVB_CORE && I2C

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

@@ -38,6 +38,7 @@ obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
 obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
 obj-$(CONFIG_DVB_CX24123) += cx24123.o
 obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
+obj-$(CONFIG_DVB_ISL6405) += isl6405.o
 obj-$(CONFIG_DVB_ISL6421) += isl6421.o
 obj-$(CONFIG_DVB_TDA10086) += tda10086.o
 obj-$(CONFIG_DVB_TDA826X) += tda826x.o
@@ -51,3 +52,6 @@ obj-$(CONFIG_DVB_TUA6100) += tua6100.o
 obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
 obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
 obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o
+obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
+obj-$(CONFIG_DVB_AU8522) += au8522.o
+obj-$(CONFIG_DVB_TDA10048) += tda10048.o

+ 692 - 0
drivers/media/dvb/frontends/au8522.c

@@ -0,0 +1,692 @@
+/*
+    Auvitek AU8522 QAM/8VSB demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "dvb-pll.h"
+#include "au8522.h"
+
+struct au8522_state {
+
+	struct i2c_adapter *i2c;
+
+	/* configuration settings */
+	const struct au8522_config *config;
+
+	struct dvb_frontend frontend;
+
+	u32 current_frequency;
+	fe_modulation_t current_modulation;
+
+};
+
+static int debug;
+
+#define dprintk(arg...) do {		\
+	if (debug) 			\
+		 printk(arg); 		\
+	} while (0)
+
+/* 16 bit registers, 8 bit values */
+static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
+{
+	int ret;
+	u8 buf [] = { reg >> 8, reg & 0xff, data };
+
+	struct i2c_msg msg = { .addr = state->config->demod_address,
+			       .flags = 0, .buf = buf, .len = 3 };
+
+	ret = i2c_transfer(state->i2c, &msg, 1);
+
+	if (ret != 1)
+		printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
+		       "ret == %i)\n", __func__, reg, data, ret);
+
+	return (ret != 1) ? -1 : 0;
+}
+
+static u8 au8522_readreg(struct au8522_state *state, u16 reg)
+{
+	int ret;
+	u8 b0 [] = { reg >> 8, reg & 0xff };
+	u8 b1 [] = { 0 };
+
+	struct i2c_msg msg [] = {
+		{ .addr = state->config->demod_address, .flags = 0,
+		  .buf = b0, .len = 2 },
+		{ .addr = state->config->demod_address, .flags = I2C_M_RD,
+		  .buf = b1, .len = 1 } };
+
+	ret = i2c_transfer(state->i2c, msg, 2);
+
+	if (ret != 2)
+		printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+		       __func__, ret);
+	return b1[0];
+}
+
+static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	dprintk("%s(%d)\n", __func__, enable);
+
+	if (enable)
+		return au8522_writereg(state, 0x106, 1);
+	else
+		return au8522_writereg(state, 0x106, 0);
+}
+
+struct mse2snr_tab {
+	u16 val;
+	u16 data;
+};
+
+/* VSB SNR lookup table */
+static struct mse2snr_tab vsb_mse2snr_tab[] = {
+	{   0, 270 },
+	{   2, 250 },
+	{   3, 240 },
+	{   5, 230 },
+	{   7, 220 },
+	{   9, 210 },
+	{  12, 200 },
+	{  13, 195 },
+	{  15, 190 },
+	{  17, 185 },
+	{  19, 180 },
+	{  21, 175 },
+	{  24, 170 },
+	{  27, 165 },
+	{  31, 160 },
+	{  32, 158 },
+	{  33, 156 },
+	{  36, 152 },
+	{  37, 150 },
+	{  39, 148 },
+	{  40, 146 },
+	{  41, 144 },
+	{  43, 142 },
+	{  44, 140 },
+	{  48, 135 },
+	{  50, 130 },
+	{  43, 142 },
+	{  53, 125 },
+	{  56, 120 },
+	{ 256, 115 },
+};
+
+/* QAM64 SNR lookup table */
+static struct mse2snr_tab qam64_mse2snr_tab[] = {
+	{  15,   0 },
+	{  16, 290 },
+	{  17, 288 },
+	{  18, 286 },
+	{  19, 284 },
+	{  20, 282 },
+	{  21, 281 },
+	{  22, 279 },
+	{  23, 277 },
+	{  24, 275 },
+	{  25, 273 },
+	{  26, 271 },
+	{  27, 269 },
+	{  28, 268 },
+	{  29, 266 },
+	{  30, 264 },
+	{  31, 262 },
+	{  32, 260 },
+	{  33, 259 },
+	{  34, 258 },
+	{  35, 256 },
+	{  36, 255 },
+	{  37, 254 },
+	{  38, 252 },
+	{  39, 251 },
+	{  40, 250 },
+	{  41, 249 },
+	{  42, 248 },
+	{  43, 246 },
+	{  44, 245 },
+	{  45, 244 },
+	{  46, 242 },
+	{  47, 241 },
+	{  48, 240 },
+	{  50, 239 },
+	{  51, 238 },
+	{  53, 237 },
+	{  54, 236 },
+	{  56, 235 },
+	{  57, 234 },
+	{  59, 233 },
+	{  60, 232 },
+	{  62, 231 },
+	{  63, 230 },
+	{  65, 229 },
+	{  67, 228 },
+	{  68, 227 },
+	{  70, 226 },
+	{  71, 225 },
+	{  73, 224 },
+	{  74, 223 },
+	{  76, 222 },
+	{  78, 221 },
+	{  80, 220 },
+	{  82, 219 },
+	{  85, 218 },
+	{  88, 217 },
+	{  90, 216 },
+	{  92, 215 },
+	{  93, 214 },
+	{  94, 212 },
+	{  95, 211 },
+	{  97, 210 },
+	{  99, 209 },
+	{ 101, 208 },
+	{ 102, 207 },
+	{ 104, 206 },
+	{ 107, 205 },
+	{ 111, 204 },
+	{ 114, 203 },
+	{ 118, 202 },
+	{ 122, 201 },
+	{ 125, 200 },
+	{ 128, 199 },
+	{ 130, 198 },
+	{ 132, 197 },
+	{ 256, 190 },
+};
+
+/* QAM256 SNR lookup table */
+static struct mse2snr_tab qam256_mse2snr_tab[] = {
+	{  16,   0 },
+	{  17, 400 },
+	{  18, 398 },
+	{  19, 396 },
+	{  20, 394 },
+	{  21, 392 },
+	{  22, 390 },
+	{  23, 388 },
+	{  24, 386 },
+	{  25, 384 },
+	{  26, 382 },
+	{  27, 380 },
+	{  28, 379 },
+	{  29, 378 },
+	{  30, 377 },
+	{  31, 376 },
+	{  32, 375 },
+	{  33, 374 },
+	{  34, 373 },
+	{  35, 372 },
+	{  36, 371 },
+	{  37, 370 },
+	{  38, 362 },
+	{  39, 354 },
+	{  40, 346 },
+	{  41, 338 },
+	{  42, 330 },
+	{  43, 328 },
+	{  44, 326 },
+	{  45, 324 },
+	{  46, 322 },
+	{  47, 320 },
+	{  48, 319 },
+	{  49, 318 },
+	{  50, 317 },
+	{  51, 316 },
+	{  52, 315 },
+	{  53, 314 },
+	{  54, 313 },
+	{  55, 312 },
+	{  56, 311 },
+	{  57, 310 },
+	{  58, 308 },
+	{  59, 306 },
+	{  60, 304 },
+	{  61, 302 },
+	{  62, 300 },
+	{  63, 298 },
+	{  65, 295 },
+	{  68, 294 },
+	{  70, 293 },
+	{  73, 292 },
+	{  76, 291 },
+	{  78, 290 },
+	{  79, 289 },
+	{  81, 288 },
+	{  82, 287 },
+	{  83, 286 },
+	{  84, 285 },
+	{  85, 284 },
+	{  86, 283 },
+	{  88, 282 },
+	{  89, 281 },
+	{ 256, 280 },
+};
+
+static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
+				 u16 *snr)
+{
+	int i, ret = -EINVAL;
+	dprintk("%s()\n", __func__);
+
+	for (i = 0; i < sz; i++) {
+		if (mse < tab[i].val) {
+			*snr = tab[i].data;
+			ret = 0;
+			break;
+		}
+	}
+	dprintk("%s() snr=%d\n", __func__, *snr);
+	return ret;
+}
+
+/* VSB Modulation table */
+static struct {
+	u16 reg;
+	u16 data;
+} VSB_mod_tab[] = {
+	{ 0x8090, 0x84 },
+	{ 0x4092, 0x11 },
+	{ 0x2005, 0x00 },
+	{ 0x8091, 0x80 },
+	{ 0x80a3, 0x0c },
+	{ 0x80a4, 0xe8 },
+	{ 0x8081, 0xc4 },
+	{ 0x80a5, 0x40 },
+	{ 0x80a7, 0x40 },
+	{ 0x80a6, 0x67 },
+	{ 0x8262, 0x20 },
+	{ 0x821c, 0x30 },
+	{ 0x80d8, 0x1a },
+	{ 0x8227, 0xa0 },
+	{ 0x8121, 0xff },
+	{ 0x80a8, 0xf0 },
+	{ 0x80a9, 0x05 },
+	{ 0x80aa, 0x77 },
+	{ 0x80ab, 0xf0 },
+	{ 0x80ac, 0x05 },
+	{ 0x80ad, 0x77 },
+	{ 0x80ae, 0x41 },
+	{ 0x80af, 0x66 },
+	{ 0x821b, 0xcc },
+	{ 0x821d, 0x80 },
+	{ 0x80b5, 0xfb },
+	{ 0x80b6, 0x8e },
+	{ 0x80b7, 0x39 },
+	{ 0x80a4, 0xe8 },
+	{ 0x8231, 0x13 },
+};
+
+/* QAM Modulation table */
+static struct {
+	u16 reg;
+	u16 data;
+} QAM_mod_tab[] = {
+	{ 0x80a3, 0x09 },
+	{ 0x80a4, 0x00 },
+	{ 0x8081, 0xc4 },
+	{ 0x80a5, 0x40 },
+	{ 0x80b5, 0xfb },
+	{ 0x80b6, 0x8e },
+	{ 0x80b7, 0x39 },
+	{ 0x80aa, 0x77 },
+	{ 0x80ad, 0x77 },
+	{ 0x80a6, 0x67 },
+	{ 0x8262, 0x20 },
+	{ 0x821c, 0x30 },
+	{ 0x80b8, 0x3e },
+	{ 0x80b9, 0xf0 },
+	{ 0x80ba, 0x01 },
+	{ 0x80bb, 0x18 },
+	{ 0x80bc, 0x50 },
+	{ 0x80bd, 0x00 },
+	{ 0x80be, 0xea },
+	{ 0x80bf, 0xef },
+	{ 0x80c0, 0xfc },
+	{ 0x80c1, 0xbd },
+	{ 0x80c2, 0x1f },
+	{ 0x80c3, 0xfc },
+	{ 0x80c4, 0xdd },
+	{ 0x80c5, 0xaf },
+	{ 0x80c6, 0x00 },
+	{ 0x80c7, 0x38 },
+	{ 0x80c8, 0x30 },
+	{ 0x80c9, 0x05 },
+	{ 0x80ca, 0x4a },
+	{ 0x80cb, 0xd0 },
+	{ 0x80cc, 0x01 },
+	{ 0x80cd, 0xd9 },
+	{ 0x80ce, 0x6f },
+	{ 0x80cf, 0xf9 },
+	{ 0x80d0, 0x70 },
+	{ 0x80d1, 0xdf },
+	{ 0x80d2, 0xf7 },
+	{ 0x80d3, 0xc2 },
+	{ 0x80d4, 0xdf },
+	{ 0x80d5, 0x02 },
+	{ 0x80d6, 0x9a },
+	{ 0x80d7, 0xd0 },
+	{ 0x8250, 0x0d },
+	{ 0x8251, 0xcd },
+	{ 0x8252, 0xe0 },
+	{ 0x8253, 0x05 },
+	{ 0x8254, 0xa7 },
+	{ 0x8255, 0xff },
+	{ 0x8256, 0xed },
+	{ 0x8257, 0x5b },
+	{ 0x8258, 0xae },
+	{ 0x8259, 0xe6 },
+	{ 0x825a, 0x3d },
+	{ 0x825b, 0x0f },
+	{ 0x825c, 0x0d },
+	{ 0x825d, 0xea },
+	{ 0x825e, 0xf2 },
+	{ 0x825f, 0x51 },
+	{ 0x8260, 0xf5 },
+	{ 0x8261, 0x06 },
+	{ 0x821a, 0x00 },
+	{ 0x8546, 0x40 },
+	{ 0x8210, 0x26 },
+	{ 0x8211, 0xf6 },
+	{ 0x8212, 0x84 },
+	{ 0x8213, 0x02 },
+	{ 0x8502, 0x01 },
+	{ 0x8121, 0x04 },
+	{ 0x8122, 0x04 },
+	{ 0x852e, 0x10 },
+	{ 0x80a4, 0xca },
+	{ 0x80a7, 0x40 },
+	{ 0x8526, 0x01 },
+};
+
+static int au8522_enable_modulation(struct dvb_frontend *fe,
+				    fe_modulation_t m)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	int i;
+
+	dprintk("%s(0x%08x)\n", __func__, m);
+
+	switch (m) {
+	case VSB_8:
+		dprintk("%s() VSB_8\n", __func__);
+		for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
+			au8522_writereg(state,
+				VSB_mod_tab[i].reg,
+				VSB_mod_tab[i].data);
+		break;
+	case QAM_64:
+	case QAM_256:
+		dprintk("%s() QAM 64/256\n", __func__);
+		for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++)
+			au8522_writereg(state,
+				QAM_mod_tab[i].reg,
+				QAM_mod_tab[i].data);
+		break;
+	default:
+		dprintk("%s() Invalid modulation\n", __func__);
+		return -EINVAL;
+	}
+
+	state->current_modulation = m;
+
+	return 0;
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int au8522_set_frontend(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *p)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	dprintk("%s(frequency=%d)\n", __func__, p->frequency);
+
+	state->current_frequency = p->frequency;
+
+	au8522_enable_modulation(fe, p->u.vsb.modulation);
+
+	/* Allow the demod to settle */
+	msleep(100);
+
+	if (fe->ops.tuner_ops.set_params) {
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+		fe->ops.tuner_ops.set_params(fe, p);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+	}
+
+	return 0;
+}
+
+/* Reset the demod hardware and reset all of the configuration registers
+   to a default state. */
+static int au8522_init(struct dvb_frontend *fe)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	dprintk("%s()\n", __func__);
+
+	au8522_writereg(state, 0xa4, 1 << 5);
+
+	au8522_i2c_gate_ctrl(fe, 1);
+
+	return 0;
+}
+
+static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	u8 reg;
+	u32 tuner_status = 0;
+
+	*status = 0;
+
+	if (state->current_modulation == VSB_8) {
+		dprintk("%s() Checking VSB_8\n", __func__);
+		reg = au8522_readreg(state, 0x4088);
+		if (reg & 0x01)
+			*status |= FE_HAS_VITERBI;
+		if (reg & 0x02)
+			*status |= FE_HAS_LOCK | FE_HAS_SYNC;
+	} else {
+		dprintk("%s() Checking QAM\n", __func__);
+		reg = au8522_readreg(state, 0x4541);
+		if (reg & 0x80)
+			*status |= FE_HAS_VITERBI;
+		if (reg & 0x20)
+			*status |= FE_HAS_LOCK | FE_HAS_SYNC;
+	}
+
+	switch (state->config->status_mode) {
+	case AU8522_DEMODLOCKING:
+		dprintk("%s() DEMODLOCKING\n", __func__);
+		if (*status & FE_HAS_VITERBI)
+			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+		break;
+	case AU8522_TUNERLOCKING:
+		/* Get the tuner status */
+		dprintk("%s() TUNERLOCKING\n", __func__);
+		if (fe->ops.tuner_ops.get_status) {
+			if (fe->ops.i2c_gate_ctrl)
+				fe->ops.i2c_gate_ctrl(fe, 1);
+
+			fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+			if (fe->ops.i2c_gate_ctrl)
+				fe->ops.i2c_gate_ctrl(fe, 0);
+		}
+		if (tuner_status)
+			*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+		break;
+	}
+
+	dprintk("%s() status 0x%08x\n", __func__, *status);
+
+	return 0;
+}
+
+static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	int ret = -EINVAL;
+
+	dprintk("%s()\n", __func__);
+
+	if (state->current_modulation == QAM_256)
+		ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
+					    ARRAY_SIZE(qam256_mse2snr_tab),
+					    au8522_readreg(state, 0x4522),
+					    snr);
+	else if (state->current_modulation == QAM_64)
+		ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
+					    ARRAY_SIZE(qam64_mse2snr_tab),
+					    au8522_readreg(state, 0x4522),
+					    snr);
+	else /* VSB_8 */
+		ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
+					    ARRAY_SIZE(vsb_mse2snr_tab),
+					    au8522_readreg(state, 0x4311),
+					    snr);
+
+	return ret;
+}
+
+static int au8522_read_signal_strength(struct dvb_frontend *fe,
+				       u16 *signal_strength)
+{
+	return au8522_read_snr(fe, signal_strength);
+}
+
+static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	if (state->current_modulation == VSB_8)
+		*ucblocks = au8522_readreg(state, 0x4087);
+	else
+		*ucblocks = au8522_readreg(state, 0x4543);
+
+	return 0;
+}
+
+static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	return au8522_read_ucblocks(fe, ber);
+}
+
+static int au8522_get_frontend(struct dvb_frontend *fe,
+				struct dvb_frontend_parameters *p)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+
+	p->frequency = state->current_frequency;
+	p->u.vsb.modulation = state->current_modulation;
+
+	return 0;
+}
+
+static int au8522_get_tune_settings(struct dvb_frontend *fe,
+				    struct dvb_frontend_tune_settings *tune)
+{
+	tune->min_delay_ms = 1000;
+	return 0;
+}
+
+static void au8522_release(struct dvb_frontend *fe)
+{
+	struct au8522_state *state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops au8522_ops;
+
+struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+				   struct i2c_adapter *i2c)
+{
+	struct au8522_state *state = NULL;
+
+	/* allocate memory for the internal state */
+	state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	/* setup the state */
+	state->config = config;
+	state->i2c = i2c;
+	/* create dvb_frontend */
+	memcpy(&state->frontend.ops, &au8522_ops,
+	       sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+
+	if (au8522_init(&state->frontend) != 0) {
+		printk(KERN_ERR "%s: Failed to initialize correctly\n",
+			__func__);
+		goto error;
+	}
+
+	/* Note: Leaving the I2C gate open here. */
+	au8522_i2c_gate_ctrl(&state->frontend, 1);
+
+	return &state->frontend;
+
+error:
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(au8522_attach);
+
+static struct dvb_frontend_ops au8522_ops = {
+
+	.info = {
+		.name			= "Auvitek AU8522 QAM/8VSB Frontend",
+		.type			= FE_ATSC,
+		.frequency_min		= 54000000,
+		.frequency_max		= 858000000,
+		.frequency_stepsize	= 62500,
+		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+	},
+
+	.init                 = au8522_init,
+	.i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
+	.set_frontend         = au8522_set_frontend,
+	.get_frontend         = au8522_get_frontend,
+	.get_tune_settings    = au8522_get_tune_settings,
+	.read_status          = au8522_read_status,
+	.read_ber             = au8522_read_ber,
+	.read_signal_strength = au8522_read_signal_strength,
+	.read_snr             = au8522_read_snr,
+	.read_ucblocks        = au8522_read_ucblocks,
+	.release              = au8522_release,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");

+ 56 - 0
drivers/media/dvb/frontends/au8522.h

@@ -0,0 +1,56 @@
+/*
+    Auvitek AU8522 QAM/8VSB demodulator driver
+
+    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    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 __AU8522_H__
+#define __AU8522_H__
+
+#include <linux/dvb/frontend.h>
+
+struct au8522_config {
+	/* the demodulator's i2c address */
+	u8 demod_address;
+
+	/* Return lock status based on tuner lock, or demod lock */
+#define AU8522_TUNERLOCKING 0
+#define AU8522_DEMODLOCKING 1
+	u8 status_mode;
+};
+
+#if defined(CONFIG_DVB_AU8522) || 				\
+	    (defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE))
+extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+					  struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+				   struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_AU8522 */
+
+#endif /* __AU8522_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */

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

@@ -91,7 +91,7 @@ static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8
 	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
 
 		deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
-			__FUNCTION__, state->config->demod_address, reg,  err);
+			__func__, state->config->demod_address, reg,  err);
 		return -EREMOTEIO;
 	}
 
@@ -110,7 +110,7 @@ static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 l
 
 	if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
 		deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
-			__FUNCTION__, state->config->demod_address, reg,  err);
+			__func__, state->config->demod_address, reg,  err);
 		return -EREMOTEIO;
 	}
 	deb_i2c("i2c rd %02x: ",reg);

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

@@ -41,7 +41,7 @@ extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
 static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
 						  struct i2c_adapter* i2c)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif // CONFIG_DVB_BCM3510

+ 19 - 39
drivers/media/dvb/frontends/bsbe1.h

@@ -1,5 +1,5 @@
 /*
- * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.c)
+ * bsbe1.h - ALPS BSBE1 tuner support
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -26,44 +26,24 @@
 #define BSBE1_H
 
 static u8 alps_bsbe1_inittab[] = {
-	0x01, 0x15,
-	0x02, 0x30,
-	0x03, 0x00,
+	0x01, 0x15,   /* XTAL = 4MHz, VCO = 352 MHz */
+	0x02, 0x30,   /* MCLK = 88 MHz */
+	0x03, 0x00,   /* ACR output 0 */
 	0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-	0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
-	0x06, 0x40,   /* DAC not used, set to high impendance mode */
-	0x07, 0x00,   /* DAC LSB */
+	0x05, 0x05,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
+	0x06, 0x00,   /* DAC output 0 */
 	0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
 	0x09, 0x00,   /* FIFO */
-	0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-	0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
-	0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
-	0x10, 0x3f,   // AGC2  0x3d
-	0x11, 0x84,
-	0x12, 0xb9,
-	0x15, 0xc9,   // lock detector threshold
-	0x16, 0x00,
-	0x17, 0x00,
-	0x18, 0x00,
-	0x19, 0x00,
-	0x1a, 0x00,
-	0x1f, 0x50,
-	0x20, 0x00,
-	0x21, 0x00,
-	0x22, 0x00,
-	0x23, 0x00,
-	0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
-	0x29, 0x1e,  // 1/2 threshold
-	0x2a, 0x14,  // 2/3 threshold
-	0x2b, 0x0f,  // 3/4 threshold
-	0x2c, 0x09,  // 5/6 threshold
-	0x2d, 0x05,  // 7/8 threshold
-	0x2e, 0x01,
-	0x31, 0x1f,  // test all FECs
-	0x32, 0x19,  // viterbi and synchro search
-	0x33, 0xfc,  // rs control
-	0x34, 0x93,  // error control
-	0x0f, 0x92,
+	0x0c, 0x51,   /* OP1/OP0 normal, val = 1 (LNB power on) */
+	0x0d, 0x82,   /* DC offset compensation = on, beta_agc1 = 2 */
+	0x0f, 0x92,   /* AGC1R */
+	0x10, 0x34,   /* AGC2O */
+	0x11, 0x84,   /* TLSR */
+	0x12, 0xb9,   /* CFD */
+	0x15, 0xc9,   /* lock detector threshold */
+	0x28, 0x00,   /* out imp: normal, type: parallel, FEC mode: QPSK */
+	0x33, 0xfc,   /* RS control */
+	0x34, 0x93,   /* count viterbi bit errors per 2E18 bytes */
 	0xff, 0xff
 };
 
@@ -100,11 +80,11 @@ static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_front
 	if ((params->frequency < 950000) || (params->frequency > 2150000))
 		return -EINVAL;
 
-	div = (params->frequency + (125 - 1)) / 125; // round correctly
+	div = params->frequency / 1000;
 	data[0] = (div >> 8) & 0x7f;
 	data[1] = div & 0xff;
-	data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
-	data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
+	data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1;
+	data[3] = 0xe0;
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);

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

@@ -133,7 +133,7 @@ static struct stv0299_config alps_bsru6_config = {
 	.mclk = 88000000UL,
 	.invert = 1,
 	.skip_reinit = 0,
-	.lock_output = STV0229_LOCKOUTPUT_1,
+	.lock_output = STV0299_LOCKOUTPUT_1,
 	.volt13_op0_op1 = STV0299_VOLT13_OP1,
 	.min_delay_ms = 100,
 	.set_symbol_rate = alps_bsru6_set_symbol_rate,

+ 6 - 6
drivers/media/dvb/frontends/cx22700.c

@@ -73,13 +73,13 @@ static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
 	u8 buf [] = { reg, data };
 	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	ret = i2c_transfer (state->i2c, &msg, 1);
 
 	if (ret != 1)
 		printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-			__FUNCTION__, reg, data, ret);
+			__func__, reg, data, ret);
 
 	return (ret != 1) ? -1 : 0;
 }
@@ -92,7 +92,7 @@ static int cx22700_readreg (struct cx22700_state* state, u8 reg)
 	struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
 			   { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	ret = i2c_transfer (state->i2c, msg, 2);
 
@@ -105,7 +105,7 @@ static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
 {
 	u8 val;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	switch (inversion) {
 	case INVERSION_AUTO:
@@ -127,7 +127,7 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet
 	static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
 	u8 val;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
 		return -EINVAL;
@@ -191,7 +191,7 @@ static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_paramet
 						    FEC_5_6, FEC_7_8 };
 	u8 val;
 
-	dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __func__);
 
 	if (!(cx22700_readreg(state, 0x07) & 0x20))  /*  tps valid? */
 		return -EAGAIN;

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

@@ -38,7 +38,7 @@ extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
 static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
 					   struct i2c_adapter* i2c)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif // CONFIG_DVB_CX22700

+ 13 - 13
drivers/media/dvb/frontends/cx22702.c

@@ -48,7 +48,7 @@ struct cx22702_state {
 	u8 prevUCBlocks;
 };
 
-static int debug = 0;
+static int debug;
 #define dprintk	if (debug) printk
 
 /* Register values to initialise the demod */
@@ -90,7 +90,7 @@ static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data)
 
 	if (ret != 1)
 		printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-			__FUNCTION__, reg, data, ret);
+			__func__, reg, data, ret);
 
 	return (ret != 1) ? -1 : 0;
 }
@@ -108,7 +108,7 @@ static u8 cx22702_readreg (struct cx22702_state* state, u8 reg)
 	ret = i2c_transfer(state->i2c, msg, 2);
 
 	if (ret != 2)
-		printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+		printk("%s: readreg error (ret == %i)\n", __func__, ret);
 
 	return b1[0];
 }
@@ -195,7 +195,7 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet
 static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
 {
 	struct cx22702_state* state = fe->demodulator_priv;
-	dprintk ("%s(%d)\n", __FUNCTION__, enable);
+	dprintk ("%s(%d)\n", __func__, enable);
 	if (enable)
 		return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe);
 	else
@@ -228,7 +228,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 		cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf );
 		break;
 	default:
-		dprintk ("%s: invalid bandwidth\n",__FUNCTION__);
+		dprintk ("%s: invalid bandwidth\n",__func__);
 		return -EINVAL;
 	}
 
@@ -250,7 +250,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 		cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
 		cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
 		cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
-		dprintk("%s: Autodetecting\n",__FUNCTION__);
+		dprintk("%s: Autodetecting\n",__func__);
 		return 0;
 	}
 
@@ -261,7 +261,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 		case QAM_16: val = (val&0xe7)|0x08; break;
 		case QAM_64: val = (val&0xe7)|0x10; break;
 		default:
-			dprintk ("%s: invalid constellation\n",__FUNCTION__);
+			dprintk ("%s: invalid constellation\n",__func__);
 			return -EINVAL;
 	}
 	switch(p->u.ofdm.hierarchy_information) {
@@ -270,7 +270,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 		case    HIERARCHY_2: val = (val&0xf8)|2; break;
 		case    HIERARCHY_4: val = (val&0xf8)|3; break;
 		default:
-			dprintk ("%s: invalid hierarchy\n",__FUNCTION__);
+			dprintk ("%s: invalid hierarchy\n",__func__);
 			return -EINVAL;
 	}
 	cx22702_writereg (state, 0x06, val);
@@ -284,7 +284,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 		case FEC_5_6: val = (val&0xc7)|0x18; break;
 		case FEC_7_8: val = (val&0xc7)|0x20; break;
 		default:
-			dprintk ("%s: invalid code_rate_HP\n",__FUNCTION__);
+			dprintk ("%s: invalid code_rate_HP\n",__func__);
 			return -EINVAL;
 	}
 	switch(p->u.ofdm.code_rate_LP) {
@@ -295,7 +295,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 		case FEC_5_6: val = (val&0xf8)|3; break;
 		case FEC_7_8: val = (val&0xf8)|4; break;
 		default:
-			dprintk ("%s: invalid code_rate_LP\n",__FUNCTION__);
+			dprintk ("%s: invalid code_rate_LP\n",__func__);
 			return -EINVAL;
 	}
 	cx22702_writereg (state, 0x07, val);
@@ -307,14 +307,14 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
 		case  GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break;
 		case  GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break;
 		default:
-			dprintk ("%s: invalid guard_interval\n",__FUNCTION__);
+			dprintk ("%s: invalid guard_interval\n",__func__);
 			return -EINVAL;
 	}
 	switch(p->u.ofdm.transmission_mode) {
 		case TRANSMISSION_MODE_2K: val = (val&0xfc); break;
 		case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break;
 		default:
-			dprintk ("%s: invalid transmission_mode\n",__FUNCTION__);
+			dprintk ("%s: invalid transmission_mode\n",__func__);
 			return -EINVAL;
 	}
 	cx22702_writereg(state, 0x08, val);
@@ -360,7 +360,7 @@ static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
 	reg23 = cx22702_readreg (state, 0x23);
 
 	dprintk ("%s: status demod=0x%02x agc=0x%02x\n"
-		,__FUNCTION__,reg0A,reg23);
+		,__func__,reg0A,reg23);
 
 	if(reg0A & 0x10) {
 		*status |= FE_HAS_LOCK;

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

@@ -48,7 +48,7 @@ extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
 static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
 					   struct i2c_adapter* i2c)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif // CONFIG_DVB_CX22702

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

@@ -121,7 +121,7 @@ static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
 
 	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
 		dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
-			 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+			 " data == 0x%02x)\n", __func__, err, reg, data);
 		return -EREMOTEIO;
 	}
 
@@ -247,7 +247,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
 	static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
 	int i;
 
-	dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate);
+	dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate);
 	if (srate>90999000UL/2)
 		srate=90999000UL/2;
 	if (srate<500000)
@@ -358,7 +358,7 @@ static int cx24110_initfe(struct dvb_frontend* fe)
 /* fixme (low): error handling */
 	int i;
 
-	dprintk("%s: init chip\n", __FUNCTION__);
+	dprintk("%s: init chip\n", __func__);
 
 	for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) {
 		cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);

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

@@ -48,7 +48,7 @@ extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
 static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
 						  struct i2c_adapter* i2c)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif // CONFIG_DVB_CX24110

+ 48 - 0
drivers/media/dvb/frontends/cx24113.h

@@ -0,0 +1,48 @@
+/*
+ *  Driver for Conexant CX24113/CX24128 Tuner (Satelite)
+ *
+ *  Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  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.
+ *
+ *  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 CX24113_H
+#define CX24113_H
+
+struct dvb_frontend;
+
+struct cx24113_config {
+	u8 i2c_addr; /* 0x14 or 0x54 */
+
+	u32 xtal_khz;
+};
+
+/* TODO: #if defined(CONFIG_DVB_TUNER_CX24113) || \
+ * (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE)) */
+
+static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
+	const struct cx24113_config *config, struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+
+static inline void cx24113_agc_callback(struct dvb_frontend *fe)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+
+#endif /* CX24113_H */

+ 204 - 100
drivers/media/dvb/frontends/cx24123.c

@@ -1,24 +1,26 @@
 /*
-    Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
-
-    Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
-
-    Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
-
-    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.
-
-    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.
-*/
+ *   Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
+ *
+ *   Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
+ *
+ *   Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
+ *
+ *   Support for CX24123/CX24113-NIM by Patrick Boettcher <pb@linuxtv.org>
+ *
+ *   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.
+ *
+ *   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/slab.h>
 #include <linux/kernel.h>
@@ -32,9 +34,16 @@
 
 static int force_band;
 static int debug;
+
+#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
+#define err(args...)  do { printk(KERN_ERR  "CX24123: " args); } while (0)
+
 #define dprintk(args...) \
 	do { \
-		if (debug) printk (KERN_DEBUG "cx24123: " args); \
+		if (debug) { \
+			printk(KERN_DEBUG "CX24123: %s: ", __func__); \
+			printk(args); \
+		} \
 	} while (0)
 
 struct cx24123_state
@@ -51,6 +60,10 @@ struct cx24123_state
 	u32 pllarg;
 	u32 FILTune;
 
+	struct i2c_adapter tuner_i2c_adapter;
+
+	u8 demod_rev;
+
 	/* The Demod/Tuner can't easily provide these, we cache them */
 	u32 currentfreq;
 	u32 currentsymbolrate;
@@ -225,48 +238,52 @@ static struct {
 	{0x67, 0x83}, /* Non-DCII symbol clock */
 };
 
-static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
+static int cx24123_i2c_writereg(struct cx24123_state *state,
+	u8 i2c_addr, int reg, int data)
 {
 	u8 buf[] = { reg, data };
-	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+	struct i2c_msg msg = {
+		.addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
+	};
 	int err;
 
-	if (debug>1)
-		printk("cx24123: %s:  write reg 0x%02x, value 0x%02x\n",
-						__FUNCTION__,reg, data);
+	/* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */
 
 	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
 		printk("%s: writereg error(err == %i, reg == 0x%02x,"
-			 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
-		return -EREMOTEIO;
+			 " data == 0x%02x)\n", __func__, err, reg, data);
+		return err;
 	}
 
 	return 0;
 }
 
-static int cx24123_readreg(struct cx24123_state* state, u8 reg)
+static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
 {
 	int ret;
-	u8 b0[] = { reg };
-	u8 b1[] = { 0 };
+	u8 b = 0;
 	struct i2c_msg msg[] = {
-		{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-		{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }
+		{ .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
+		{ .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 }
 	};
 
 	ret = i2c_transfer(state->i2c, msg, 2);
 
 	if (ret != 2) {
-		printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret);
+		err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
 		return ret;
 	}
 
-	if (debug>1)
-		printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret);
+	/* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */
 
-	return b1[0];
+	return b;
 }
 
+#define cx24123_readreg(state, reg) \
+	cx24123_i2c_readreg(state, state->config->demod_address, reg)
+#define cx24123_writereg(state, reg, val) \
+	cx24123_i2c_writereg(state, state->config->demod_address, reg, val)
+
 static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
 {
 	u8 nom_reg = cx24123_readreg(state, 0x0e);
@@ -274,17 +291,17 @@ static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_invers
 
 	switch (inversion) {
 	case INVERSION_OFF:
-		dprintk("%s:  inversion off\n",__FUNCTION__);
+		dprintk("inversion off\n");
 		cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
 		cx24123_writereg(state, 0x10, auto_reg | 0x80);
 		break;
 	case INVERSION_ON:
-		dprintk("%s:  inversion on\n",__FUNCTION__);
+		dprintk("inversion on\n");
 		cx24123_writereg(state, 0x0e, nom_reg | 0x80);
 		cx24123_writereg(state, 0x10, auto_reg | 0x80);
 		break;
 	case INVERSION_AUTO:
-		dprintk("%s:  inversion auto\n",__FUNCTION__);
+		dprintk("inversion auto\n");
 		cx24123_writereg(state, 0x10, auto_reg & ~0x80);
 		break;
 	default:
@@ -301,10 +318,10 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers
 	val = cx24123_readreg(state, 0x1b) >> 7;
 
 	if (val == 0) {
-		dprintk("%s:  read inversion off\n",__FUNCTION__);
+		dprintk("read inversion off\n");
 		*inversion = INVERSION_OFF;
 	} else {
-		dprintk("%s:  read inversion on\n",__FUNCTION__);
+		dprintk("read inversion on\n");
 		*inversion = INVERSION_ON;
 	}
 
@@ -326,42 +343,42 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
 
 	switch (fec) {
 	case FEC_1_2:
-		dprintk("%s:  set FEC to 1/2\n",__FUNCTION__);
+		dprintk("set FEC to 1/2\n");
 		cx24123_writereg(state, 0x0e, nom_reg | 0x01);
 		cx24123_writereg(state, 0x0f, 0x02);
 		break;
 	case FEC_2_3:
-		dprintk("%s:  set FEC to 2/3\n",__FUNCTION__);
+		dprintk("set FEC to 2/3\n");
 		cx24123_writereg(state, 0x0e, nom_reg | 0x02);
 		cx24123_writereg(state, 0x0f, 0x04);
 		break;
 	case FEC_3_4:
-		dprintk("%s:  set FEC to 3/4\n",__FUNCTION__);
+		dprintk("set FEC to 3/4\n");
 		cx24123_writereg(state, 0x0e, nom_reg | 0x03);
 		cx24123_writereg(state, 0x0f, 0x08);
 		break;
 	case FEC_4_5:
-		dprintk("%s:  set FEC to 4/5\n",__FUNCTION__);
+		dprintk("set FEC to 4/5\n");
 		cx24123_writereg(state, 0x0e, nom_reg | 0x04);
 		cx24123_writereg(state, 0x0f, 0x10);
 		break;
 	case FEC_5_6:
-		dprintk("%s:  set FEC to 5/6\n",__FUNCTION__);
+		dprintk("set FEC to 5/6\n");
 		cx24123_writereg(state, 0x0e, nom_reg | 0x05);
 		cx24123_writereg(state, 0x0f, 0x20);
 		break;
 	case FEC_6_7:
-		dprintk("%s:  set FEC to 6/7\n",__FUNCTION__);
+		dprintk("set FEC to 6/7\n");
 		cx24123_writereg(state, 0x0e, nom_reg | 0x06);
 		cx24123_writereg(state, 0x0f, 0x40);
 		break;
 	case FEC_7_8:
-		dprintk("%s:  set FEC to 7/8\n",__FUNCTION__);
+		dprintk("set FEC to 7/8\n");
 		cx24123_writereg(state, 0x0e, nom_reg | 0x07);
 		cx24123_writereg(state, 0x0f, 0x80);
 		break;
 	case FEC_AUTO:
-		dprintk("%s:  set FEC to auto\n",__FUNCTION__);
+		dprintk("set FEC to auto\n");
 		cx24123_writereg(state, 0x0f, 0xfe);
 		break;
 	default:
@@ -490,7 +507,8 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
 	tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
 	cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);
 
-	dprintk("%s: srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", __FUNCTION__, srate, ratio, sample_rate, sample_gain);
+	dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n",
+		srate, ratio, sample_rate, sample_gain);
 
 	return 0;
 }
@@ -570,7 +588,7 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
 	struct cx24123_state *state = fe->demodulator_priv;
 	unsigned long timeout;
 
-	dprintk("%s:  pll writereg called, data=0x%08x\n",__FUNCTION__,data);
+	dprintk("pll writereg called, data=0x%08x\n", data);
 
 	/* align the 21 bytes into to bit23 boundary */
 	data = data << 3;
@@ -583,7 +601,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
 	cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
 	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
 		if (time_after(jiffies, timeout)) {
-			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
+			err("%s:  demodulator is not responding, "\
+				"possibly hung, aborting.\n", __func__);
 			return -EREMOTEIO;
 		}
 		msleep(10);
@@ -594,7 +613,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
 	cx24123_writereg(state, 0x22, (data>>8) & 0xff );
 	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
 		if (time_after(jiffies, timeout)) {
-			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
+			err("%s:  demodulator is not responding, "\
+				"possibly hung, aborting.\n", __func__);
 			return -EREMOTEIO;
 		}
 		msleep(10);
@@ -605,7 +625,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
 	cx24123_writereg(state, 0x22, (data) & 0xff );
 	while ((cx24123_readreg(state, 0x20) & 0x80)) {
 		if (time_after(jiffies, timeout)) {
-			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
+			err("%s:  demodulator is not responding," \
+				"possibly hung, aborting.\n", __func__);
 			return -EREMOTEIO;
 		}
 		msleep(10);
@@ -626,7 +647,7 @@ static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_paramet
 	dprintk("frequency=%i\n", p->frequency);
 
 	if (cx24123_pll_calculate(fe, p) != 0) {
-		printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__);
+		err("%s: cx24123_pll_calcutate failed\n", __func__);
 		return -EINVAL;
 	}
 
@@ -643,18 +664,38 @@ static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_paramet
 	cx24123_writereg(state, 0x27, state->FILTune >> 2);
 	cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));
 
-	dprintk("%s:  pll tune VCA=%d, band=%d, pll=%d\n",__FUNCTION__,state->VCAarg,
-			state->bandselectarg,state->pllarg);
+	dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg,
+			state->bandselectarg, state->pllarg);
 
 	return 0;
 }
 
+
+/*
+ * 0x23:
+ *    [7:7] = BTI enabled
+ *    [6:6] = I2C repeater enabled
+ *    [5:5] = I2C repeater start
+ *    [0:0] = BTI start
+ */
+
+/* mode == 1 -> i2c-repeater, 0 -> bti */
+static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
+{
+	u8 r = cx24123_readreg(state, 0x23) & 0x1e;
+	if (mode)
+		r |= (1 << 6) | (start << 5);
+	else
+		r |= (1 << 7) | (start);
+	return cx24123_writereg(state, 0x23, r);
+}
+
 static int cx24123_initfe(struct dvb_frontend* fe)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 	int i;
 
-	dprintk("%s:  init frontend\n",__FUNCTION__);
+	dprintk("init frontend\n");
 
 	/* Configure the demod to a good set of defaults */
 	for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
@@ -664,6 +705,9 @@ static int cx24123_initfe(struct dvb_frontend* fe)
 	if(state->config->lnb_polarity)
 		cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02);
 
+	if (state->config->dont_use_pll)
+	cx24123_repeater_mode(state, 1, 0);
+
 	return 0;
 }
 
@@ -676,10 +720,10 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
 
 	switch (voltage) {
 	case SEC_VOLTAGE_13:
-		dprintk("%s: setting voltage 13V\n", __FUNCTION__);
+		dprintk("setting voltage 13V\n");
 		return cx24123_writereg(state, 0x29, val & 0x7f);
 	case SEC_VOLTAGE_18:
-		dprintk("%s: setting voltage 18V\n", __FUNCTION__);
+		dprintk("setting voltage 18V\n");
 		return cx24123_writereg(state, 0x29, val | 0x80);
 	case SEC_VOLTAGE_OFF:
 		/* already handled in cx88-dvb */
@@ -697,7 +741,8 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
 	unsigned long timeout = jiffies + msecs_to_jiffies(200);
 	while (!(cx24123_readreg(state, 0x29) & 0x40)) {
 		if(time_after(jiffies, timeout)) {
-			printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__);
+			err("%s: diseqc queue not ready, " \
+				"command may be lost.\n", __func__);
 			break;
 		}
 		msleep(10);
@@ -709,7 +754,7 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
 	struct cx24123_state *state = fe->demodulator_priv;
 	int i, val, tone;
 
-	dprintk("%s:\n",__FUNCTION__);
+	dprintk("\n");
 
 	/* stop continuous tone if enabled */
 	tone = cx24123_readreg(state, 0x29);
@@ -744,7 +789,7 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
 	struct cx24123_state *state = fe->demodulator_priv;
 	int val, tone;
 
-	dprintk("%s:\n", __FUNCTION__);
+	dprintk("\n");
 
 	/* stop continuous tone if enabled */
 	tone = cx24123_readreg(state, 0x29);
@@ -778,13 +823,21 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
 static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
-
 	int sync = cx24123_readreg(state, 0x14);
-	int lock = cx24123_readreg(state, 0x20);
 
 	*status = 0;
-	if (lock & 0x01)
-		*status |= FE_HAS_SIGNAL;
+	if (state->config->dont_use_pll) {
+		u32 tun_status = 0;
+		if (fe->ops.tuner_ops.get_status)
+			fe->ops.tuner_ops.get_status(fe, &tun_status);
+		if (tun_status & TUNER_STATUS_LOCKED)
+			*status |= FE_HAS_SIGNAL;
+	} else {
+		int lock = cx24123_readreg(state, 0x20);
+		if (lock & 0x01)
+			*status |= FE_HAS_SIGNAL;
+	}
+
 	if (sync & 0x02)
 		*status |= FE_HAS_CARRIER;	/* Phase locked */
 	if (sync & 0x04)
@@ -803,7 +856,7 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
  * Configured to return the measurement of errors in blocks, because no UCBLOCKS value
  * is available, so this value doubles up to satisfy both measurements
  */
-static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
+static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 
@@ -813,23 +866,24 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
 		(cx24123_readreg(state, 0x1d) << 8 |
 		 cx24123_readreg(state, 0x1e));
 
-	dprintk("%s:  BER = %d\n",__FUNCTION__,*ber);
+	dprintk("BER = %d\n", *ber);
 
 	return 0;
 }
 
-static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+static int cx24123_read_signal_strength(struct dvb_frontend *fe,
+	u16 *signal_strength)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 
 	*signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
 
-	dprintk("%s:  Signal strength = %d\n",__FUNCTION__,*signal_strength);
+	dprintk("Signal strength = %d\n", *signal_strength);
 
 	return 0;
 }
 
-static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
+static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 
@@ -838,16 +892,17 @@ static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
 	*snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
 			 (u16)cx24123_readreg(state, 0x19));
 
-	dprintk("%s:  read S/N index = %d\n",__FUNCTION__,*snr);
+	dprintk("read S/N index = %d\n", *snr);
 
 	return 0;
 }
 
-static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx24123_set_frontend(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 
-	dprintk("%s:  set_frontend\n",__FUNCTION__);
+	dprintk("\n");
 
 	if (state->config->set_ts_params)
 		state->config->set_ts_params(fe, 0);
@@ -858,13 +913,22 @@ static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 	cx24123_set_inversion(state, p->inversion);
 	cx24123_set_fec(state, p->u.qpsk.fec_inner);
 	cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate);
-	cx24123_pll_tune(fe, p);
+
+	if (!state->config->dont_use_pll)
+		cx24123_pll_tune(fe, p);
+	else if (fe->ops.tuner_ops.set_params)
+		fe->ops.tuner_ops.set_params(fe, p);
+	else
+		err("it seems I don't have a tuner...");
 
 	/* Enable automatic aquisition and reset cycle */
 	cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
 	cx24123_writereg(state, 0x00, 0x10);
 	cx24123_writereg(state, 0x00, 0);
 
+	if (state->config->agc_callback)
+		state->config->agc_callback(fe);
+
 	return 0;
 }
 
@@ -872,14 +936,14 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 {
 	struct cx24123_state *state = fe->demodulator_priv;
 
-	dprintk("%s:  get_frontend\n",__FUNCTION__);
+	dprintk("\n");
 
 	if (cx24123_get_inversion(state, &p->inversion) != 0) {
-		printk("%s: Failed to get inversion status\n",__FUNCTION__);
+		err("%s: Failed to get inversion status\n", __func__);
 		return -EREMOTEIO;
 	}
 	if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) {
-		printk("%s: Failed to get fec status\n",__FUNCTION__);
+		err("%s: Failed to get fec status\n", __func__);
 		return -EREMOTEIO;
 	}
 	p->frequency = state->currentfreq;
@@ -900,13 +964,13 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 
 	switch (tone) {
 	case SEC_TONE_ON:
-		dprintk("%s: setting tone on\n", __FUNCTION__);
+		dprintk("setting tone on\n");
 		return cx24123_writereg(state, 0x29, val | 0x10);
 	case SEC_TONE_OFF:
-		dprintk("%s: setting tone off\n",__FUNCTION__);
+		dprintk("setting tone off\n");
 		return cx24123_writereg(state, 0x29, val & 0xef);
 	default:
-		printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
+		err("CASE reached default with tone=%d\n", tone);
 		return -EINVAL;
 	}
 
@@ -939,47 +1003,86 @@ static int cx24123_get_algo(struct dvb_frontend *fe)
 static void cx24123_release(struct dvb_frontend* fe)
 {
 	struct cx24123_state* state = fe->demodulator_priv;
-	dprintk("%s\n",__FUNCTION__);
+	dprintk("\n");
+	i2c_del_adapter(&state->tuner_i2c_adapter);
 	kfree(state);
 }
 
+static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap,
+	struct i2c_msg msg[], int num)
+{
+	struct cx24123_state *state = i2c_get_adapdata(i2c_adap);
+	/* this repeater closes after the first stop */
+    cx24123_repeater_mode(state, 1, 1);
+	return i2c_transfer(state->i2c, msg, num);
+}
+
+static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm cx24123_tuner_i2c_algo = {
+	.master_xfer   = cx24123_tuner_i2c_tuner_xfer,
+	.functionality = cx24123_tuner_i2c_func,
+};
+
+struct i2c_adapter *
+	cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	return &state->tuner_i2c_adapter;
+}
+EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
+
 static struct dvb_frontend_ops cx24123_ops;
 
 struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
 				    struct i2c_adapter* i2c)
 {
-	struct cx24123_state* state = NULL;
-	int ret;
-
-	dprintk("%s\n",__FUNCTION__);
+	struct cx24123_state *state =
+		kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
 
+	dprintk("\n");
 	/* allocate memory for the internal state */
-	state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL);
 	if (state == NULL) {
-		printk("Unable to kmalloc\n");
+		err("Unable to kmalloc\n");
 		goto error;
 	}
 
 	/* setup the state */
 	state->config = config;
 	state->i2c = i2c;
-	state->VCAarg = 0;
-	state->VGAarg = 0;
-	state->bandselectarg = 0;
-	state->pllarg = 0;
-	state->currentfreq = 0;
-	state->currentsymbolrate = 0;
 
 	/* check if the demod is there */
-	ret = cx24123_readreg(state, 0x00);
-	if ((ret != 0xd1) && (ret != 0xe1)) {
-		printk("Version != d1 or e1\n");
+	state->demod_rev = cx24123_readreg(state, 0x00);
+	switch (state->demod_rev) {
+	case 0xe1: info("detected CX24123C\n"); break;
+	case 0xd1: info("detected CX24123\n"); break;
+	default:
+		err("wrong demod revision: %x\n", state->demod_rev);
 		goto error;
 	}
 
 	/* create dvb_frontend */
 	memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
 	state->frontend.demodulator_priv = state;
+
+    /* create tuner i2c adapter */
+    if (config->dont_use_pll)
+	cx24123_repeater_mode(state, 1, 0);
+
+	strncpy(state->tuner_i2c_adapter.name,
+		"CX24123 tuner I2C bus", I2C_NAME_SIZE);
+	state->tuner_i2c_adapter.class     = I2C_CLASS_TV_DIGITAL,
+	state->tuner_i2c_adapter.algo      = &cx24123_tuner_i2c_algo;
+	state->tuner_i2c_adapter.algo_data = NULL;
+	i2c_set_adapdata(&state->tuner_i2c_adapter, state);
+	if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
+	err("tuner i2c bus could not be initialized\n");
+		goto error;
+	}
+
 	return &state->frontend;
 
 error:
@@ -1029,7 +1132,8 @@ MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
 module_param(force_band, int, 0644);
 MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off).");
 
-MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware");
+MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
+	"CX24123/CX24109/CX24113 hardware");
 MODULE_AUTHOR("Steven Toth");
 MODULE_LICENSE("GPL");
 

+ 16 - 5
drivers/media/dvb/frontends/cx24123.h

@@ -33,16 +33,27 @@ struct cx24123_config
 
 	/* 0 = LNB voltage normal, 1 = LNB voltage inverted */
 	int lnb_polarity;
+
+	/* this device has another tuner */
+	u8 dont_use_pll;
+	void (*agc_callback) (struct dvb_frontend *);
 };
 
 #if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE))
-extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
-					   struct i2c_adapter* i2c);
+extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
+					   struct i2c_adapter *i2c);
+extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
 #else
-static inline struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
-						  struct i2c_adapter* i2c)
+static inline struct dvb_frontend *cx24123_attach(
+	const struct cx24123_config *config, struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+static struct i2c_adapter *
+	cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif // CONFIG_DVB_CX24123

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

@@ -48,7 +48,7 @@ extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config
 static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
 					     struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif // CONFIG_DVB_DIB3000MB

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

@@ -44,7 +44,7 @@ extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i
 #else
 static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif // CONFIG_DVB_DIB3000MC

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

@@ -1168,7 +1168,7 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
 	ret = dib7000p_tune(fe, fep);
 
 	/* make this a config parameter */
-	dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO);
+	dib7000p_set_output_mode(state, state->cfg.output_mode);
     return ret;
 }
 
@@ -1330,6 +1330,12 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
 	st->gpio_val = cfg->gpio_val;
 	st->gpio_dir = cfg->gpio_dir;
 
+	/* Ensure the output mode remains at the previous default if it's
+	 * not specifically set by the caller.
+	 */
+	if (st->cfg.output_mode != OUTMODE_MPEG2_SERIAL)
+		st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
+
 	demod                   = &st->demod;
 	demod->demodulator_priv = st;
 	memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));

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

@@ -31,6 +31,8 @@ struct dib7000p_config {
 	u8 spur_protect;
 
 	int (*agc_control) (struct dvb_frontend *, u8 before);
+
+	u8 output_mode;
 };
 
 #define DEFAULT_DIB7000P_I2C_ADDRESS 18

+ 1 - 259
drivers/media/dvb/frontends/dvb-pll.c

@@ -44,14 +44,10 @@ struct dvb_pll_priv {
 
 static unsigned int dvb_pll_devcount;
 
-static int debug = 0;
+static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "enable verbose debug messages");
 
-static unsigned int input[DVB_PLL_MAX] = { [ 0 ... (DVB_PLL_MAX-1) ] = 0 };
-module_param_array(input, int, NULL, 0644);
-MODULE_PARM_DESC(input,"specify rf input choice, 0 for autoselect (default)");
-
 static unsigned int id[DVB_PLL_MAX] =
 	{ [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED };
 module_param_array(id, int, NULL, 0644);
@@ -80,23 +76,6 @@ struct dvb_pll_desc {
 /* ----------------------------------------------------------- */
 /* descriptions                                                */
 
-/* Set AGC TOP value to 103 dBuV:
-	0x80 = Control Byte
-	0x40 = 250 uA charge pump (irrelevant)
-	0x18 = Aux Byte to follow
-	0x06 = 64.5 kHz divider (irrelevant)
-	0x01 = Disable Vt (aka sleep)
-
-	0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA)
-	0x50 = AGC Take over point = 103 dBuV */
-static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 };
-
-/*	0x04 = 166.67 kHz divider
-
-	0x80 = AGC Time constant 50ms Iagc = 9 uA
-	0x20 = AGC Take over point = 112 dBuV */
-static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 };
-
 static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
 	.name  = "Thomson dtt7579",
 	.min   = 177000000,
@@ -112,19 +91,6 @@ static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
 	},
 };
 
-static struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
-	.name  = "Thomson dtt7610",
-	.min   =  44000000,
-	.max   = 958000000,
-	.iffreq= 44000000,
-	.count = 3,
-	.entries = {
-		{ 157250000, 62500, 0x8e, 0x39 },
-		{ 454000000, 62500, 0x8e, 0x3a },
-		{ 999999999, 62500, 0x8e, 0x3c },
-	},
-};
-
 static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf,
 			       const struct dvb_frontend_parameters *params)
 {
@@ -165,34 +131,6 @@ static struct dvb_pll_desc dvb_pll_lg_z201 = {
 	},
 };
 
-static struct dvb_pll_desc dvb_pll_microtune_4042 = {
-	.name  = "Microtune 4042 FI5",
-	.min   =  57000000,
-	.max   = 858000000,
-	.iffreq= 44000000,
-	.count = 3,
-	.entries = {
-		{ 162000000, 62500, 0x8e, 0xa1 },
-		{ 457000000, 62500, 0x8e, 0x91 },
-		{ 999999999, 62500, 0x8e, 0x31 },
-	},
-};
-
-static struct dvb_pll_desc dvb_pll_thomson_dtt761x = {
-	/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
-	.name  = "Thomson dtt761x",
-	.min   =  57000000,
-	.max   = 863000000,
-	.iffreq= 44000000,
-	.count = 3,
-	.initdata = tua603x_agc103,
-	.entries = {
-		{ 147000000, 62500, 0x8e, 0x39 },
-		{ 417000000, 62500, 0x8e, 0x3a },
-		{ 999999999, 62500, 0x8e, 0x3c },
-	},
-};
-
 static struct dvb_pll_desc dvb_pll_unknown_1 = {
 	.name  = "unknown 1", /* used by dntv live dvb-t */
 	.min   = 174000000,
@@ -301,54 +239,6 @@ static struct dvb_pll_desc dvb_pll_tua6034 = {
 	},
 };
 
-/* Infineon TUA6034
- * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F
- */
-static struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = {
-	.name  = "LG TDVS-H06xF",
-	.min   =  54000000,
-	.max   = 863000000,
-	.iffreq= 44000000,
-	.initdata = tua603x_agc103,
-	.count = 3,
-	.entries = {
-		{  165000000, 62500, 0xce, 0x01 },
-		{  450000000, 62500, 0xce, 0x02 },
-		{  999999999, 62500, 0xce, 0x04 },
-	},
-};
-
-/* Philips FMD1216ME
- * used in Medion Hybrid PCMCIA card and USB Box
- */
-static void fmd1216me_bw(struct dvb_frontend *fe, u8 *buf,
-			 const struct dvb_frontend_parameters *params)
-{
-	if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ &&
-	    params->frequency >= 158870000)
-		buf[3] |= 0x08;
-}
-
-static struct dvb_pll_desc dvb_pll_fmd1216me = {
-	.name = "Philips FMD1216ME",
-	.min = 50870000,
-	.max = 858000000,
-	.iffreq= 36125000,
-	.set   = fmd1216me_bw,
-	.initdata = tua603x_agc112,
-	.sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
-	.count = 7,
-	.entries = {
-		{ 143870000, 166667, 0xbc, 0x41 },
-		{ 158870000, 166667, 0xf4, 0x41 },
-		{ 329870000, 166667, 0xbc, 0x42 },
-		{ 441870000, 166667, 0xf4, 0x42 },
-		{ 625870000, 166667, 0xbc, 0x44 },
-		{ 803870000, 166667, 0xf4, 0x44 },
-		{ 999999999, 166667, 0xfc, 0x44 },
-	}
-};
-
 /* ALPS TDED4
  * used in Nebula-Cards and USB boxes
  */
@@ -391,55 +281,6 @@ static struct dvb_pll_desc dvb_pll_tdhu2 = {
 	}
 };
 
-/* Philips TUV1236D
- * used in ATI HDTV Wonder
- */
-static void tuv1236d_rf(struct dvb_frontend *fe, u8 *buf,
-			const struct dvb_frontend_parameters *params)
-{
-	struct dvb_pll_priv *priv = fe->tuner_priv;
-	unsigned int new_rf = input[priv->nr];
-
-	if ((new_rf == 0) || (new_rf > 2)) {
-		switch (params->u.vsb.modulation) {
-			case QAM_64:
-			case QAM_256:
-				new_rf = 1;
-				break;
-			case VSB_8:
-			default:
-				new_rf = 2;
-		}
-	}
-
-	switch (new_rf) {
-		case 1:
-			buf[3] |= 0x08;
-			break;
-		case 2:
-			buf[3] &= ~0x08;
-			break;
-		default:
-			printk(KERN_WARNING
-			       "%s: unhandled rf input selection: %d",
-			       __FUNCTION__, new_rf);
-	}
-}
-
-static struct dvb_pll_desc dvb_pll_tuv1236d = {
-	.name  = "Philips TUV1236D",
-	.min   =  54000000,
-	.max   = 864000000,
-	.iffreq= 44000000,
-	.set   = tuv1236d_rf,
-	.count = 3,
-	.entries = {
-		{ 157250000, 62500, 0xc6, 0x41 },
-		{ 454000000, 62500, 0xc6, 0x42 },
-		{ 999999999, 62500, 0xc6, 0x44 },
-	},
-};
-
 /* Samsung TBMV30111IN / TBMV30712IN1
  * used in Air2PC ATSC - 2nd generation (nxt2002)
  */
@@ -476,64 +317,6 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
 	},
 };
 
-/*
- * Philips TD1316 Tuner.
- */
-static void td1316_bw(struct dvb_frontend *fe, u8 *buf,
-		      const struct dvb_frontend_parameters *params)
-{
-	u8 band;
-
-	/* determine band */
-	if (params->frequency < 161000000)
-		band = 1;
-	else if (params->frequency < 444000000)
-		band = 2;
-	else
-		band = 4;
-
-	buf[3] |= band;
-
-	/* setup PLL filter */
-	if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
-		buf[3] |= 1 << 3;
-}
-
-static struct dvb_pll_desc dvb_pll_philips_td1316 = {
-	.name  = "Philips TD1316",
-	.min   =  87000000,
-	.max   = 895000000,
-	.iffreq= 36166667,
-	.set   = td1316_bw,
-	.count = 9,
-	.entries = {
-		{  93834000, 166667, 0xca, 0x60},
-		{ 123834000, 166667, 0xca, 0xa0},
-		{ 163834000, 166667, 0xca, 0xc0},
-		{ 253834000, 166667, 0xca, 0x60},
-		{ 383834000, 166667, 0xca, 0xa0},
-		{ 443834000, 166667, 0xca, 0xc0},
-		{ 583834000, 166667, 0xca, 0x60},
-		{ 793834000, 166667, 0xca, 0xa0},
-		{ 858834000, 166667, 0xca, 0xe0},
-	},
-};
-
-/* FE6600 used on DViCO Hybrid */
-static struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
-	.name = "Thomson FE6600",
-	.min =  44250000,
-	.max = 858000000,
-	.iffreq= 36125000,
-	.count = 4,
-	.entries = {
-		{ 250000000, 166667, 0xb4, 0x12 },
-		{ 455000000, 166667, 0xfe, 0x11 },
-		{ 775500000, 166667, 0xbc, 0x18 },
-		{ 999999999, 166667, 0xf4, 0x18 },
-	}
-};
-
 static void opera1_bw(struct dvb_frontend *fe, u8 *buf,
 		      const struct dvb_frontend_parameters *params)
 {
@@ -560,50 +343,23 @@ static struct dvb_pll_desc dvb_pll_opera1 = {
 	}
 };
 
-/* Philips FCV1236D
- */
-static struct dvb_pll_desc dvb_pll_fcv1236d = {
-/* Bit_0: RF Input select
- * Bit_1: 0=digital, 1=analog
- */
-	.name  = "Philips FCV1236D",
-	.min   =  53000000,
-	.max   = 803000000,
-	.iffreq= 44000000,
-	.count = 3,
-	.entries = {
-		{ 159000000, 62500, 0x8e, 0xa0 },
-		{ 453000000, 62500, 0x8e, 0x90 },
-		{ 999999999, 62500, 0x8e, 0x30 },
-	},
-};
-
 /* ----------------------------------------------------------- */
 
 static struct dvb_pll_desc *pll_list[] = {
 	[DVB_PLL_UNDEFINED]              = NULL,
 	[DVB_PLL_THOMSON_DTT7579]        = &dvb_pll_thomson_dtt7579,
 	[DVB_PLL_THOMSON_DTT759X]        = &dvb_pll_thomson_dtt759x,
-	[DVB_PLL_THOMSON_DTT7610]        = &dvb_pll_thomson_dtt7610,
 	[DVB_PLL_LG_Z201]                = &dvb_pll_lg_z201,
-	[DVB_PLL_MICROTUNE_4042]         = &dvb_pll_microtune_4042,
-	[DVB_PLL_THOMSON_DTT761X]        = &dvb_pll_thomson_dtt761x,
 	[DVB_PLL_UNKNOWN_1]              = &dvb_pll_unknown_1,
 	[DVB_PLL_TUA6010XS]              = &dvb_pll_tua6010xs,
 	[DVB_PLL_ENV57H1XD5]             = &dvb_pll_env57h1xd5,
 	[DVB_PLL_TUA6034]                = &dvb_pll_tua6034,
-	[DVB_PLL_LG_TDVS_H06XF]          = &dvb_pll_lg_tdvs_h06xf,
 	[DVB_PLL_TDA665X]                = &dvb_pll_tda665x,
-	[DVB_PLL_FMD1216ME]              = &dvb_pll_fmd1216me,
 	[DVB_PLL_TDED4]                  = &dvb_pll_tded4,
-	[DVB_PLL_TUV1236D]               = &dvb_pll_tuv1236d,
 	[DVB_PLL_TDHU2]                  = &dvb_pll_tdhu2,
 	[DVB_PLL_SAMSUNG_TBMV]           = &dvb_pll_samsung_tbmv,
 	[DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
-	[DVB_PLL_PHILIPS_TD1316]         = &dvb_pll_philips_td1316,
-	[DVB_PLL_THOMSON_FE6600]         = &dvb_pll_thomson_fe6600,
 	[DVB_PLL_OPERA1]                 = &dvb_pll_opera1,
-	[DVB_PLL_FCV1236D]               = &dvb_pll_fcv1236d,
 };
 
 /* ----------------------------------------------------------- */
@@ -849,20 +605,6 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
 		       id[priv->nr] == pll_desc_id ?
 				"insmod option" : "autodetected");
 	}
-	if ((debug) || (input[priv->nr] > 0)) {
-		printk("dvb-pll[%d]", priv->nr);
-		if (i2c != NULL)
-			printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr);
-		printk(": tuner rf input will be ");
-		switch (input[priv->nr]) {
-		case 0:
-			printk("autoselected\n");
-			break;
-		default:
-			printk("set to input %d (insmod option)\n",
-			       input[priv->nr]);
-		}
-	}
 
 	return fe;
 }

+ 12 - 21
drivers/media/dvb/frontends/dvb-pll.h

@@ -11,26 +11,17 @@
 #define DVB_PLL_UNDEFINED               0
 #define DVB_PLL_THOMSON_DTT7579         1
 #define DVB_PLL_THOMSON_DTT759X         2
-#define DVB_PLL_THOMSON_DTT7610         3
-#define DVB_PLL_LG_Z201                 4
-#define DVB_PLL_MICROTUNE_4042          5
-#define DVB_PLL_THOMSON_DTT761X         6
-#define DVB_PLL_UNKNOWN_1               7
-#define DVB_PLL_TUA6010XS               8
-#define DVB_PLL_ENV57H1XD5              9
-#define DVB_PLL_TUA6034                10
-#define DVB_PLL_LG_TDVS_H06XF          11
-#define DVB_PLL_TDA665X                12
-#define DVB_PLL_FMD1216ME              13
-#define DVB_PLL_TDED4                  14
-#define DVB_PLL_TUV1236D               15
-#define DVB_PLL_TDHU2                  16
-#define DVB_PLL_SAMSUNG_TBMV           17
-#define DVB_PLL_PHILIPS_SD1878_TDA8261 18
-#define DVB_PLL_PHILIPS_TD1316         19
-#define DVB_PLL_THOMSON_FE6600         20
-#define DVB_PLL_OPERA1                 21
-#define DVB_PLL_FCV1236D               22
+#define DVB_PLL_LG_Z201                 3
+#define DVB_PLL_UNKNOWN_1               4
+#define DVB_PLL_TUA6010XS               5
+#define DVB_PLL_ENV57H1XD5              6
+#define DVB_PLL_TUA6034                 7
+#define DVB_PLL_TDA665X                 8
+#define DVB_PLL_TDED4                   9
+#define DVB_PLL_TDHU2                  10
+#define DVB_PLL_SAMSUNG_TBMV           11
+#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
+#define DVB_PLL_OPERA1                 13
 
 /**
  * Attach a dvb-pll to the supplied frontend structure.
@@ -52,7 +43,7 @@ static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
 					   struct i2c_adapter *i2c,
 					   unsigned int pll_desc_id)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif

+ 164 - 0
drivers/media/dvb/frontends/isl6405.c

@@ -0,0 +1,164 @@
+/*
+ * isl6405.c - driver for dual lnb supply and control ic ISL6405
+ *
+ * Copyright (C) 2008 Hartmut Hackmann
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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.
+ *
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "isl6405.h"
+
+struct isl6405 {
+	u8			config;
+	u8			override_or;
+	u8			override_and;
+	struct i2c_adapter	*i2c;
+	u8			i2c_addr;
+};
+
+static int isl6405_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv;
+	struct i2c_msg msg = {	.addr = isl6405->i2c_addr, .flags = 0,
+				.buf = &isl6405->config,
+				.len = sizeof(isl6405->config) };
+
+	if (isl6405->override_or & 0x80) {
+		isl6405->config &= ~(ISL6405_VSEL2 | ISL6405_EN2);
+		switch (voltage) {
+		case SEC_VOLTAGE_OFF:
+			break;
+		case SEC_VOLTAGE_13:
+			isl6405->config |= ISL6405_EN2;
+			break;
+		case SEC_VOLTAGE_18:
+			isl6405->config |= (ISL6405_EN2 | ISL6405_VSEL2);
+			break;
+		default:
+			return -EINVAL;
+		}
+	} else {
+		isl6405->config &= ~(ISL6405_VSEL1 | ISL6405_EN1);
+		switch (voltage) {
+		case SEC_VOLTAGE_OFF:
+			break;
+		case SEC_VOLTAGE_13:
+			isl6405->config |= ISL6405_EN1;
+			break;
+		case SEC_VOLTAGE_18:
+			isl6405->config |= (ISL6405_EN1 | ISL6405_VSEL1);
+			break;
+		default:
+			return -EINVAL;
+		};
+	}
+	isl6405->config |= isl6405->override_or;
+	isl6405->config &= isl6405->override_and;
+
+	return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static int isl6405_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
+{
+	struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv;
+	struct i2c_msg msg = {	.addr = isl6405->i2c_addr, .flags = 0,
+				.buf = &isl6405->config,
+				.len = sizeof(isl6405->config) };
+
+	if (isl6405->override_or & 0x80) {
+		if (arg)
+			isl6405->config |= ISL6405_LLC2;
+		else
+			isl6405->config &= ~ISL6405_LLC2;
+	} else {
+		if (arg)
+			isl6405->config |= ISL6405_LLC1;
+		else
+			isl6405->config &= ~ISL6405_LLC1;
+	}
+	isl6405->config |= isl6405->override_or;
+	isl6405->config &= isl6405->override_and;
+
+	return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO;
+}
+
+static void isl6405_release(struct dvb_frontend *fe)
+{
+	/* power off */
+	isl6405_set_voltage(fe, SEC_VOLTAGE_OFF);
+
+	/* free */
+	kfree(fe->sec_priv);
+	fe->sec_priv = NULL;
+}
+
+struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c,
+				    u8 i2c_addr, u8 override_set, u8 override_clear)
+{
+	struct isl6405 *isl6405 = kmalloc(sizeof(struct isl6405), GFP_KERNEL);
+	if (!isl6405)
+		return NULL;
+
+	/* default configuration */
+	if (override_set & 0x80)
+		isl6405->config = ISL6405_ISEL2;
+	else
+		isl6405->config = ISL6405_ISEL1;
+	isl6405->i2c = i2c;
+	isl6405->i2c_addr = i2c_addr;
+	fe->sec_priv = isl6405;
+
+	/* bits which should be forced to '1' */
+	isl6405->override_or = override_set;
+
+	/* bits which should be forced to '0' */
+	isl6405->override_and = ~override_clear;
+
+	/* detect if it is present or not */
+	if (isl6405_set_voltage(fe, SEC_VOLTAGE_OFF)) {
+		kfree(isl6405);
+		fe->sec_priv = NULL;
+		return NULL;
+	}
+
+	/* install release callback */
+	fe->ops.release_sec = isl6405_release;
+
+	/* override frontend ops */
+	fe->ops.set_voltage = isl6405_set_voltage;
+	fe->ops.enable_high_lnb_voltage = isl6405_enable_high_lnb_voltage;
+
+	return fe;
+}
+EXPORT_SYMBOL(isl6405_attach);
+
+MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405");
+MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss");
+MODULE_LICENSE("GPL");

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

@@ -0,0 +1,74 @@
+/*
+ * isl6405.h - driver for dual lnb supply and control ic ISL6405
+ *
+ * Copyright (C) 2008 Hartmut Hackmann
+ * Copyright (C) 2006 Oliver Endriss
+ *
+ * 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.
+ *
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef _ISL6405_H
+#define _ISL6405_H
+
+#include <linux/dvb/frontend.h>
+
+/* system register bits */
+
+/* this bit selects register (control) 1 or 2
+   note that the bit maps are different */
+
+#define ISL6405_SR	0x80
+
+/* SR = 0 */
+#define ISL6405_OLF1	0x01
+#define ISL6405_EN1	0x02
+#define ISL6405_VSEL1	0x04
+#define ISL6405_LLC1	0x08
+#define ISL6405_ENT1	0x10
+#define ISL6405_ISEL1	0x20
+#define ISL6405_DCL	0x40
+
+/* SR = 1 */
+#define ISL6405_OLF2	0x01
+#define ISL6405_OTF	0x02
+#define ISL6405_EN2	0x04
+#define ISL6405_VSEL2	0x08
+#define ISL6405_LLC2	0x10
+#define ISL6405_ENT2	0x20
+#define ISL6405_ISEL2	0x40
+
+#if defined(CONFIG_DVB_ISL6405) || (defined(CONFIG_DVB_ISL6405_MODULE) && defined(MODULE))
+/* override_set and override_clear control which system register bits (above)
+ * to always set & clear
+ */
+extern struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c,
+					   u8 i2c_addr, u8 override_set, u8 override_clear);
+#else
+static inline struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe,
+						  struct i2c_adapter *i2c, u8 i2c_addr,
+						  u8 override_set, u8 override_clear)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_ISL6405 */
+
+#endif

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

@@ -47,7 +47,7 @@ extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_a
 static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
 						  u8 override_set, u8 override_clear)
 {
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 }
 #endif // CONFIG_DVB_ISL6421

+ 400 - 0
drivers/media/dvb/frontends/itd1000.c

@@ -0,0 +1,400 @@
+/*
+ *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
+ *
+ *  Copyright (c) 2007-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  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.
+ *
+ *  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>
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "itd1000.h"
+#include "itd1000_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define deb(args...)  do { \
+	if (debug) { \
+		printk(KERN_DEBUG   "ITD1000: " args);\
+		printk("\n"); \
+	} \
+} while (0)
+
+#define warn(args...) do { \
+	printk(KERN_WARNING "ITD1000: " args); \
+	printk("\n"); \
+} while (0)
+
+#define info(args...) do { \
+	printk(KERN_INFO    "ITD1000: " args); \
+	printk("\n"); \
+} while (0)
+
+/* don't write more than one byte with flexcop behind */
+static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 len)
+{
+	u8 buf[1+len];
+	struct i2c_msg msg = {
+		.addr = state->cfg->i2c_address, .flags = 0, .buf = buf, .len = len+1
+	};
+	buf[0] = reg;
+	memcpy(&buf[1], v, len);
+
+	/* deb("wr %02x: %02x", reg, v[0]); */
+
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		printk(KERN_WARNING "itd1000 I2C write failed\n");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
+{
+	u8 val;
+	struct i2c_msg msg[2] = {
+		{ .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+		{ .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = &val, .len = 1 },
+	};
+
+	/* ugly flexcop workaround */
+	itd1000_write_regs(state, (reg - 1) & 0xff, &state->shadow[(reg - 1) & 0xff], 1);
+
+	if (i2c_transfer(state->i2c, msg, 2) != 2) {
+		warn("itd1000 I2C read failed");
+		return -EREMOTEIO;
+	}
+	return val;
+}
+
+static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
+{
+	int ret = itd1000_write_regs(state, r, &v, 1);
+	state->shadow[r] = v;
+	return ret;
+}
+
+
+static struct {
+	u32 symbol_rate;
+	u8  pgaext  : 4; /* PLLFH */
+	u8  bbgvmin : 4; /* BBGVMIN */
+} itd1000_lpf_pga[] = {
+	{        0, 0x8, 0x3 },
+	{  5200000, 0x8, 0x3 },
+	{ 12200000, 0x4, 0x3 },
+	{ 15400000, 0x2, 0x3 },
+	{ 19800000, 0x2, 0x3 },
+	{ 21500000, 0x2, 0x3 },
+	{ 24500000, 0x2, 0x3 },
+	{ 28400000, 0x2, 0x3 },
+	{ 33400000, 0x2, 0x3 },
+	{ 34400000, 0x1, 0x4 },
+	{ 34400000, 0x1, 0x4 },
+	{ 38400000, 0x1, 0x4 },
+	{ 38400000, 0x1, 0x4 },
+	{ 40400000, 0x1, 0x4 },
+	{ 45400000, 0x1, 0x4 },
+};
+
+static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate)
+{
+	u8 i;
+	u8 con1    = itd1000_read_reg(state, CON1)    & 0xfd;
+	u8 pllfh   = itd1000_read_reg(state, PLLFH)   & 0x0f;
+	u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0;
+	u8 bw      = itd1000_read_reg(state, BW)      & 0xf0;
+
+	deb("symbol_rate = %d", symbol_rate);
+
+	/* not sure what is that ? - starting to download the table */
+	itd1000_write_reg(state, CON1, con1 | (1 << 1));
+
+	for (i = 0; i < ARRAY_SIZE(itd1000_lpf_pga); i++)
+		if (symbol_rate < itd1000_lpf_pga[i].symbol_rate) {
+			deb("symrate: index: %d pgaext: %x, bbgvmin: %x", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin);
+			itd1000_write_reg(state, PLLFH,   pllfh | (itd1000_lpf_pga[i].pgaext << 4));
+			itd1000_write_reg(state, BBGVMIN, bbgvmin | (itd1000_lpf_pga[i].bbgvmin));
+			itd1000_write_reg(state, BW,      bw | (i & 0x0f));
+			break;
+		}
+
+	itd1000_write_reg(state, CON1, con1 | (0 << 1));
+}
+
+static struct {
+	u8 vcorg;
+	u32 fmax_rg;
+} itd1000_vcorg[] = {
+	{  1,  920000 },
+	{  2,  971000 },
+	{  3, 1031000 },
+	{  4, 1091000 },
+	{  5, 1171000 },
+	{  6, 1281000 },
+	{  7, 1381000 },
+	{  8,  500000 },	/* this is intentional. */
+	{  9, 1451000 },
+	{ 10, 1531000 },
+	{ 11, 1631000 },
+	{ 12, 1741000 },
+	{ 13, 1891000 },
+	{ 14, 2071000 },
+	{ 15, 2250000 },
+};
+
+static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz)
+{
+	u8 i;
+	u8 gvbb_i2c     = itd1000_read_reg(state, GVBB_I2C) & 0xbf;
+	u8 vco_chp1_i2c = itd1000_read_reg(state, VCO_CHP1_I2C) & 0x0f;
+	u8 adcout;
+
+	/* reserved bit again (reset ?) */
+	itd1000_write_reg(state, GVBB_I2C, gvbb_i2c | (1 << 6));
+
+	for (i = 0; i < ARRAY_SIZE(itd1000_vcorg); i++) {
+		if (freq_khz < itd1000_vcorg[i].fmax_rg) {
+			itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | (itd1000_vcorg[i].vcorg << 4));
+			msleep(1);
+
+			adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f;
+
+			deb("VCO: %dkHz: %d -> ADCOUT: %d %02x", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c);
+
+			if (adcout > 13) {
+				if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15))
+					itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg + 1) << 4));
+			} else if (adcout < 2) {
+				if (!(itd1000_vcorg[i].vcorg == 1 || itd1000_vcorg[i].vcorg == 9))
+					itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg - 1) << 4));
+			}
+			break;
+		}
+	}
+}
+
+struct {
+	u32 freq;
+	u8 values[10]; /* RFTR, RFST1 - RFST9 */
+} itd1000_fre_values[] = {
+	{ 1075000, { 0x59, 0x1d, 0x1c, 0x17, 0x16, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+	{ 1250000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+	{ 1450000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+	{ 1650000, { 0x69, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+	{ 1750000, { 0x69, 0x1e, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+	{ 1850000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
+	{ 1900000, { 0x69, 0x1d, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
+	{ 1950000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0d, 0x0b, 0x0a } },
+	{ 2050000, { 0x69, 0x1e, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0b, 0x0a } },
+	{ 2150000, { 0x69, 0x1d, 0x1c, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x0e, 0x0b } }
+};
+
+
+#define FREF 16
+
+static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz)
+{
+	int i, j;
+	u32 plln, pllf;
+	u64 tmp;
+
+	plln = (freq_khz * 1000) / 2 / FREF;
+
+	/* Compute the factional part times 1000 */
+	tmp  = plln % 1000000;
+	plln /= 1000000;
+
+	tmp *= 1048576;
+	do_div(tmp, 1000000);
+	pllf = (u32) tmp;
+
+	state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF;
+	deb("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d", freq_khz, state->frequency, pllf, plln);
+
+	itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */;
+	itd1000_write_reg(state, PLLNL, plln & 0xff);
+	itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f));
+	itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff);
+	itd1000_write_reg(state, PLLFL, (pllf >> 0) & 0xff);
+
+	for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) {
+		if (freq_khz <= itd1000_fre_values[i].freq) {
+			deb("fre_values: %d", i);
+			itd1000_write_reg(state, RFTR, itd1000_fre_values[i].values[0]);
+			for (j = 0; j < 9; j++)
+				itd1000_write_reg(state, RFST1+j, itd1000_fre_values[i].values[j+1]);
+			break;
+		}
+	}
+
+	itd1000_set_vco(state, freq_khz);
+}
+
+static int itd1000_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+	struct itd1000_state *state = fe->tuner_priv;
+	u8 pllcon1;
+
+	itd1000_set_lo(state, p->frequency);
+	itd1000_set_lpf_bw(state, p->u.qpsk.symbol_rate);
+
+	pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f;
+	itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7));
+	itd1000_write_reg(state, PLLCON1, pllcon1);
+
+	return 0;
+}
+
+static int itd1000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct itd1000_state *state = fe->tuner_priv;
+	*frequency = state->frequency;
+	return 0;
+}
+
+static int itd1000_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+	return 0;
+}
+
+static u8 itd1000_init_tab[][2] = {
+	{ PLLCON1,       0x65 }, /* Register does not change */
+	{ PLLNH,         0x80 }, /* Bits [7:6] do not change */
+	{ RESERVED_0X6D, 0x3b },
+	{ VCO_CHP2_I2C,  0x12 },
+	{ 0x72,          0xf9 }, /* No such regsister defined */
+	{ RESERVED_0X73, 0xff },
+	{ RESERVED_0X74, 0xb2 },
+	{ RESERVED_0X75, 0xc7 },
+	{ EXTGVBBRF,     0xf0 },
+	{ DIVAGCCK,      0x80 },
+	{ BBTR,          0xa0 },
+	{ RESERVED_0X7E, 0x4f },
+	{ 0x82,          0x88 }, /* No such regsister defined */
+	{ 0x83,          0x80 }, /* No such regsister defined */
+	{ 0x84,          0x80 }, /* No such regsister defined */
+	{ RESERVED_0X85, 0x74 },
+	{ RESERVED_0X86, 0xff },
+	{ RESERVED_0X88, 0x02 },
+	{ RESERVED_0X89, 0x16 },
+	{ RFST0,         0x1f },
+	{ RESERVED_0X94, 0x66 },
+	{ RESERVED_0X95, 0x66 },
+	{ RESERVED_0X96, 0x77 },
+	{ RESERVED_0X97, 0x99 },
+	{ RESERVED_0X98, 0xff },
+	{ RESERVED_0X99, 0xfc },
+	{ RESERVED_0X9A, 0xba },
+	{ RESERVED_0X9B, 0xaa },
+};
+
+static u8 itd1000_reinit_tab[][2] = {
+	{ VCO_CHP1_I2C, 0x8a },
+	{ BW,           0x87 },
+	{ GVBB_I2C,     0x03 },
+	{ BBGVMIN,      0x03 },
+	{ CON1,         0x2e },
+};
+
+
+static int itd1000_init(struct dvb_frontend *fe)
+{
+	struct itd1000_state *state = fe->tuner_priv;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(itd1000_init_tab); i++)
+		itd1000_write_reg(state, itd1000_init_tab[i][0], itd1000_init_tab[i][1]);
+
+	for (i = 0; i < ARRAY_SIZE(itd1000_reinit_tab); i++)
+		itd1000_write_reg(state, itd1000_reinit_tab[i][0], itd1000_reinit_tab[i][1]);
+
+	return 0;
+}
+
+static int itd1000_sleep(struct dvb_frontend *fe)
+{
+	return 0;
+}
+
+static int itd1000_release(struct dvb_frontend *fe)
+{
+	kfree(fe->tuner_priv);
+	fe->tuner_priv = NULL;
+	return 0;
+}
+
+static const struct dvb_tuner_ops itd1000_tuner_ops = {
+	.info = {
+		.name           = "Integrant ITD1000",
+		.frequency_min  = 950000,
+		.frequency_max  = 2150000,
+		.frequency_step = 125,     /* kHz for QPSK frontends */
+	},
+
+	.release       = itd1000_release,
+
+	.init          = itd1000_init,
+	.sleep         = itd1000_sleep,
+
+	.set_params    = itd1000_set_parameters,
+	.get_frequency = itd1000_get_frequency,
+	.get_bandwidth = itd1000_get_bandwidth
+};
+
+
+struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
+{
+	struct itd1000_state *state = NULL;
+	u8 i = 0;
+
+	state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL);
+	if (state == NULL)
+		return NULL;
+
+	state->cfg = cfg;
+	state->i2c = i2c;
+
+	i = itd1000_read_reg(state, 0);
+	if (i != 0) {
+		kfree(state);
+		return NULL;
+	}
+	info("successfully identified (ID: %d)", i);
+
+	memset(state->shadow, 0xff, sizeof(state->shadow));
+	for (i = 0x65; i < 0x9c; i++)
+		state->shadow[i] = itd1000_read_reg(state, i);
+
+	memcpy(&fe->ops.tuner_ops, &itd1000_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+	fe->tuner_priv = state;
+
+	return fe;
+}
+EXPORT_SYMBOL(itd1000_attach);
+
+MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
+MODULE_DESCRIPTION("Integrant ITD1000 driver");
+MODULE_LICENSE("GPL");

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

@@ -0,0 +1,42 @@
+/*
+ *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
+ *
+ *  Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  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.
+ *
+ *  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 ITD1000_H
+#define ITD1000_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct itd1000_config {
+	u8 i2c_address;
+};
+
+#if defined(CONFIG_DVB_TUNER_ITD1000) || (defined(CONFIG_DVB_TUNER_ITD1000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg);
+#else
+static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif

+ 88 - 0
drivers/media/dvb/frontends/itd1000_priv.h

@@ -0,0 +1,88 @@
+/*
+ *  Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
+ *
+ *  Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org>
+ *
+ *  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.
+ *
+ *  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 ITD1000_PRIV_H
+#define ITD1000_PRIV_H
+
+struct itd1000_state {
+	struct itd1000_config *cfg;
+	struct i2c_adapter    *i2c;
+
+	u32 frequency; /* contains the value resulting from the LO-setting */
+
+	/* ugly workaround for flexcop's incapable i2c-controller
+	 * FIXME, if possible
+	 */
+	u8 shadow[255];
+};
+
+enum itd1000_register {
+	VCO_CHP1 = 0x65,
+	VCO_CHP2,
+	PLLCON1,
+	PLLNH,
+	PLLNL,
+	PLLFH,
+	PLLFM,
+	PLLFL,
+	RESERVED_0X6D,
+	PLLLOCK,
+	VCO_CHP2_I2C,
+	VCO_CHP1_I2C,
+	BW,
+	RESERVED_0X73 = 0x73,
+	RESERVED_0X74,
+	RESERVED_0X75,
+	GVBB,
+	GVRF,
+	GVBB_I2C,
+	EXTGVBBRF,
+	DIVAGCCK,
+	BBTR,
+	RFTR,
+	BBGVMIN,
+	RESERVED_0X7E,
+	RESERVED_0X85 = 0x85,
+	RESERVED_0X86,
+	CON1,
+	RESERVED_0X88,
+	RESERVED_0X89,
+	RFST0,
+	RFST1,
+	RFST2,
+	RFST3,
+	RFST4,
+	RFST5,
+	RFST6,
+	RFST7,
+	RFST8,
+	RFST9,
+	RESERVED_0X94,
+	RESERVED_0X95,
+	RESERVED_0X96,
+	RESERVED_0X97,
+	RESERVED_0X98,
+	RESERVED_0X99,
+	RESERVED_0X9A,
+	RESERVED_0X9B,
+};
+
+#endif

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác