mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 21:54:11 +08:00
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 ...
This commit is contained in:
commit
c328d54cd4
4
Documentation/video4linux/CARDLIST.au0828
Normal file
4
Documentation/video4linux/CARDLIST.au0828
Normal file
@ -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]
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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,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/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
mutex_unlock(&i2c->fc->i2c_mutex);
|
||||
|
||||
if (ret == 0)
|
||||
ret = num;
|
||||
|
||||
mutex_unlock(&fc->i2c_mutex);
|
||||
|
||||
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));
|
||||
fc->fc_i2c_adap[0].fc = fc;
|
||||
fc->fc_i2c_adap[1].fc = fc;
|
||||
fc->fc_i2c_adap[2].fc = fc;
|
||||
|
||||
i2c_set_adapdata(&fc->i2c_adap,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;
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0)
|
||||
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;
|
||||
|
||||
ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap);
|
||||
if (ret < 0)
|
||||
goto adap_1_failed;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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[] = {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
spin_lock_irq(&dmxdevfilter->dev->lock);
|
||||
mem = buf->data;
|
||||
buf->data = NULL;
|
||||
buf->size = size;
|
||||
dvb_ringbuffer_flush(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);
|
||||
}
|
||||
newmem = vmalloc(size);
|
||||
if (!newmem)
|
||||
return -ENOMEM;
|
||||
|
||||
oldmem = buf->data;
|
||||
|
||||
spin_lock_irq(&dmxdevfilter->dev->lock);
|
||||
buf->data = newmem;
|
||||
buf->size = size;
|
||||
|
||||
/* reset and not flush in case the buffer shrinks */
|
||||
dvb_ringbuffer_reset(buf);
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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[] = {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
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;
|
||||
}
|
||||
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];
|
||||
d->last_event = keymap[i].event;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
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
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 [] = {
|
||||
|
@ -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 [] = {
|
||||
|
@ -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
|
||||
|
@ -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
drivers/media/dvb/frontends/au8522.c
Normal file
692
drivers/media/dvb/frontends/au8522.c
Normal file
@ -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
drivers/media/dvb/frontends/au8522.h
Normal file
56
drivers/media/dvb/frontends/au8522.h
Normal file
@ -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
|
||||
*/
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
drivers/media/dvb/frontends/cx24113.h
Normal file
48
drivers/media/dvb/frontends/cx24113.h
Normal file
@ -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 */
|
@ -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 = ®, .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");
|
||||
|
||||
|
@ -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", __FUNCTION__);
|
||||
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", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif // CONFIG_DVB_CX24123
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
drivers/media/dvb/frontends/isl6405.c
Normal file
164
drivers/media/dvb/frontends/isl6405.c
Normal file
@ -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
drivers/media/dvb/frontends/isl6405.h
Normal file
74
drivers/media/dvb/frontends/isl6405.h
Normal file
@ -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
|
@ -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
drivers/media/dvb/frontends/itd1000.c
Normal file
400
drivers/media/dvb/frontends/itd1000.c
Normal file
@ -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 = ®, .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
drivers/media/dvb/frontends/itd1000.h
Normal file
42
drivers/media/dvb/frontends/itd1000.h
Normal file
@ -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
drivers/media/dvb/frontends/itd1000_priv.h
Normal file
88
drivers/media/dvb/frontends/itd1000_priv.h
Normal file
@ -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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user