Commit 5ffd1a6a authored by Linus Torvalds's avatar Linus Torvalds

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

* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (180 commits)
  V4L/DVB (4641): Trivial: use lowercase letters in hex subsystem ids
  V4L/DVB (4639): Cx88: add autodetection for alternate revision of Leadtek PVR
  V4L/DVB (4638): Basic DVB-T and analog TV support for the HVR1300.
  V4L/DVB (4637): Add a default method for VIDIOC_G_PARM
  V4L/DVB (4635): Extend bttv and saa7134 to check for both AGP and PCI PCI failure case
  V4L/DVB (4634): Zr36120: implement pcipci checks
  V4L/DVB (4632): Zoran: Implement pcipci failure check
  V4L/DVB (4631): Av7110: remove V4L2_CAP_VBI_CAPTURE flag
  V4L/DVB (4630): Av7110: FW_LOADER depemdency fixed
  V4L/DVB (4629): Saa7134: add card support for Proteus Pro 2309
  V4L/DVB (4628): Fix VIDIOC_ENUMSTD ioctl in videodev.c
  V4L/DVB (4627): Vivi crashes with mplayer
  V4L/DVB (4626): On saa7111/7113, LUMA_CTRL need a different value
  V4L/DVB (4624): Tvaudio: Replaced kernel_thread() with kthread_run()
  V4L/DVB (4622): Copy-paste bug in videodev.c
  V4L/DVB (4620): Fix AGC configuration for MOD3000P-based boards
  V4L/DVB (4619): Fixes some I2C dependencies on V4L devices
  V4L/DVB (4617): Problem with dibusb-mb.c USB IDs
  V4L/DVB (4616): [PATCH] Nebula DigiTV USB RC support
  V4L/DVB (4614): Export symbol saa7134_tvaudio_setmute from saa7134 for saa7134-alsa
  ...
parents 0cd43f83 8dd86eeb
...@@ -47,7 +47,7 @@ Who: Jody McIntyre <scjody@modernduck.com> ...@@ -47,7 +47,7 @@ Who: Jody McIntyre <scjody@modernduck.com>
--------------------------- ---------------------------
What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
When: July 2006 When: December 2006
Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6 Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
series. The old API have lots of drawbacks and don't provide enough series. The old API have lots of drawbacks and don't provide enough
means to work with all video and audio standards. The newer API is means to work with all video and audio standards. The newer API is
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
6 -> AverTV Studio 303 (M126) [1461:000b] 6 -> AverTV Studio 303 (M126) [1461:000b]
7 -> MSI TV-@nywhere Master [1462:8606] 7 -> MSI TV-@nywhere Master [1462:8606]
8 -> Leadtek Winfast DV2000 [107d:6620] 8 -> Leadtek Winfast DV2000 [107d:6620]
9 -> Leadtek PVR 2000 [107d:663b,107d:663C] 9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632]
10 -> IODATA GV-VCP3/PCI [10fc:d003] 10 -> IODATA GV-VCP3/PCI [10fc:d003]
11 -> Prolink PlayTV PVR 11 -> Prolink PlayTV PVR
12 -> ASUS PVR-416 [1043:4823] 12 -> ASUS PVR-416 [1043:4823,1461:c111]
13 -> MSI TV-@nywhere 13 -> MSI TV-@nywhere
14 -> KWorld/VStream XPert DVB-T [17de:08a6] 14 -> KWorld/VStream XPert DVB-T [17de:08a6]
15 -> DViCO FusionHDTV DVB-T1 [18ac:db00] 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00]
...@@ -51,3 +51,7 @@ ...@@ -51,3 +51,7 @@
50 -> NPG Tech Real TV FM Top 10 [14f1:0842] 50 -> NPG Tech Real TV FM Top 10 [14f1:0842]
51 -> WinFast DTV2000 H [107d:665e] 51 -> WinFast DTV2000 H [107d:665e]
52 -> Geniatech DVB-S [14f1:0084] 52 -> Geniatech DVB-S [14f1:0084]
53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T [0070:1404]
54 -> Norwood Micro TV Tuner
55 -> Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM [c180:c980]
56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder [0070:9600,0070:9601,0070:9602]
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
57 -> Avermedia AVerTV GO 007 FM [1461:f31f] 57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370]
59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
60 -> LifeView/Typhoon FlyDVB-T Duo Cardbus [5168:0502,4e42:0502] 60 -> LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus [5168:0502,4e42:0502,1489:0502]
61 -> Philips TOUGH DVB-T reference design [1131:2004] 61 -> Philips TOUGH DVB-T reference design [1131:2004]
62 -> Compro VideoMate TV Gold+II 62 -> Compro VideoMate TV Gold+II
63 -> Kworld Xpert TV PVR7134 63 -> Kworld Xpert TV PVR7134
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
82 -> MSI TV@Anywhere plus [1462:6231] 82 -> MSI TV@Anywhere plus [1462:6231]
83 -> Terratec Cinergy 250 PCI TV [153b:1160] 83 -> Terratec Cinergy 250 PCI TV [153b:1160]
84 -> LifeView FlyDVB Trio [5168:0319] 84 -> LifeView FlyDVB Trio [5168:0319]
85 -> AverTV DVB-T 777 [1461:2c05] 85 -> AverTV DVB-T 777 [1461:2c05,1461:2c05]
86 -> LifeView FlyDVB-T / Genius VideoWonder DVB-T [5168:0301,1489:0301] 86 -> LifeView FlyDVB-T / Genius VideoWonder DVB-T [5168:0301,1489:0301]
87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421] 87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421]
88 -> Tevion/KWorld DVB-T 220RF [17de:7201] 88 -> Tevion/KWorld DVB-T 220RF [17de:7201]
...@@ -94,3 +94,6 @@ ...@@ -94,3 +94,6 @@
93 -> Medion 7134 Bridge #2 [16be:0005] 93 -> Medion 7134 Bridge #2 [16be:0005]
94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502] 94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502]
95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138]
96 -> Medion Md8800 Quadro [16be:0007,16be:0008]
97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300]
98 -> Proteus Pro 2309 [0919:2003]
...@@ -54,6 +54,12 @@ bttv.o ...@@ -54,6 +54,12 @@ bttv.o
dropouts. dropouts.
chroma_agc=0/1 AGC of chroma signal, off by default. chroma_agc=0/1 AGC of chroma signal, off by default.
adc_crush=0/1 Luminance ADC crush, on by default. adc_crush=0/1 Luminance ADC crush, on by default.
i2c_udelay= Allow reduce I2C speed. Default is 5 usecs
(meaning 66,67 Kbps). The default is the
maximum supported speed by kernel bitbang
algoritm. You may use lower numbers, if I2C
messages are lost (16 is known to work on
all supported cards).
bttv_gpio=0/1 bttv_gpio=0/1
gpiomask= gpiomask=
......
The cx23416 can produce (and the cx23415 can also read) raw YUV output. The
format of a YUV frame is specific to this chip and is called HM12. 'HM' stands
for 'Hauppauge Macroblock', which is a misnomer as 'Conexant Macroblock' would
be more accurate.
The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per
four pixels.
The data is encoded as two macroblock planes, the first containing the Y
values, the second containing UV macroblocks.
The Y plane is divided into blocks of 16x16 pixels from left to right
and from top to bottom. Each block is transmitted in turn, line-by-line.
So the first 16 bytes are the first line of the top-left block, the
second 16 bytes are the second line of the top-left block, etc. After
transmitting this block the first line of the block on the right to the
first block is transmitted, etc.
The UV plane is divided into blocks of 16x8 UV values going from left
to right, top to bottom. Each block is transmitted in turn, line-by-line.
So the first 16 bytes are the first line of the top-left block and
contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the
second line of 8 UV pairs of the top-left block, etc. After transmitting
this block the first line of the block on the right to the first block is
transmitted, etc.
The code below is given as an example on how to convert HM12 to separate
Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
The width of a frame is always 720 pixels, regardless of the actual specified
width.
--------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static unsigned char frame[576*720*3/2];
static unsigned char framey[576*720];
static unsigned char frameu[576*720 / 4];
static unsigned char framev[576*720 / 4];
static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h)
{
unsigned int y, x, i;
// descramble Y plane
// dstride = 720 = w
// The Y plane is divided into blocks of 16x16 pixels
// Each block in transmitted in turn, line-by-line.
for (y = 0; y < h; y += 16) {
for (x = 0; x < w; x += 16) {
for (i = 0; i < 16; i++) {
memcpy(dst + x + (y + i) * dstride, src, 16);
src += 16;
}
}
}
}
static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h)
{
unsigned int y, x, i;
// descramble U/V plane
// dstride = 720 / 2 = w
// The U/V values are interlaced (UVUV...).
// Again, the UV plane is divided into blocks of 16x16 UV values.
// Each block in transmitted in turn, line-by-line.
for (y = 0; y < h; y += 16) {
for (x = 0; x < w; x += 8) {
for (i = 0; i < 16; i++) {
int idx = x + (y + i) * dstride;
dstu[idx+0] = src[0]; dstv[idx+0] = src[1];
dstu[idx+1] = src[2]; dstv[idx+1] = src[3];
dstu[idx+2] = src[4]; dstv[idx+2] = src[5];
dstu[idx+3] = src[6]; dstv[idx+3] = src[7];
dstu[idx+4] = src[8]; dstv[idx+4] = src[9];
dstu[idx+5] = src[10]; dstv[idx+5] = src[11];
dstu[idx+6] = src[12]; dstv[idx+6] = src[13];
dstu[idx+7] = src[14]; dstv[idx+7] = src[15];
src += 16;
}
}
}
}
/*************************************************************************/
int main(int argc, char **argv)
{
FILE *fin;
int i;
if (argc == 1) fin = stdin;
else fin = fopen(argv[1], "r");
if (fin == NULL) {
fprintf(stderr, "cannot open input\n");
exit(-1);
}
while (fread(frame, sizeof(frame), 1, fin) == 1) {
de_macro_y(framey, frame, 720, 720, 576);
de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2);
fwrite(framey, sizeof(framey), 1, stdout);
fwrite(framev, sizeof(framev), 1, stdout);
fwrite(frameu, sizeof(frameu), 1, stdout);
}
fclose(fin);
return 0;
}
--------------------------------------------------------------------------
Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
=========================================================
This document describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
embedded in an MPEG-2 program stream. This format is in part dictated by some
hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6
chips), in particular a maximum size for the VBI data. Anything longer is cut
off when the MPEG stream is played back through the cx23415.
The advantage of this format is it is very compact and that all VBI data for
all lines can be stored while still fitting within the maximum allowed size.
The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is
4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte
header and a 42 bytes payload each. Anything beyond this limit is cut off by
the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits
for a bitmask determining which lines are captured and 4 bytes for a magic cookie,
signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data.
If all lines are used, then there is no longer room for the bitmask. To solve this
two different magic numbers were introduced:
'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first
unsigned long denote which lines of the first field are captured. Bits 18-31 of
the first unsigned long and bits 0-3 of the second unsigned long are used for the
second field.
'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly
implies that the bitmasks are 0xffffffff and 0xf.
After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the
captured VBI lines start:
For each line the least significant 4 bits of the first byte contain the data type.
Possible values are shown in the table below. The payload is in the following 42
bytes.
Here is the list of possible data types:
#define IVTV_SLICED_TYPE_TELETEXT 0x1 // Teletext (uses lines 6-22 for PAL)
#define IVTV_SLICED_TYPE_CC 0x4 // Closed Captions (line 21 NTSC)
#define IVTV_SLICED_TYPE_WSS 0x5 // Wide Screen Signal (line 23 PAL)
#define IVTV_SLICED_TYPE_VPS 0x7 // Video Programming System (PAL) (line 16)
Hans Verkuil <hverkuil@xs4all.nl>
...@@ -4,7 +4,6 @@ config VIDEO_SAA7146 ...@@ -4,7 +4,6 @@ config VIDEO_SAA7146
config VIDEO_SAA7146_VV config VIDEO_SAA7146_VV
tristate tristate
select VIDEO_V4L2
select VIDEO_BUF select VIDEO_BUF
select VIDEO_VIDEOBUF select VIDEO_VIDEOBUF
select VIDEO_SAA7146 select VIDEO_SAA7146
......
...@@ -32,6 +32,37 @@ IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { ...@@ -32,6 +32,37 @@ IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
EXPORT_SYMBOL_GPL(ir_codes_empty); EXPORT_SYMBOL_GPL(ir_codes_empty);
/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE] = {
/* numeric */
[ 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,
[ 0x5c ] = KEY_POWER, /* power */
[ 0x20 ] = KEY_F, /* full screen */
[ 0x0f ] = KEY_BACKSPACE, /* recall */
[ 0x1b ] = KEY_ENTER, /* mute */
[ 0x41 ] = KEY_RECORD, /* record */
[ 0x43 ] = KEY_STOP, /* stop */
[ 0x16 ] = KEY_S,
[ 0x1a ] = KEY_Q, /* off */
[ 0x2e ] = KEY_RED,
[ 0x1f ] = KEY_DOWN, /* channel - */
[ 0x1c ] = KEY_UP, /* channel + */
[ 0x10 ] = KEY_LEFT, /* volume - */
[ 0x1e ] = KEY_RIGHT, /* volume + */
[ 0x14 ] = KEY_F1,
};
EXPORT_SYMBOL_GPL(ir_codes_proteus_2309);
/* Matt Jesson <dvb@jesson.eclipse.co.uk */ /* Matt Jesson <dvb@jesson.eclipse.co.uk */
IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = { IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
[ 0x28 ] = KEY_0, //'0' / 'enter' [ 0x28 ] = KEY_0, //'0' / 'enter'
...@@ -1473,3 +1504,51 @@ IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = { ...@@ -1473,3 +1504,51 @@ IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = {
}; };
EXPORT_SYMBOL_GPL(ir_codes_npgtech); EXPORT_SYMBOL_GPL(ir_codes_npgtech);
/* Norwood Micro (non-Pro) TV Tuner
By Peter Naulls <peter@chocky.org>
Key comments are the functions given in the manual */
IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE] = {
/* Keys 0 to 9 */
[ 0x20 ] = KEY_0,
[ 0x21 ] = KEY_1,
[ 0x22 ] = KEY_2,
[ 0x23 ] = KEY_3,
[ 0x24 ] = KEY_4,
[ 0x25 ] = KEY_5,
[ 0x26 ] = KEY_6,
[ 0x27 ] = KEY_7,
[ 0x28 ] = KEY_8,
[ 0x29 ] = KEY_9,
[ 0x78 ] = KEY_TUNER, /* Video Source */
[ 0x2c ] = KEY_EXIT, /* Open/Close software */
[ 0x2a ] = KEY_SELECT, /* 2 Digit Select */
[ 0x69 ] = KEY_AGAIN, /* Recall */
[ 0x32 ] = KEY_BRIGHTNESSUP, /* Brightness increase */
[ 0x33 ] = KEY_BRIGHTNESSDOWN, /* Brightness decrease */
[ 0x6b ] = KEY_KPPLUS, /* (not named >>>>>) */
[ 0x6c ] = KEY_KPMINUS, /* (not named <<<<<) */
[ 0x2d ] = KEY_MUTE, /* Mute */
[ 0x30 ] = KEY_VOLUMEUP, /* Volume up */
[ 0x31 ] = KEY_VOLUMEDOWN, /* Volume down */
[ 0x60 ] = KEY_CHANNELUP, /* Channel up */
[ 0x61 ] = KEY_CHANNELDOWN, /* Channel down */
[ 0x3f ] = KEY_RECORD, /* Record */
[ 0x37 ] = KEY_PLAY, /* Play */
[ 0x36 ] = KEY_PAUSE, /* Pause */
[ 0x2b ] = KEY_STOP, /* Stop */
[ 0x67 ] = KEY_FASTFORWARD, /* Foward */
[ 0x66 ] = KEY_REWIND, /* Rewind */
[ 0x3e ] = KEY_SEARCH, /* Auto Scan */
[ 0x2e ] = KEY_CAMERA, /* Capture Video */
[ 0x6d ] = KEY_MENU, /* Show/Hide Control */
[ 0x2f ] = KEY_ZOOM, /* Full Screen */
[ 0x34 ] = KEY_RADIO, /* FM */
[ 0x65 ] = KEY_POWER, /* Computer power */
};
EXPORT_SYMBOL_GPL(ir_codes_norwood);
...@@ -455,7 +455,6 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status) ...@@ -455,7 +455,6 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
static struct video_device device_template = static struct video_device device_template =
{ {
.hardware = VID_HARDWARE_SAA7146,
.fops = &video_fops, .fops = &video_fops,
.minor = -1, .minor = -1,
}; };
......
...@@ -2,13 +2,13 @@ config DVB_B2C2_FLEXCOP ...@@ -2,13 +2,13 @@ config DVB_B2C2_FLEXCOP
tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters" tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
select DVB_PLL select DVB_PLL
select DVB_STV0299 select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_MT352 select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_MT312 select DVB_MT312 if !DVB_FE_CUSTOMISE
select DVB_NXT200X select DVB_NXT200X if !DVB_FE_CUSTOMISE
select DVB_STV0297 select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_BCM3510 select DVB_BCM3510 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X select DVB_LGDT330X if !DVB_FE_CUSTOMISE
help help
Support for the digital TV receiver chip made by B2C2 Inc. included in Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes. Technisats PCI cards and USB boxes.
......
...@@ -505,7 +505,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) ...@@ -505,7 +505,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
struct dvb_frontend_ops *ops; struct dvb_frontend_ops *ops;
/* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { if ((fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
ops = &fc->fe->ops; ops = &fc->fe->ops;
ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
...@@ -519,36 +519,36 @@ int flexcop_frontend_init(struct flexcop_device *fc) ...@@ -519,36 +519,36 @@ int flexcop_frontend_init(struct flexcop_device *fc)
info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
} else } else
/* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { if ((fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
fc->dev_type = FC_AIR_DVB; fc->dev_type = FC_AIR_DVB;
fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; 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); info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
} else } else
/* try the air atsc 2nd generation (nxt2002) */ /* try the air atsc 2nd generation (nxt2002) */
if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC2; fc->dev_type = FC_AIR_ATSC2;
dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_samsung_tbmv); 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); info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
} else } else
/* try the air atsc 3nd generation (lgdt3303) */ /* try the air atsc 3nd generation (lgdt3303) */
if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC3; fc->dev_type = FC_AIR_ATSC3;
fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
} else } else
/* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { if ((fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_AIR_ATSC1; fc->dev_type = FC_AIR_ATSC1;
info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address); info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
} else } else
/* try the cable dvb (stv0297) */ /* try the cable dvb (stv0297) */
if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { if ((fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
fc->dev_type = FC_CABLE; fc->dev_type = FC_CABLE;
fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; 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); info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
} else } else
/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { if ((fc->fe = dvb_attach(vp310_mt312_attach, &skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
ops = &fc->fe->ops; ops = &fc->fe->ops;
ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
...@@ -571,9 +571,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) ...@@ -571,9 +571,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
} else { } else {
if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
err("frontend registration failed!"); err("frontend registration failed!");
ops = &fc->fe->ops; dvb_frontend_detach(fc->fe);
if (ops->release != NULL)
ops->release(fc->fe);
fc->fe = NULL; fc->fe = NULL;
return -EINVAL; return -EINVAL;
} }
...@@ -584,8 +582,10 @@ int flexcop_frontend_init(struct flexcop_device *fc) ...@@ -584,8 +582,10 @@ int flexcop_frontend_init(struct flexcop_device *fc)
void flexcop_frontend_exit(struct flexcop_device *fc) void flexcop_frontend_exit(struct flexcop_device *fc)
{ {
if (fc->init_state & FC_STATE_FE_INIT) if (fc->init_state & FC_STATE_FE_INIT) {
dvb_unregister_frontend(fc->fe); dvb_unregister_frontend(fc->fe);
dvb_frontend_detach(fc->fe);
}
fc->init_state &= ~FC_STATE_FE_INIT; fc->init_state &= ~FC_STATE_FE_INIT;
} }
...@@ -2,13 +2,13 @@ config DVB_BT8XX ...@@ -2,13 +2,13 @@ config DVB_BT8XX
tristate "BT8xx based PCI cards" tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && I2C && VIDEO_BT848 depends on DVB_CORE && PCI && I2C && VIDEO_BT848
select DVB_PLL select DVB_PLL
select DVB_MT352 select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_SP887X select DVB_SP887X if !DVB_FE_CUSTOMISE
select DVB_NXT6000 select DVB_NXT6000 if !DVB_FE_CUSTOMISE
select DVB_CX24110 select DVB_CX24110 if !DVB_FE_CUSTOMISE
select DVB_OR51211 select DVB_OR51211 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are Support for PCI cards based on the Bt8xx PCI bridge. Examples are
......
...@@ -1715,6 +1715,15 @@ static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet ...@@ -1715,6 +1715,15 @@ static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet
static void dst_release(struct dvb_frontend *fe) static void dst_release(struct dvb_frontend *fe)
{ {
struct dst_state *state = fe->demodulator_priv; struct dst_state *state = fe->demodulator_priv;
if (state->dst_ca) {
dvb_unregister_device(state->dst_ca);
#ifdef CONFIG_DVB_CORE_ATTACH
symbol_put(dst_ca_attach);
#endif
}
#ifdef CONFIG_DVB_CORE_ATTACH
symbol_put(dst_attach);
#endif
kfree(state); kfree(state);
} }
......
...@@ -699,12 +699,17 @@ static struct dvb_device dvbdev_ca = { ...@@ -699,12 +699,17 @@ static struct dvb_device dvbdev_ca = {
.fops = &dst_ca_fops .fops = &dst_ca_fops
}; };
int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter) struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter)
{ {
struct dvb_device *dvbdev; struct dvb_device *dvbdev;
dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device"); dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA); if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
return 0; dst->dst_ca = dvbdev;
return dst->dst_ca;
}
return NULL;
} }
EXPORT_SYMBOL(dst_ca_attach); EXPORT_SYMBOL(dst_ca_attach);
......
...@@ -140,6 +140,7 @@ struct dst_state { ...@@ -140,6 +140,7 @@ struct dst_state {
char *tuner_name; char *tuner_name;
struct mutex dst_mutex; struct mutex dst_mutex;
u8 fw_name[8]; u8 fw_name[8];
struct dvb_device *dst_ca;
}; };
struct tuner_types { struct tuner_types {
...@@ -178,7 +179,7 @@ int write_dst(struct dst_state *state, u8 * data, u8 len); ...@@ -178,7 +179,7 @@ int write_dst(struct dst_state *state, u8 * data, u8 len);
int read_dst(struct dst_state *state, u8 * ret, u8 len); int read_dst(struct dst_state *state, u8 * ret, u8 len);
u8 dst_check_sum(u8 * buf, u32 len); u8 dst_check_sum(u8 * buf, u32 len);
struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter); struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter);
int dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter); struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter);
int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay); int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay);
int dst_command(struct dst_state* state, u8 * data, u8 len); int dst_command(struct dst_state* state, u8 * data, u8 len);
......
...@@ -67,7 +67,7 @@ static void dvb_bt8xx_task(unsigned long data) ...@@ -67,7 +67,7 @@ static void dvb_bt8xx_task(unsigned long data)
static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed) static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{ {
struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct dvb_demux*dvbdmx = dvbdmxfeed->demux;
struct dvb_bt8xx_card *card = dvbdmx->priv; struct dvb_bt8xx_card *card = dvbdmx->priv;
int rc; int rc;
...@@ -595,15 +595,14 @@ static void lgdt330x_reset(struct dvb_bt8xx_card *bt) ...@@ -595,15 +595,14 @@ static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
static void frontend_init(struct dvb_bt8xx_card *card, u32 type) static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
{ {
int ret;
struct dst_state* state = NULL; struct dst_state* state = NULL;
switch(type) { switch(type) {
case BTTV_BOARD_DVICO_DVBT_LITE: case BTTV_BOARD_DVICO_DVBT_LITE:
card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter);
if (card->fe == NULL) if (card->fe == NULL)
card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config, card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config,
card->i2c_adapter); card->i2c_adapter);
if (card->fe != NULL) { if (card->fe != NULL) {
...@@ -615,7 +614,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -615,7 +614,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
lgdt330x_reset(card); lgdt330x_reset(card);
card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter);
if (card->fe != NULL) { if (card->fe != NULL) {
card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params; card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params;
dprintk ("dvb_bt8xx: lgdt330x detected\n"); dprintk ("dvb_bt8xx: lgdt330x detected\n");
...@@ -630,7 +629,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -630,7 +629,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
/* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
digitv_alps_tded4_reset(card); digitv_alps_tded4_reset(card);
card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter);
if (card->fe != NULL) { if (card->fe != NULL) {
card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params; card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params;
dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
...@@ -639,7 +638,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -639,7 +638,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
/* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */ /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */
digitv_alps_tded4_reset(card); digitv_alps_tded4_reset(card);
card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter); card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter);
if (card->fe != NULL) { if (card->fe != NULL) {
card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs; card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs;
...@@ -648,14 +647,14 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -648,14 +647,14 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
break; break;
case BTTV_BOARD_AVDVBT_761: case BTTV_BOARD_AVDVBT_761:
card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter); card->fe = dvb_attach(sp887x_attach, &microtune_mt7202dtf_config, card->i2c_adapter);
if (card->fe) { if (card->fe) {
card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params; card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
} }
break; break;
case BTTV_BOARD_AVDVBT_771: case BTTV_BOARD_AVDVBT_771:
card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
if (card->fe != NULL) { if (card->fe != NULL) {
card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs; card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
card->fe->ops.info.frequency_min = 174000000; card->fe->ops.info.frequency_min = 174000000;
...@@ -670,22 +669,21 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -670,22 +669,21 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
state->config = &dst_config; state->config = &dst_config;
state->i2c = card->i2c_adapter; state->i2c = card->i2c_adapter;
state->bt = card->bt; state->bt = card->bt;
state->dst_ca = NULL;
/* DST is not a frontend, attaching the ASIC */ /* DST is not a frontend, attaching the ASIC */
if ((dst_attach(state, &card->dvb_adapter)) == NULL) { 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", __FUNCTION__);
break; break;
} }
card->fe = &state->frontend;
/* Attach other DST peripherals if any */ /* Attach other DST peripherals if any */
/* Conditional Access device */ /* Conditional Access device */
card->fe = &state->frontend;
if (state->dst_hw_cap & DST_TYPE_HAS_CA) if (state->dst_hw_cap & DST_TYPE_HAS_CA)
ret = dst_ca_attach(state, &card->dvb_adapter); dvb_attach(dst_ca_attach, state, &card->dvb_adapter);
break; break;
case BTTV_BOARD_PINNACLESAT: case BTTV_BOARD_PINNACLESAT:
card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter);
if (card->fe) { if (card->fe) {
card->fe->ops.tuner_ops.init = pinnsat_tuner_init; card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep; card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
...@@ -694,7 +692,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -694,7 +692,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
break; break;
case BTTV_BOARD_PC_HDTV: case BTTV_BOARD_PC_HDTV:
card->fe = or51211_attach(&or51211_config, card->i2c_adapter); card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter);
break; break;
} }
...@@ -707,8 +705,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) ...@@ -707,8 +705,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
else else
if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
printk("dvb-bt8xx: Frontend registration failed!\n"); printk("dvb-bt8xx: Frontend registration failed!\n");
if (card->fe->ops.release) dvb_frontend_detach(card->fe);
card->fe->ops.release(card->fe);
card->fe = NULL; card->fe = NULL;
} }
} }
...@@ -925,8 +922,10 @@ static void dvb_bt8xx_remove(struct bttv_sub_device *sub) ...@@ -925,8 +922,10 @@ static void dvb_bt8xx_remove(struct bttv_sub_device *sub)
card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
dvb_dmxdev_release(&card->dmxdev); dvb_dmxdev_release(&card->dmxdev);
dvb_dmx_release(&card->demux); dvb_dmx_release(&card->demux);
if (card->fe) if (card->fe) {
dvb_unregister_frontend(card->fe); dvb_unregister_frontend(card->fe);
dvb_frontend_detach(card->fe);
}
dvb_unregister_adapter(&card->dvb_adapter); dvb_unregister_adapter(&card->dvb_adapter);
kfree(card); kfree(card);
......
...@@ -9,3 +9,16 @@ config DVB_CORE ...@@ -9,3 +9,16 @@ config DVB_CORE
in-kernel drivers will select this automatically if needed. in-kernel drivers will select this automatically if needed.
If unsure say N. If unsure say N.
config DVB_CORE_ATTACH
bool "Load and attach frontend modules as needed"
depends on DVB_CORE
depends on MODULES
help
Remove the static dependency of DVB card drivers on all
frontend modules for all possible card variants. Instead,
allow the card drivers to only load the frontend modules
they require. This saves several KBytes of memory.
Note: You will need moudule-init-tools v3.2 or later for this feature.
If unsure say Y.
...@@ -1105,18 +1105,42 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) ...@@ -1105,18 +1105,42 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
mutex_lock(&frontend_mutex); mutex_lock(&frontend_mutex);
dvb_unregister_device (fepriv->dvbdev); dvb_unregister_device (fepriv->dvbdev);
dvb_frontend_stop (fe); dvb_frontend_stop (fe);
if (fe->ops.tuner_ops.release) {
fe->ops.tuner_ops.release(fe);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
}
if (fe->ops.release)
fe->ops.release(fe);
else
printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops.info.name);
/* fe is invalid now */ /* fe is invalid now */
kfree(fepriv); kfree(fepriv);
mutex_unlock(&frontend_mutex); mutex_unlock(&frontend_mutex);
return 0; return 0;
} }
EXPORT_SYMBOL(dvb_unregister_frontend); EXPORT_SYMBOL(dvb_unregister_frontend);
#ifdef CONFIG_DVB_CORE_ATTACH
void dvb_frontend_detach(struct dvb_frontend* fe)
{
void *ptr;
if (fe->ops.release_sec) {
fe->ops.release_sec(fe);
symbol_put_addr(fe->ops.release_sec);
}
if (fe->ops.tuner_ops.release) {
fe->ops.tuner_ops.release(fe);
symbol_put_addr(fe->ops.tuner_ops.release);
}
ptr = (void*)fe->ops.release;
if (ptr) {
fe->ops.release(fe);
symbol_put_addr(ptr);
}
}
#else
void dvb_frontend_detach(struct dvb_frontend* fe)
{
if (fe->ops.release_sec)
fe->ops.release_sec(fe);
if (fe->ops.tuner_ops.release)
fe->ops.tuner_ops.release(fe);
if (fe->ops.release)
fe->ops.release(fe);
}
#endif
EXPORT_SYMBOL(dvb_frontend_detach);
...@@ -92,10 +92,13 @@ struct dvb_frontend_ops { ...@@ -92,10 +92,13 @@ struct dvb_frontend_ops {
struct dvb_frontend_info info; struct dvb_frontend_info info;
void (*release)(struct dvb_frontend* fe); void (*release)(struct dvb_frontend* fe);
void (*release_sec)(struct dvb_frontend* fe);
int (*init)(struct dvb_frontend* fe); int (*init)(struct dvb_frontend* fe);
int (*sleep)(struct dvb_frontend* fe); int (*sleep)(struct dvb_frontend* fe);
int (*write)(struct dvb_frontend* fe, u8* buf, int len);
/* if this is set, it overrides the default swzigzag */ /* if this is set, it overrides the default swzigzag */
int (*tune)(struct dvb_frontend* fe, int (*tune)(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params, struct dvb_frontend_parameters* params,
...@@ -147,7 +150,7 @@ struct dvb_frontend { ...@@ -147,7 +150,7 @@ struct dvb_frontend {
void* demodulator_priv; void* demodulator_priv;
void* tuner_priv; void* tuner_priv;
void* frontend_priv; void* frontend_priv;
void* misc_priv; void* sec_priv;
}; };
extern int dvb_register_frontend(struct dvb_adapter* dvb, extern int dvb_register_frontend(struct dvb_adapter* dvb,
...@@ -155,6 +158,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb, ...@@ -155,6 +158,8 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
extern int dvb_unregister_frontend(struct dvb_frontend* fe); extern int dvb_unregister_frontend(struct dvb_frontend* fe);
extern void dvb_frontend_detach(struct dvb_frontend* fe);
extern void dvb_frontend_reinitialise(struct dvb_frontend *fe); extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
......
...@@ -102,4 +102,26 @@ extern int dvb_usercopy(struct inode *inode, struct file *file, ...@@ -102,4 +102,26 @@ extern int dvb_usercopy(struct inode *inode, struct file *file,
int (*func)(struct inode *inode, struct file *file, int (*func)(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)); unsigned int cmd, void *arg));
/** generic DVB attach function. */
#ifdef CONFIG_DVB_CORE_ATTACH
#define dvb_attach(FUNCTION, ARGS...) ({ \
void *__r = NULL; \
typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
if (__a) { \
__r = (void *) __a(ARGS); \
if (__r == NULL) \
symbol_put(FUNCTION); \
} else { \
printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \
} \
__r; \
})
#else
#define dvb_attach(FUNCTION, ARGS...) ({ \
FUNCTION(ARGS); \
})
#endif
#endif /* #ifndef _DVBDEV_H_ */ #endif /* #ifndef _DVBDEV_H_ */
...@@ -26,6 +26,7 @@ config DVB_USB_A800 ...@@ -26,6 +26,7 @@ config DVB_USB_A800
tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
depends on DVB_USB depends on DVB_USB
select DVB_DIB3000MC select DVB_DIB3000MC
select DVB_TUNER_MT2060
help help
Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
...@@ -33,6 +34,7 @@ config DVB_USB_DIBUSB_MB ...@@ -33,6 +34,7 @@ config DVB_USB_DIBUSB_MB
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
depends on DVB_USB depends on DVB_USB
select DVB_DIB3000MB select DVB_DIB3000MB
select DVB_TUNER_MT2060
help help
Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
...@@ -65,6 +67,7 @@ config DVB_USB_DIBUSB_MC ...@@ -65,6 +67,7 @@ config DVB_USB_DIBUSB_MC
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
depends on DVB_USB depends on DVB_USB
select DVB_DIB3000MC select DVB_DIB3000MC
select DVB_TUNER_MT2060
help help
Support for 2.0 DVB-T receivers based on reference designs made by Support for 2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
...@@ -80,16 +83,17 @@ config DVB_USB_UMT_010 ...@@ -80,16 +83,17 @@ config DVB_USB_UMT_010
tristate "HanfTek UMT-010 DVB-T USB2.0 support" tristate "HanfTek UMT-010 DVB-T USB2.0 support"
depends on DVB_USB depends on DVB_USB
select DVB_DIB3000MC select DVB_DIB3000MC
select DVB_TUNER_MT2060
help help
Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
config DVB_USB_CXUSB config DVB_USB_CXUSB
tristate "Conexant USB2.0 hybrid reference design support" tristate "Conexant USB2.0 hybrid reference design support"
depends on DVB_USB depends on DVB_USB
select DVB_CX22702 select DVB_CX22702 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_MT352 select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
help help
Say Y here to support the Conexant USB2.0 hybrid reference design. Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode Currently, only DVB and ATSC modes are supported, analog mode
...@@ -101,8 +105,8 @@ config DVB_USB_CXUSB ...@@ -101,8 +105,8 @@ config DVB_USB_CXUSB
config DVB_USB_DIGITV config DVB_USB_DIGITV
tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
depends on DVB_USB depends on DVB_USB
select DVB_NXT6000 select DVB_NXT6000 if !DVB_FE_CUSTOMISE
select DVB_MT352 select DVB_MT352 if !DVB_FE_CUSTOMISE
help help
Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver. Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
...@@ -145,6 +149,7 @@ config DVB_USB_NOVA_T_USB2 ...@@ -145,6 +149,7 @@ config DVB_USB_NOVA_T_USB2
tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
depends on DVB_USB depends on DVB_USB
select DVB_DIB3000MC select DVB_DIB3000MC
select DVB_TUNER_MT2060
help help
Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
......
...@@ -26,6 +26,13 @@ static int a800_power_ctrl(struct dvb_usb_device *d, int onoff) ...@@ -26,6 +26,13 @@ static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
return 0; return 0;
} }
/* assure to put cold to 0 for iManufacturer == 1 */
static int a800_identify_state(struct usb_device *udev, struct dvb_usb_properties *props,struct dvb_usb_device_description **desc, int *cold)
{
*cold = udev->descriptor.iManufacturer != 1;
return 0;
}
static struct dvb_usb_rc_key a800_rc_keys[] = { static struct dvb_usb_rc_key a800_rc_keys[] = {
{ 0x02, 0x01, KEY_PROG1 }, /* SOURCE */ { 0x02, 0x01, KEY_PROG1 }, /* SOURCE */
{ 0x02, 0x00, KEY_POWER }, /* POWER */ { 0x02, 0x00, KEY_POWER }, /* POWER */
...@@ -113,6 +120,7 @@ static struct dvb_usb_properties a800_properties = { ...@@ -113,6 +120,7 @@ static struct dvb_usb_properties a800_properties = {
.power_ctrl = a800_power_ctrl, .power_ctrl = a800_power_ctrl,
.frontend_attach = dibusb_dib3000mc_frontend_attach, .frontend_attach = dibusb_dib3000mc_frontend_attach,
.tuner_attach = dibusb_dib3000mc_tuner_attach, .tuner_attach = dibusb_dib3000mc_tuner_attach,
.identify_state = a800_identify_state,
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = a800_rc_keys, .rc_key_map = a800_rc_keys,
......
...@@ -349,6 +349,7 @@ static struct mt352_config cxusb_dee1601_config = { ...@@ -349,6 +349,7 @@ static struct mt352_config cxusb_dee1601_config = {
static struct zl10353_config cxusb_zl10353_dee1601_config = { static struct zl10353_config cxusb_zl10353_dee1601_config = {
.demod_address = 0x0f, .demod_address = 0x0f,
.parallel_ts = 1,
}; };
static struct mt352_config cxusb_mt352_config = { static struct mt352_config cxusb_mt352_config = {
...@@ -409,7 +410,7 @@ static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d) ...@@ -409,7 +410,7 @@ static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1); cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1);
if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL) if ((d->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, &d->i2c_adap)) != NULL)
return 0; return 0;
return -EIO; return -EIO;
...@@ -422,7 +423,7 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_device *d) ...@@ -422,7 +423,7 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
if ((d->fe = lgdt330x_attach(&cxusb_lgdt3303_config, &d->i2c_adap)) != NULL) if ((d->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config, &d->i2c_adap)) != NULL)
return 0; return 0;
return -EIO; return -EIO;
...@@ -435,7 +436,7 @@ static int cxusb_mt352_frontend_attach(struct dvb_usb_device *d) ...@@ -435,7 +436,7 @@ static int cxusb_mt352_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
if ((d->fe = mt352_attach(&cxusb_mt352_config, &d->i2c_adap)) != NULL) if ((d->fe = dvb_attach(mt352_attach, &cxusb_mt352_config, &d->i2c_adap)) != NULL)
return 0; return 0;
return -EIO; return -EIO;
...@@ -448,8 +449,8 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d) ...@@ -448,8 +449,8 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
if (((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) || if (((d->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
((d->fe = zl10353_attach(&cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL)) ((d->fe = dvb_attach(zl10353_attach, &cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
return 0; return 0;
return -EIO; return -EIO;
......
...@@ -131,9 +131,6 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num ...@@ -131,9 +131,6 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
if (mutex_lock_interruptible(&d->i2c_mutex) < 0) if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN; return -EAGAIN;
if (num > 2)
warn("more than 2 i2c messages at a time is not handled yet. TODO.");
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
/* write/read request */ /* write/read request */
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
...@@ -168,31 +165,137 @@ int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val) ...@@ -168,31 +165,137 @@ int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
} }
EXPORT_SYMBOL(dibusb_read_eeprom_byte); EXPORT_SYMBOL(dibusb_read_eeprom_byte);
/* 3000MC/P stuff */
// Config Adjacent channels Perf -cal22
static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
.band_caps = BAND_VHF | BAND_UHF,
.setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0),
.agc1_max = 48497,
.agc1_min = 23593,
.agc2_max = 46531,
.agc2_min = 24904,
.agc1_pt1 = 0x65,
.agc1_pt2 = 0x69,
.agc1_slope1 = 0x51,
.agc1_slope2 = 0x27,
.agc2_pt1 = 0,
.agc2_pt2 = 0x33,
.agc2_slope1 = 0x35,
.agc2_slope2 = 0x37,
};
static struct dib3000mc_config stk3000p_dib3000p_config = {
&dib3000p_mt2060_agc_config,
.max_time = 0x196,
.ln_adc_level = 0x1cc7,
.output_mpeg2_in_188_bytes = 1,
};
static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
.setup = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0),
.agc1_max = 56361,
.agc1_min = 22282,
.agc2_max = 47841,
.agc2_min = 36045,
.agc1_pt1 = 0x3b,
.agc1_pt2 = 0x6b,
.agc1_slope1 = 0x55,
.agc1_slope2 = 0x1d,
.agc2_pt1 = 0,
.agc2_pt2 = 0x0a,
.agc2_slope1 = 0x95,
.agc2_slope2 = 0x1e,
};
static struct dib3000mc_config mod3000p_dib3000p_config = {
&dib3000p_panasonic_agc_config,
.max_time = 0x51,
.ln_adc_level = 0x1cc7,
.output_mpeg2_in_188_bytes = 1,
};
int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
{ {
struct dib3000_config demod_cfg; if (dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000P_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0 ||
struct dibusb_state *st = d->priv; dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000MC_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0) {
if (d->priv != NULL) {
for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) struct dibusb_state *st = d->priv;
if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { st->ops.pid_parse = dib3000mc_pid_parse;
d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; st->ops.pid_ctrl = dib3000mc_pid_control;
d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
return 0;
} }
return 0;
}
return -ENODEV; return -ENODEV;
} }
EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach); EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
static struct mt2060_config stk3000p_mt2060_config = {
0x60
};
int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
{ {
d->pll_addr = 0x60; struct dibusb_state *st = d->priv;
d->pll_desc = &dvb_pll_env57h1xd5; int ret;
u8 a,b;
d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; u16 if1 = 1220;
d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; struct i2c_adapter *tun_i2c;
// First IF calibration for Liteon Sticks
if (d->udev->descriptor.idVendor == USB_VID_LITEON &&
d->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
dibusb_read_eeprom_byte(d,0x7E,&a);
dibusb_read_eeprom_byte(d,0x7F,&b);
if (a == 0x00)
if1 += b;
else if (a == 0x80)
if1 -= b;
else
warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
} else if (d->udev->descriptor.idVendor == USB_VID_DIBCOM &&
d->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
u8 desc;
dibusb_read_eeprom_byte(d, 7, &desc);
if (desc == 2) {
a = 127;
do {
dibusb_read_eeprom_byte(d, a, &desc);
a--;
} while (a > 7 && (desc == 0xff || desc == 0x00));
if (desc & 0x80)
if1 -= (0xff - desc);
else
if1 += desc;
}
}
tun_i2c = dib3000mc_get_tuner_i2c_master(d->fe, 1);
if ((ret = mt2060_attach(d->fe, tun_i2c, &stk3000p_mt2060_config, if1)) != 0) {
/* not found - use panasonic pll parameters */
if (dvb_pll_attach(d->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL)
return -ENOMEM;
} else {
st->mt2060_present = 1;
/* set the correct parameters for the dib3000p */
dib3000mc_set_config(d->fe, &stk3000p_dib3000p_config);
}
return 0; return 0;
} }
EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
...@@ -267,6 +370,67 @@ struct dvb_usb_rc_key dibusb_rc_keys[] = { ...@@ -267,6 +370,67 @@ struct dvb_usb_rc_key dibusb_rc_keys[] = {
{ 0x86, 0x1e, KEY_DOWN }, { 0x86, 0x1e, KEY_DOWN },
{ 0x86, 0x1f, KEY_LEFT }, { 0x86, 0x1f, KEY_LEFT },
{ 0x86, 0x1b, KEY_RIGHT }, { 0x86, 0x1b, KEY_RIGHT },
/* Key codes for the DiBcom MOD3000 remote. */
{ 0x80, 0x00, KEY_MUTE },
{ 0x80, 0x01, KEY_TEXT },
{ 0x80, 0x02, KEY_HOME },
{ 0x80, 0x03, KEY_POWER },
{ 0x80, 0x04, KEY_RED },
{ 0x80, 0x05, KEY_GREEN },
{ 0x80, 0x06, KEY_YELLOW },
{ 0x80, 0x07, KEY_BLUE },
{ 0x80, 0x08, KEY_DVD },
{ 0x80, 0x09, KEY_AUDIO },
{ 0x80, 0x0a, KEY_MEDIA }, /* Pictures */
{ 0x80, 0x0b, KEY_VIDEO },
{ 0x80, 0x0c, KEY_BACK },
{ 0x80, 0x0d, KEY_UP },
{ 0x80, 0x0e, KEY_RADIO },
{ 0x80, 0x0f, KEY_EPG },
{ 0x80, 0x10, KEY_LEFT },
{ 0x80, 0x11, KEY_OK },
{ 0x80, 0x12, KEY_RIGHT },
{ 0x80, 0x13, KEY_UNKNOWN }, /* SAP */
{ 0x80, 0x14, KEY_TV },
{ 0x80, 0x15, KEY_DOWN },
{ 0x80, 0x16, KEY_MENU }, /* DVD Menu */
{ 0x80, 0x17, KEY_LAST },
{ 0x80, 0x18, KEY_RECORD },
{ 0x80, 0x19, KEY_STOP },
{ 0x80, 0x1a, KEY_PAUSE },
{ 0x80, 0x1b, KEY_PLAY },
{ 0x80, 0x1c, KEY_PREVIOUS },
{ 0x80, 0x1d, KEY_REWIND },
{ 0x80, 0x1e, KEY_FASTFORWARD },
{ 0x80, 0x1f, KEY_NEXT},
{ 0x80, 0x40, KEY_1 },
{ 0x80, 0x41, KEY_2 },
{ 0x80, 0x42, KEY_3 },
{ 0x80, 0x43, KEY_CHANNELUP },
{ 0x80, 0x44, KEY_4 },
{ 0x80, 0x45, KEY_5 },
{ 0x80, 0x46, KEY_6 },
{ 0x80, 0x47, KEY_CHANNELDOWN },
{ 0x80, 0x48, KEY_7 },
{ 0x80, 0x49, KEY_8 },
{ 0x80, 0x4a, KEY_9 },
{ 0x80, 0x4b, KEY_VOLUMEUP },
{ 0x80, 0x4c, KEY_CLEAR },
{ 0x80, 0x4d, KEY_0 },
{ 0x80, 0x4e, KEY_ENTER },
{ 0x80, 0x4f, KEY_VOLUMEDOWN },
}; };
EXPORT_SYMBOL(dibusb_rc_keys); EXPORT_SYMBOL(dibusb_rc_keys);
......
...@@ -21,11 +21,11 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) ...@@ -21,11 +21,11 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
demod_cfg.demod_address = 0x8; demod_cfg.demod_address = 0x8;
if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) { if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
return -ENODEV; return -ENODEV;
}
d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
...@@ -169,7 +169,7 @@ static struct dvb_usb_properties dibusb1_1_properties = { ...@@ -169,7 +169,7 @@ static struct dvb_usb_properties dibusb1_1_properties = {
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys, .rc_key_map = dibusb_rc_keys,
.rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query, .rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo, .i2c_algo = &dibusb_i2c_algo,
...@@ -247,7 +247,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { ...@@ -247,7 +247,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys, .rc_key_map = dibusb_rc_keys,
.rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query, .rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo, .i2c_algo = &dibusb_i2c_algo,
...@@ -272,8 +272,8 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { ...@@ -272,8 +272,8 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
#endif #endif
.devices = { .devices = {
{ "Artec T1 USB1.1 TVBOX with AN2235", { "Artec T1 USB1.1 TVBOX with AN2235",
{ &dibusb_dib3000mb_table[20], NULL },
{ &dibusb_dib3000mb_table[21], NULL }, { &dibusb_dib3000mb_table[21], NULL },
{ &dibusb_dib3000mb_table[22], NULL },
}, },
#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
{ "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
...@@ -304,7 +304,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = { ...@@ -304,7 +304,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys, .rc_key_map = dibusb_rc_keys,
.rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query, .rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo, .i2c_algo = &dibusb_i2c_algo,
...@@ -355,7 +355,7 @@ static struct dvb_usb_properties artec_t1_usb2_properties = { ...@@ -355,7 +355,7 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys, .rc_key_map = dibusb_rc_keys,
.rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
.rc_query = dibusb_rc_query, .rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo, .i2c_algo = &dibusb_i2c_algo,
......
...@@ -28,6 +28,17 @@ static struct usb_device_id dibusb_dib3000mc_table [] = { ...@@ -28,6 +28,17 @@ static struct usb_device_id dibusb_dib3000mc_table [] = {
/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) }, /* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) }, /* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, /* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
/* 03 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, // ( ? )
/* 04 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_COLD) },
/* 05 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_WARM) },
/* 06 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_COLD) },
/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_WARM) },
/* 08 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_COLD) },
/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_WARM) },
/* 10 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_COLD) },
/* 11 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) },
/* 12 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_COLD) },
/* 13 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_WARM) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table); MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
...@@ -50,7 +61,7 @@ static struct dvb_usb_properties dibusb_mc_properties = { ...@@ -50,7 +61,7 @@ static struct dvb_usb_properties dibusb_mc_properties = {
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys, .rc_key_map = dibusb_rc_keys,
.rc_key_map_size = 63, /* FIXME */ .rc_key_map_size = 111, /* FIXME */
.rc_query = dibusb_rc_query, .rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo, .i2c_algo = &dibusb_i2c_algo,
...@@ -68,16 +79,38 @@ static struct dvb_usb_properties dibusb_mc_properties = { ...@@ -68,16 +79,38 @@ static struct dvb_usb_properties dibusb_mc_properties = {
} }
}, },
.num_device_descs = 2, .num_device_descs = 7,
.devices = { .devices = {
{ "DiBcom USB2.0 DVB-T reference design (MOD3000P)", { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
{ &dibusb_dib3000mc_table[0], NULL }, { &dibusb_dib3000mc_table[0], NULL },
{ &dibusb_dib3000mc_table[1], NULL }, { &dibusb_dib3000mc_table[1], NULL },
}, },
{ "Artec T1 USB2.0 TVBOX (please report the warm ID)", { "Artec T1 USB2.0 TVBOX (please check the warm ID)",
{ &dibusb_dib3000mc_table[2], NULL }, { &dibusb_dib3000mc_table[2], NULL },
{ NULL }, { &dibusb_dib3000mc_table[3], NULL },
}, },
{ "LITE-ON USB2.0 DVB-T Tuner",
/* Also rebranded as Intuix S800, Toshiba */
{ &dibusb_dib3000mc_table[4], NULL },
{ &dibusb_dib3000mc_table[5], NULL },
},
{ "MSI Digivox Mini SL",
{ &dibusb_dib3000mc_table[6], NULL },
{ &dibusb_dib3000mc_table[7], NULL },
},
{ "GRAND - USB2.0 DVB-T adapter",
{ &dibusb_dib3000mc_table[8], NULL },
{ &dibusb_dib3000mc_table[9], NULL },
},
{ "Artec T14 - USB2.0 DVB-T",
{ &dibusb_dib3000mc_table[10], NULL },
{ &dibusb_dib3000mc_table[11], NULL },
},
{ "Leadtek - USB2.0 Winfast DTV dongle",
{ &dibusb_dib3000mc_table[12], NULL },
{ &dibusb_dib3000mc_table[13], NULL },
},
{ NULL },
} }
}; };
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "dvb-usb.h" #include "dvb-usb.h"
#include "dib3000.h" #include "dib3000.h"
#include "dib3000mc.h"
#include "mt2060.h"
/* /*
* protocol of all dibusb related devices * protocol of all dibusb related devices
...@@ -96,6 +98,7 @@ ...@@ -96,6 +98,7 @@
struct dibusb_state { struct dibusb_state {
struct dib_fe_xfer_ops ops; struct dib_fe_xfer_ops ops;
int mt2060_present;
/* for RC5 remote control */ /* for RC5 remote control */
int old_toggle; int old_toggle;
......
...@@ -128,11 +128,11 @@ static struct nxt6000_config digitv_nxt6000_config = { ...@@ -128,11 +128,11 @@ static struct nxt6000_config digitv_nxt6000_config = {
static int digitv_frontend_attach(struct dvb_usb_device *d) static int digitv_frontend_attach(struct dvb_usb_device *d)
{ {
if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) { if ((d->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &d->i2c_adap)) != NULL) {
d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
return 0; return 0;
} }
if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) { if ((d->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
return 0; return 0;
} }
...@@ -147,21 +147,91 @@ static int digitv_tuner_attach(struct dvb_usb_device *d) ...@@ -147,21 +147,91 @@ static int digitv_tuner_attach(struct dvb_usb_device *d)
} }
static struct dvb_usb_rc_key digitv_rc_keys[] = { static struct dvb_usb_rc_key digitv_rc_keys[] = {
{ 0x00, 0x16, KEY_POWER }, /* dummy key */ { 0x5f, 0x55, KEY_0 },
{ 0x6f, 0x55, KEY_1 },
{ 0x9f, 0x55, KEY_2 },
{ 0xaf, 0x55, KEY_3 },
{ 0x5f, 0x56, KEY_4 },
{ 0x6f, 0x56, KEY_5 },
{ 0x9f, 0x56, KEY_6 },
{ 0xaf, 0x56, KEY_7 },
{ 0x5f, 0x59, KEY_8 },
{ 0x6f, 0x59, KEY_9 },
{ 0x9f, 0x59, KEY_TV },
{ 0xaf, 0x59, KEY_AUX },
{ 0x5f, 0x5a, KEY_DVD },
{ 0x6f, 0x5a, KEY_POWER },
{ 0x9f, 0x5a, KEY_MHP }, /* labelled 'Picture' */
{ 0xaf, 0x5a, KEY_AUDIO },
{ 0x5f, 0x65, KEY_INFO },
{ 0x6f, 0x65, KEY_F13 }, /* 16:9 */
{ 0x9f, 0x65, KEY_F14 }, /* 14:9 */
{ 0xaf, 0x65, KEY_EPG },
{ 0x5f, 0x66, KEY_EXIT },
{ 0x6f, 0x66, KEY_MENU },
{ 0x9f, 0x66, KEY_UP },
{ 0xaf, 0x66, KEY_DOWN },
{ 0x5f, 0x69, KEY_LEFT },
{ 0x6f, 0x69, KEY_RIGHT },
{ 0x9f, 0x69, KEY_ENTER },
{ 0xaf, 0x69, KEY_CHANNELUP },
{ 0x5f, 0x6a, KEY_CHANNELDOWN },
{ 0x6f, 0x6a, KEY_VOLUMEUP },
{ 0x9f, 0x6a, KEY_VOLUMEDOWN },
{ 0xaf, 0x6a, KEY_RED },
{ 0x5f, 0x95, KEY_GREEN },
{ 0x6f, 0x95, KEY_YELLOW },
{ 0x9f, 0x95, KEY_BLUE },
{ 0xaf, 0x95, KEY_SUBTITLE },
{ 0x5f, 0x96, KEY_F15 }, /* AD */
{ 0x6f, 0x96, KEY_TEXT },
{ 0x9f, 0x96, KEY_MUTE },
{ 0xaf, 0x96, KEY_REWIND },
{ 0x5f, 0x99, KEY_STOP },
{ 0x6f, 0x99, KEY_PLAY },
{ 0x9f, 0x99, KEY_FASTFORWARD },
{ 0xaf, 0x99, KEY_F16 }, /* chapter */
{ 0x5f, 0x9a, KEY_PAUSE },
{ 0x6f, 0x9a, KEY_PLAY },
{ 0x9f, 0x9a, KEY_RECORD },
{ 0xaf, 0x9a, KEY_F17 }, /* picture in picture */
{ 0x5f, 0xa5, KEY_KPPLUS }, /* zoom in */
{ 0x6f, 0xa5, KEY_KPMINUS }, /* zoom out */
{ 0x9f, 0xa5, KEY_F18 }, /* capture */
{ 0xaf, 0xa5, KEY_F19 }, /* web */
{ 0x5f, 0xa6, KEY_EMAIL },
{ 0x6f, 0xa6, KEY_PHONE },
{ 0x9f, 0xa6, KEY_PC },
}; };
/* TODO is it really the NEC protocol ? */
static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{ {
int i;
u8 key[5]; u8 key[5];
u8 b[4] = { 0 };
*event = 0;
*state = REMOTE_NO_KEY_PRESSED;
digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4); digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
/* TODO state, maybe it is VV ? */
/* Tell the device we've read the remote. Not sure how necessary
this is, but the Nebula SDK does it. */
digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
/* if something is inside the buffer, simulate key press */
if (key[1] != 0) if (key[1] != 0)
key[0] = 0x01; /* if something is inside the buffer, simulate key press */ {
for (i = 0; i < d->props.rc_key_map_size; i++) {
if (d->props.rc_key_map[i].custom == key[1] &&
d->props.rc_key_map[i].data == key[2]) {
*event = d->props.rc_key_map[i].event;
*state = REMOTE_KEY_PRESSED;
return 0;
}
}
}
/* call the universal NEC remote processor, to find out the key's state and event */
dvb_usb_nec_rc_key_to_event(d,key,event,state);
if (key[0] != 0) if (key[0] != 0)
deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
return 0; return 0;
......
...@@ -93,6 +93,7 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d) ...@@ -93,6 +93,7 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d)
} }
static struct dvb_usb_properties dtt200u_properties; static struct dvb_usb_properties dtt200u_properties;
static struct dvb_usb_properties wt220u_fc_properties;
static struct dvb_usb_properties wt220u_properties; static struct dvb_usb_properties wt220u_properties;
static struct dvb_usb_properties wt220u_zl0353_properties; static struct dvb_usb_properties wt220u_zl0353_properties;
...@@ -101,6 +102,7 @@ static int dtt200u_usb_probe(struct usb_interface *intf, ...@@ -101,6 +102,7 @@ static int dtt200u_usb_probe(struct usb_interface *intf,
{ {
if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 || 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_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_zl0353_properties,THIS_MODULE,NULL) == 0)
return 0; return 0;
...@@ -114,6 +116,9 @@ static struct usb_device_id dtt200u_usb_table [] = { ...@@ -114,6 +116,9 @@ static struct usb_device_id dtt200u_usb_table [] = {
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) }, { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) }, { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) },
{ 0 }, { 0 },
}; };
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
...@@ -193,13 +198,54 @@ static struct dvb_usb_properties wt220u_properties = { ...@@ -193,13 +198,54 @@ static struct dvb_usb_properties wt220u_properties = {
.num_device_descs = 1, .num_device_descs = 1,
.devices = { .devices = {
{ .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)", { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
.cold_ids = { &dtt200u_usb_table[2], NULL }, .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL },
.warm_ids = { &dtt200u_usb_table[3], NULL }, .warm_ids = { &dtt200u_usb_table[3], NULL },
}, },
{ NULL }, { NULL },
} }
}; };
static struct dvb_usb_properties wt220u_fc_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
.pid_filter_count = 15,
.usb_ctrl = CYPRESS_FX2,
.firmware = "dvb-usb-wt220u-fc03.fw",
.power_ctrl = dtt200u_power_ctrl,
.streaming_ctrl = dtt200u_streaming_ctrl,
.pid_filter = dtt200u_pid_filter,
.frontend_attach = dtt200u_frontend_attach,
.rc_interval = 300,
.rc_key_map = dtt200u_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
.rc_query = dtt200u_rc_query,
.generic_bulk_ctrl_endpoint = 0x01,
/* parameter for the MPEG2-data transfer */
.urb = {
.type = DVB_USB_BULK,
.count = 7,
.endpoint = 0x86,
.u = {
.bulk = {
.buffersize = 4096,
}
}
},
.num_device_descs = 1,
.devices = {
{ .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
.cold_ids = { &dtt200u_usb_table[6], NULL },
.warm_ids = { &dtt200u_usb_table[7], NULL },
},
{ NULL },
}
};
static struct dvb_usb_properties wt220u_zl0353_properties = { static struct dvb_usb_properties wt220u_zl0353_properties = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
.pid_filter_count = 15, .pid_filter_count = 15,
...@@ -271,6 +317,6 @@ module_init(dtt200u_usb_module_init); ...@@ -271,6 +317,6 @@ module_init(dtt200u_usb_module_init);
module_exit(dtt200u_usb_module_exit); module_exit(dtt200u_usb_module_exit);
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 devices"); MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D DVB-T USB2.0 devices");
MODULE_VERSION("1.0"); MODULE_VERSION("1.0");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -175,36 +175,36 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe) ...@@ -175,36 +175,36 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
int dvb_usb_fe_init(struct dvb_usb_device* d) int dvb_usb_fe_init(struct dvb_usb_device* d)
{ {
if (d->props.frontend_attach == NULL) { if (d->props.frontend_attach == NULL) {
err("strange '%s' doesn't want to attach a frontend.",d->desc->name); err("strange: '%s' doesn't want to attach a frontend.",d->desc->name);
return 0; return 0;
} }
d->props.frontend_attach(d);
/* re-assign sleep and wakeup functions */ /* re-assign sleep and wakeup functions */
if (d->fe != NULL) { if (d->props.frontend_attach(d) == 0 && d->fe != NULL) {
d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup; d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup;
d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep; d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep;
if (dvb_register_frontend(&d->dvb_adap, d->fe)) { if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
err("Frontend registration failed."); err("Frontend registration failed.");
if (d->fe->ops.release) dvb_frontend_detach(d->fe);
d->fe->ops.release(d->fe);
d->fe = NULL; d->fe = NULL;
return -ENODEV; return -ENODEV;
} }
/* only attach the tuner if the demod is there */
if (d->props.tuner_attach != NULL)
d->props.tuner_attach(d);
} else } else
err("no frontend was attached by '%s'",d->desc->name); err("no frontend was attached by '%s'",d->desc->name);
if (d->props.tuner_attach != NULL)
d->props.tuner_attach(d);
return 0; return 0;
} }
int dvb_usb_fe_exit(struct dvb_usb_device *d) int dvb_usb_fe_exit(struct dvb_usb_device *d)
{ {
if (d->fe != NULL) if (d->fe != NULL) {
dvb_unregister_frontend(d->fe); dvb_unregister_frontend(d->fe);
dvb_frontend_detach(d->fe);
}
return 0; return 0;
} }
...@@ -10,51 +10,53 @@ ...@@ -10,51 +10,53 @@
#define _DVB_USB_IDS_H_ #define _DVB_USB_IDS_H_
/* Vendor IDs */ /* Vendor IDs */
#define USB_VID_ADSTECH 0x06e1 #define USB_VID_ADSTECH 0x06e1
#define USB_VID_ANCHOR 0x0547 #define USB_VID_ANCHOR 0x0547
#define USB_VID_WIDEVIEW 0x14aa #define USB_VID_AVERMEDIA 0x07ca
#define USB_VID_AVERMEDIA 0x07ca #define USB_VID_COMPRO 0x185b
#define USB_VID_COMPRO 0x185b #define USB_VID_COMPRO_UNK 0x145f
#define USB_VID_COMPRO_UNK 0x145f #define USB_VID_CYPRESS 0x04b4
#define USB_VID_CYPRESS 0x04b4 #define USB_VID_DIBCOM 0x10b8
#define USB_VID_DIBCOM 0x10b8 #define USB_VID_DVICO 0x0fe9
#define USB_VID_DVICO 0x0fe9 #define USB_VID_EMPIA 0xeb1a
#define USB_VID_EMPIA 0xeb1a #define USB_VID_GENPIX 0x09c0
#define USB_VID_GRANDTEC 0x5032 #define USB_VID_GRANDTEC 0x5032
#define USB_VID_HANFTEK 0x15f4 #define USB_VID_HANFTEK 0x15f4
#define USB_VID_HAUPPAUGE 0x2040 #define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025 #define USB_VID_HYPER_PALTEK 0x1025
#define USB_VID_KWORLD 0xeb2a #define USB_VID_KWORLD 0xeb2a
#define USB_VID_KYE 0x0458 #define USB_VID_KYE 0x0458
#define USB_VID_MEDION 0x1660 #define USB_VID_LEADTEK 0x0413
#define USB_VID_PINNACLE 0x2304 #define USB_VID_LITEON 0x04ca
#define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_MEDION 0x1660
#define USB_VID_TWINHAN 0x1822 #define USB_VID_PINNACLE 0x2304
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 #define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_GENPIX 0x09c0 #define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
#define USB_VID_WIDEVIEW 0x14aa
/* Product IDs */ /* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333 #define USB_PID_ADSTECH_USB2_COLD 0xa333
#define USB_PID_ADSTECH_USB2_WARM 0xa334 #define USB_PID_ADSTECH_USB2_WARM 0xa334
#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801 #define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801
#define USB_PID_COMPRO_DVBU2000_COLD 0xd000 #define USB_PID_COMPRO_DVBU2000_COLD 0xd000
#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 #define USB_PID_COMPRO_DVBU2000_WARM 0xd001
#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c #define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 #define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 #define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 #define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 #define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 #define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
#define USB_PID_DIBCOM_STK7700 0x1e14 #define USB_PID_DIBCOM_STK7700 0x1e14
#define USB_PID_DIBCOM_STK7700_REENUM 0x1e15 #define USB_PID_DIBCOM_STK7700_REENUM 0x1e15
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
#define USB_PID_KWORLD_VSTREAM_COLD 0x17de #define USB_PID_KWORLD_VSTREAM_COLD 0x17de
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df #define USB_PID_KWORLD_VSTREAM_WARM 0x17df
#define USB_PID_TWINHAN_VP7041_COLD 0x3201 #define USB_PID_TWINHAN_VP7041_COLD 0x3201
...@@ -69,25 +71,30 @@ ...@@ -69,25 +71,30 @@
#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 #define USB_PID_DNTV_TINYUSB2_WARM 0x3224
#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 #define USB_PID_ULTIMA_TVBOX_COLD 0x8105
#define USB_PID_ULTIMA_TVBOX_WARM 0x8106 #define USB_PID_ULTIMA_TVBOX_WARM 0x8106
#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107 #define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 #define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 #define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 #define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a #define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 #define USB_PID_ARTEC_T14_COLD 0x810b
#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 #define USB_PID_ARTEC_T14_WARM 0x810c
#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e #define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f #define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
#define USB_PID_HANFTEK_UMT_010_COLD 0x0001 #define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
#define USB_PID_HANFTEK_UMT_010_WARM 0x0015 #define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
#define USB_PID_DTT200U_COLD 0x0201 #define USB_PID_DTT200U_COLD 0x0201
#define USB_PID_DTT200U_WARM 0x0301 #define USB_PID_DTT200U_WARM 0x0301
#define USB_PID_WT220U_COLD 0x0222 #define USB_PID_WT220U_ZAP250_COLD 0x0220
#define USB_PID_WT220U_WARM 0x0221 #define USB_PID_WT220U_COLD 0x0222
#define USB_PID_WT220U_WARM 0x0221
#define USB_PID_WT220U_FC_COLD 0x0225
#define USB_PID_WT220U_FC_WARM 0x0226
#define USB_PID_WT220U_ZL0353_COLD 0x022a #define USB_PID_WT220U_ZL0353_COLD 0x022a
#define USB_PID_WT220U_ZL0353_WARM 0x022b #define USB_PID_WT220U_ZL0353_WARM 0x022b
#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 #define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
#define USB_PID_NEBULA_DIGITV 0x0201 #define USB_PID_NEBULA_DIGITV 0x0201
#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500 #define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500
...@@ -103,8 +110,17 @@ ...@@ -103,8 +110,17 @@
#define USB_PID_MEDION_MD95700 0x0932 #define USB_PID_MEDION_MD95700 0x0932
#define USB_PID_KYE_DVB_T_COLD 0x701e #define USB_PID_KYE_DVB_T_COLD 0x701e
#define USB_PID_KYE_DVB_T_WARM 0x701f #define USB_PID_KYE_DVB_T_WARM 0x701f
#define USB_PID_PCTV_200E 0x020e #define USB_PID_PCTV_200E 0x020e
#define USB_PID_PCTV_400E 0x020f #define USB_PID_PCTV_400E 0x020f
#define USB_PID_GENPIX_8PSK_COLD 0x0200 #define USB_PID_LITEON_DVB_T_COLD 0xf000
#define USB_PID_GENPIX_8PSK_WARM 0x0201 #define USB_PID_LITEON_DVB_T_WARM 0xf001
#define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360
#define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361
#define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6
#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7
#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
#define USB_PID_GENPIX_8PSK_COLD 0x0200
#define USB_PID_GENPIX_8PSK_WARM 0x0201
#endif #endif
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* This file contains functions for initializing the the input-device and for handling remote-control-queries. * This file contains functions for initializing the the input-device and for handling remote-control-queries.
*/ */
#include "dvb-usb-common.h" #include "dvb-usb-common.h"
#include <linux/usb/input.h>
/* Remote-control poll function - called every dib->rc_query_interval ms to see /* Remote-control poll function - called every dib->rc_query_interval ms to see
* whether the remote control has received anything. * whether the remote control has received anything.
...@@ -96,7 +97,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) ...@@ -96,7 +97,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
return 0; return 0;
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcpy(d->rc_phys, "/ir0", sizeof(d->rc_phys)); strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
d->rc_input_dev = input_allocate_device(); d->rc_input_dev = input_allocate_device();
if (!d->rc_input_dev) if (!d->rc_input_dev)
...@@ -107,6 +108,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) ...@@ -107,6 +108,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
d->rc_input_dev->keycodemax = KEY_MAX; d->rc_input_dev->keycodemax = KEY_MAX;
d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver"; d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver";
d->rc_input_dev->phys = d->rc_phys; d->rc_input_dev->phys = d->rc_phys;
usb_to_input_id(d->udev, &d->rc_input_dev->id);
d->rc_input_dev->cdev.dev = &d->udev->dev;
/* set the bits for the keys */ /* set the bits for the keys */
deb_rc("key map size: %d\n", d->props.rc_key_map_size); deb_rc("key map size: %d\n", d->props.rc_key_map_size);
......
...@@ -156,7 +156,7 @@ static struct dvb_usb_properties nova_t_properties = { ...@@ -156,7 +156,7 @@ static struct dvb_usb_properties nova_t_properties = {
.pid_filter_count = 32, .pid_filter_count = 32,
.usb_ctrl = CYPRESS_FX2, .usb_ctrl = CYPRESS_FX2,
.firmware = "dvb-usb-nova-t-usb2-01.fw", .firmware = "dvb-usb-nova-t-usb2-02.fw",
.size_of_priv = sizeof(struct dibusb_state), .size_of_priv = sizeof(struct dibusb_state),
......
...@@ -58,7 +58,7 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d) ...@@ -58,7 +58,7 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
umt_config.demod_init = umt_mt352_demod_init; umt_config.demod_init = umt_mt352_demod_init;
umt_config.demod_address = 0xf; umt_config.demod_address = 0xf;
d->fe = mt352_attach(&umt_config, &d->i2c_adap); d->fe = dvb_attach(mt352_attach, &umt_config, &d->i2c_adap);
return 0; return 0;
} }
......
menu "Customise DVB Frontends" menu "Customise DVB Frontends"
depends on DVB_CORE depends on DVB_CORE
config DVB_FE_CUSTOMISE
bool "Customise the frontend modules to build"
default N
help
This allows the user to deselect frontend drivers unnecessary
for their hardware from the build. Use this option with care
as deselecting frontends which are in fact necessary will result
in DVB devices which cannot be tuned due to lack of driver support.
If unsure say N.
comment "DVB-S (satellite) frontends" comment "DVB-S (satellite) frontends"
depends on DVB_CORE depends on DVB_CORE
config DVB_STV0299 config DVB_STV0299
tristate "ST STV0299 based" tristate "ST STV0299 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-S tuner module. Say Y when you want to support this frontend. A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_CX24110 config DVB_CX24110
tristate "Conexant CX24110 based" tristate "Conexant CX24110 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-S tuner module. Say Y when you want to support this frontend. A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_CX24123 config DVB_CX24123
tristate "Conexant CX24123 based" tristate "Conexant CX24123 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-S tuner module. Say Y when you want to support this frontend. A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA8083 config DVB_TDA8083
tristate "Philips TDA8083 based" tristate "Philips TDA8083 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-S tuner module. Say Y when you want to support this frontend. A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_MT312 config DVB_MT312
tristate "Zarlink VP310/MT312 based" tristate "Zarlink VP310/MT312 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-S tuner module. Say Y when you want to support this frontend. A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_VES1X93 config DVB_VES1X93
tristate "VLSI VES1893 or VES1993 based" tristate "VLSI VES1893 or VES1993 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-S tuner module. Say Y when you want to support this frontend. A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_S5H1420 config DVB_S5H1420
tristate "Samsung S5H1420 based" tristate "Samsung S5H1420 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA10086
tristate "Philips TDA10086 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-S tuner module. Say Y when you want to support this frontend. A DVB-S tuner module. Say Y when you want to support this frontend.
...@@ -52,6 +77,7 @@ comment "DVB-T (terrestrial) frontends" ...@@ -52,6 +77,7 @@ comment "DVB-T (terrestrial) frontends"
config DVB_SP8870 config DVB_SP8870
tristate "Spase sp8870 based" tristate "Spase sp8870 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
...@@ -64,6 +90,7 @@ config DVB_SP8870 ...@@ -64,6 +90,7 @@ config DVB_SP8870
config DVB_SP887X config DVB_SP887X
tristate "Spase sp887x based" tristate "Spase sp887x based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
...@@ -76,24 +103,28 @@ config DVB_SP887X ...@@ -76,24 +103,28 @@ config DVB_SP887X
config DVB_CX22700 config DVB_CX22700
tristate "Conexant CX22700 based" tristate "Conexant CX22700 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_CX22702 config DVB_CX22702
tristate "Conexant cx22702 demodulator (OFDM)" tristate "Conexant cx22702 demodulator (OFDM)"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_L64781 config DVB_L64781
tristate "LSI L64781" tristate "LSI L64781"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_TDA1004X config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based" tristate "Philips TDA10045H/TDA10046H based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
...@@ -107,24 +138,28 @@ config DVB_TDA1004X ...@@ -107,24 +138,28 @@ config DVB_TDA1004X
config DVB_NXT6000 config DVB_NXT6000
tristate "NxtWave Communications NXT6000 based" tristate "NxtWave Communications NXT6000 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_MT352 config DVB_MT352
tristate "Zarlink MT352 based" tristate "Zarlink MT352 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_ZL10353 config DVB_ZL10353
tristate "Zarlink ZL10353 based" tristate "Zarlink ZL10353 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-T tuner module. Say Y when you want to support this frontend. A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DIB3000MB config DVB_DIB3000MB
tristate "DiBcom 3000M-B" tristate "DiBcom 3000M-B"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend. to support this frontend.
...@@ -132,6 +167,7 @@ config DVB_DIB3000MB ...@@ -132,6 +167,7 @@ config DVB_DIB3000MB
config DVB_DIB3000MC config DVB_DIB3000MC
tristate "DiBcom 3000P/M-C" tristate "DiBcom 3000P/M-C"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend. to support this frontend.
...@@ -142,18 +178,21 @@ comment "DVB-C (cable) frontends" ...@@ -142,18 +178,21 @@ comment "DVB-C (cable) frontends"
config DVB_VES1820 config DVB_VES1820
tristate "VLSI VES1820 based" tristate "VLSI VES1820 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-C tuner module. Say Y when you want to support this frontend. A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_TDA10021 config DVB_TDA10021
tristate "Philips TDA10021 based" tristate "Philips TDA10021 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-C tuner module. Say Y when you want to support this frontend. A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_STV0297 config DVB_STV0297
tristate "ST STV0297 based" tristate "ST STV0297 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
A DVB-C tuner module. Say Y when you want to support this frontend. A DVB-C tuner module. Say Y when you want to support this frontend.
...@@ -163,6 +202,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" ...@@ -163,6 +202,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
config DVB_NXT200X config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based" tristate "NxtWave Communications NXT2002/NXT2004 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
...@@ -177,6 +217,7 @@ config DVB_NXT200X ...@@ -177,6 +217,7 @@ config DVB_NXT200X
config DVB_OR51211 config DVB_OR51211
tristate "Oren OR51211 based" tristate "Oren OR51211 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend. An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
...@@ -189,6 +230,7 @@ config DVB_OR51211 ...@@ -189,6 +230,7 @@ config DVB_OR51211
config DVB_OR51132 config DVB_OR51132
tristate "Oren OR51132 based" tristate "Oren OR51132 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
...@@ -204,6 +246,7 @@ config DVB_OR51132 ...@@ -204,6 +246,7 @@ config DVB_OR51132
config DVB_BCM3510 config DVB_BCM3510
tristate "Broadcom BCM3510" tristate "Broadcom BCM3510"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER select FW_LOADER
help help
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
...@@ -212,28 +255,52 @@ config DVB_BCM3510 ...@@ -212,28 +255,52 @@ config DVB_BCM3510
config DVB_LGDT330X config DVB_LGDT330X
tristate "LG Electronics LGDT3302/LGDT3303 based" tristate "LG Electronics LGDT3302/LGDT3303 based"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend. to support this frontend.
comment "Tuners/PLL support"
comment "Miscellaneous devices"
depends on DVB_CORE depends on DVB_CORE
config DVB_PLL config DVB_PLL
tristate tristate
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
config DVB_TDA826X
tristate "Philips TDA826X silicon tuner"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_TUNER_MT2060
tristate "Microtune MT2060 silicon IF tuner"
help
A driver for the silicon IF tuner MT2060 from Microtune.
comment "Miscellaneous devices"
depends on DVB_CORE
config DVB_LNBP21 config DVB_LNBP21
tristate "LNBP21 SEC controller" tristate "LNBP21 SEC controller"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
An SEC control chip. An SEC control chip.
config DVB_ISL6421 config DVB_ISL6421
tristate "ISL6421 SEC controller" tristate "ISL6421 SEC controller"
depends on DVB_CORE && I2C depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help help
An SEC control chip. An SEC control chip.
config DVB_TUA6100
tristate "TUA6100 PLL"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVBS PLL chip.
endmenu endmenu
...@@ -11,8 +11,8 @@ obj-$(CONFIG_DVB_CX22700) += cx22700.o ...@@ -11,8 +11,8 @@ obj-$(CONFIG_DVB_CX22700) += cx22700.o
obj-$(CONFIG_DVB_CX24110) += cx24110.o obj-$(CONFIG_DVB_CX24110) += cx24110.o
obj-$(CONFIG_DVB_TDA8083) += tda8083.o obj-$(CONFIG_DVB_TDA8083) += tda8083.o
obj-$(CONFIG_DVB_L64781) += l64781.o obj-$(CONFIG_DVB_L64781) += l64781.o
obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o dib3000-common.o obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dib3000-common.o obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
obj-$(CONFIG_DVB_MT312) += mt312.o obj-$(CONFIG_DVB_MT312) += mt312.o
obj-$(CONFIG_DVB_VES1820) += ves1820.o obj-$(CONFIG_DVB_VES1820) += ves1820.o
obj-$(CONFIG_DVB_VES1X93) += ves1x93.o obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
...@@ -33,3 +33,7 @@ obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o ...@@ -33,3 +33,7 @@ obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_ISL6421) += isl6421.o obj-$(CONFIG_DVB_ISL6421) += isl6421.o
obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
...@@ -34,7 +34,16 @@ struct bcm3510_config ...@@ -34,7 +34,16 @@ struct bcm3510_config
int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
}; };
#if defined(CONFIG_DVB_BCM3510) || defined(CONFIG_DVB_BCM3510_MODULE)
extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
struct i2c_adapter* i2c); struct i2c_adapter* i2c);
#else
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__);
return NULL;
}
#endif // CONFIG_DVB_BCM3510
#endif #endif
...@@ -31,7 +31,16 @@ struct cx22700_config ...@@ -31,7 +31,16 @@ struct cx22700_config
u8 demod_address; u8 demod_address;
}; };
#if defined(CONFIG_DVB_CX22700) || defined(CONFIG_DVB_CX22700_MODULE)
extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
struct i2c_adapter* i2c); struct i2c_adapter* i2c);
#else
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__);
return NULL;
}
#endif // CONFIG_DVB_CX22700
#endif // CX22700_H #endif // CX22700_H
...@@ -399,7 +399,9 @@ static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_str ...@@ -399,7 +399,9 @@ static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
{ {
struct cx22702_state* state = fe->demodulator_priv; struct cx22702_state* state = fe->demodulator_priv;
*signal_strength = cx22702_readreg (state, 0x23); u16 rs_ber = 0;
rs_ber = cx22702_readreg (state, 0x23);
*signal_strength = (rs_ber << 8) | rs_ber;
return 0; return 0;
} }
......
...@@ -41,7 +41,16 @@ struct cx22702_config ...@@ -41,7 +41,16 @@ struct cx22702_config
u8 output_mode; u8 output_mode;
}; };
#if defined(CONFIG_DVB_CX22702) || defined(CONFIG_DVB_CX22702_MODULE)
extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
struct i2c_adapter* i2c); struct i2c_adapter* i2c);
#else
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__);
return NULL;
}
#endif // CONFIG_DVB_CX22702
#endif // CX22702_H #endif // CX22702_H
/* /*
cx24110 - Single Chip Satellite Channel Receiver driver module cx24110 - Single Chip Satellite Channel Receiver driver module
Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
...@@ -311,16 +311,17 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) ...@@ -311,16 +311,17 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
} }
int cx24110_pll_write (struct dvb_frontend* fe, u32 data) static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len)
{ {
struct cx24110_state *state = fe->demodulator_priv; struct cx24110_state *state = fe->demodulator_priv;
if (len != 3)
return -EINVAL;
/* tuner data is 21 bits long, must be left-aligned in data */ /* tuner data is 21 bits long, must be left-aligned in data */
/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */ /* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
/* FIXME (low): add error handling, avoid infinite loops if HW fails... */ /* FIXME (low): add error handling, avoid infinite loops if HW fails... */
dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data);
cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */ cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */ cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
...@@ -329,19 +330,19 @@ int cx24110_pll_write (struct dvb_frontend* fe, u32 data) ...@@ -329,19 +330,19 @@ int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
cx24110_writereg(state,0x72,0); cx24110_writereg(state,0x72,0);
/* write the topmost 8 bits */ /* write the topmost 8 bits */
cx24110_writereg(state,0x72,(data>>24)&0xff); cx24110_writereg(state,0x72,buf[0]);
/* wait for the send to be completed */ /* wait for the send to be completed */
while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
; ;
/* send another 8 bytes */ /* send another 8 bytes */
cx24110_writereg(state,0x72,(data>>16)&0xff); cx24110_writereg(state,0x72,buf[1]);
while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
; ;
/* and the topmost 5 bits of this byte */ /* and the topmost 5 bits of this byte */
cx24110_writereg(state,0x72,(data>>8)&0xff); cx24110_writereg(state,0x72,buf[2]);
while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
; ;
...@@ -642,6 +643,7 @@ static struct dvb_frontend_ops cx24110_ops = { ...@@ -642,6 +643,7 @@ static struct dvb_frontend_ops cx24110_ops = {
.release = cx24110_release, .release = cx24110_release,
.init = cx24110_initfe, .init = cx24110_initfe,
.write = _cx24110_pll_write,
.set_frontend = cx24110_set_frontend, .set_frontend = cx24110_set_frontend,
.get_frontend = cx24110_get_frontend, .get_frontend = cx24110_get_frontend,
.read_status = cx24110_read_status, .read_status = cx24110_read_status,
...@@ -664,4 +666,3 @@ MODULE_AUTHOR("Peter Hettkamp"); ...@@ -664,4 +666,3 @@ MODULE_AUTHOR("Peter Hettkamp");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
EXPORT_SYMBOL(cx24110_attach); EXPORT_SYMBOL(cx24110_attach);
EXPORT_SYMBOL(cx24110_pll_write);
...@@ -33,9 +33,24 @@ struct cx24110_config ...@@ -33,9 +33,24 @@ struct cx24110_config
u8 demod_address; u8 demod_address;
}; };
static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) {
int r = 0;
u8 buf[] = {(u8) (val>>24), (u8) (val>>16), (u8) (val>>8)};
if (fe->ops.write)
r = fe->ops.write(fe, buf, 3);
return r;
}
#if defined(CONFIG_DVB_CX24110) || defined(CONFIG_DVB_CX24110_MODULE)
extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
struct i2c_adapter* i2c); struct i2c_adapter* i2c);
#else
extern int cx24110_pll_write(struct dvb_frontend* fe, u32 data); 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__);
return NULL;
}
#endif // CONFIG_DVB_CX24110
#endif // CX24110_H #endif // CX24110_H
...@@ -45,9 +45,6 @@ struct cx24123_state ...@@ -45,9 +45,6 @@ struct cx24123_state
struct dvb_frontend frontend; struct dvb_frontend frontend;
u32 lastber;
u16 snr;
/* Some PLL specifics for tuning */ /* Some PLL specifics for tuning */
u32 VCAarg; u32 VCAarg;
u32 VGAarg; u32 VGAarg;
...@@ -194,7 +191,7 @@ static struct { ...@@ -194,7 +191,7 @@ static struct {
{0x06, 0x31}, /* MPEG (default) */ {0x06, 0x31}, /* MPEG (default) */
{0x0b, 0x00}, /* Freq search start point (default) */ {0x0b, 0x00}, /* Freq search start point (default) */
{0x0c, 0x00}, /* Demodulator sample gain (default) */ {0x0c, 0x00}, /* Demodulator sample gain (default) */
{0x0d, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */ {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */
{0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */ {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
{0x0f, 0xfe}, /* FEC search mask (all supported codes) */ {0x0f, 0xfe}, /* FEC search mask (all supported codes) */
{0x10, 0x01}, /* Default search inversion, no repeat (default) */ {0x10, 0x01}, /* Default search inversion, no repeat (default) */
...@@ -223,8 +220,9 @@ static struct { ...@@ -223,8 +220,9 @@ static struct {
{0x44, 0x00}, /* Constellation (default) */ {0x44, 0x00}, /* Constellation (default) */
{0x45, 0x00}, /* Symbol count (default) */ {0x45, 0x00}, /* Symbol count (default) */
{0x46, 0x0d}, /* Symbol rate estimator on (default) */ {0x46, 0x0d}, /* Symbol rate estimator on (default) */
{0x56, 0x41}, /* Various (default) */ {0x56, 0xc1}, /* Error Counter = Viterbi BER */
{0x57, 0xff}, /* Error Counter Window (default) */ {0x57, 0xff}, /* Error Counter Window (default) */
{0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
{0x67, 0x83}, /* Non-DCII symbol clock */ {0x67, 0x83}, /* Non-DCII symbol clock */
}; };
...@@ -321,6 +319,12 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) ...@@ -321,6 +319,12 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
fec = FEC_AUTO; fec = FEC_AUTO;
/* Set the soft decision threshold */
if(fec == FEC_1_2)
cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01);
else
cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01);
switch (fec) { switch (fec) {
case FEC_1_2: case FEC_1_2:
dprintk("%s: set FEC to 1/2\n",__FUNCTION__); dprintk("%s: set FEC to 1/2\n",__FUNCTION__);
...@@ -657,6 +661,10 @@ static int cx24123_initfe(struct dvb_frontend* fe) ...@@ -657,6 +661,10 @@ static int cx24123_initfe(struct dvb_frontend* fe)
for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
/* Set the LNB polarity */
if(state->config->lnb_polarity)
cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02);
return 0; return 0;
} }
...@@ -674,6 +682,9 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage ...@@ -674,6 +682,9 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
case SEC_VOLTAGE_18: case SEC_VOLTAGE_18:
dprintk("%s: setting voltage 18V\n", __FUNCTION__); dprintk("%s: setting voltage 18V\n", __FUNCTION__);
return cx24123_writereg(state, 0x29, val | 0x80); return cx24123_writereg(state, 0x29, val | 0x80);
case SEC_VOLTAGE_OFF:
/* already handled in cx88-dvb */
return 0;
default: default:
return -EINVAL; return -EINVAL;
}; };
...@@ -776,13 +787,15 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) ...@@ -776,13 +787,15 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
if (lock & 0x01) if (lock & 0x01)
*status |= FE_HAS_SIGNAL; *status |= FE_HAS_SIGNAL;
if (sync & 0x02) if (sync & 0x02)
*status |= FE_HAS_CARRIER; *status |= FE_HAS_CARRIER; /* Phase locked */
if (sync & 0x04) if (sync & 0x04)
*status |= FE_HAS_VITERBI; *status |= FE_HAS_VITERBI;
/* Reed-Solomon Status */
if (sync & 0x08) if (sync & 0x08)
*status |= FE_HAS_SYNC; *status |= FE_HAS_SYNC;
if (sync & 0x80) if (sync & 0x80)
*status |= FE_HAS_LOCK; *status |= FE_HAS_LOCK; /*Full Sync */
return 0; return 0;
} }
...@@ -795,29 +808,13 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) ...@@ -795,29 +808,13 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
{ {
struct cx24123_state *state = fe->demodulator_priv; struct cx24123_state *state = fe->demodulator_priv;
state->lastber = /* The true bit error rate is this value divided by
((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | the window size (set as 256 * 255) */
*ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
(cx24123_readreg(state, 0x1d) << 8 | (cx24123_readreg(state, 0x1d) << 8 |
cx24123_readreg(state, 0x1e)); cx24123_readreg(state, 0x1e));
/* Do the signal quality processing here, it's derived from the BER. */
/* Scale the BER from a 24bit to a SNR 16 bit where higher = better */
if (state->lastber < 5000)
state->snr = 655*100;
else if ( (state->lastber >= 5000) && (state->lastber < 55000) )
state->snr = 655*90;
else if ( (state->lastber >= 55000) && (state->lastber < 150000) )
state->snr = 655*80;
else if ( (state->lastber >= 150000) && (state->lastber < 250000) )
state->snr = 655*70;
else if ( (state->lastber >= 250000) && (state->lastber < 450000) )
state->snr = 655*65;
else
state->snr = 0;
dprintk("%s: BER = %d, S/N index = %d\n",__FUNCTION__,state->lastber, state->snr);
*ber = state->lastber; dprintk("%s: BER = %d\n",__FUNCTION__,*ber);
return 0; return 0;
} }
...@@ -825,6 +822,7 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) ...@@ -825,6 +822,7 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
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; struct cx24123_state *state = fe->demodulator_priv;
*signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength); dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength);
...@@ -835,19 +833,13 @@ static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_str ...@@ -835,19 +833,13 @@ static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
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; struct cx24123_state *state = fe->demodulator_priv;
*snr = state->snr;
dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr);
return 0; /* Inverted raw Es/N0 count, totally bogus but better than the
} BER threshold. */
*snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
(u16)cx24123_readreg(state, 0x19));
static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr);
{
struct cx24123_state *state = fe->demodulator_priv;
*ucblocks = state->lastber;
dprintk("%s: ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks);
return 0; return 0;
} }
...@@ -922,6 +914,29 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) ...@@ -922,6 +914,29 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
return 0; return 0;
} }
static int cx24123_tune(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params,
unsigned int mode_flags,
int *delay,
fe_status_t *status)
{
int retval = 0;
if (params != NULL)
retval = cx24123_set_frontend(fe, params);
if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
cx24123_read_status(fe, status);
*delay = HZ/10;
return retval;
}
static int cx24123_get_algo(struct dvb_frontend *fe)
{
return 1; //FE_ALGO_HW
}
static void cx24123_release(struct dvb_frontend* fe) static void cx24123_release(struct dvb_frontend* fe)
{ {
struct cx24123_state* state = fe->demodulator_priv; struct cx24123_state* state = fe->demodulator_priv;
...@@ -949,8 +964,6 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, ...@@ -949,8 +964,6 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
/* setup the state */ /* setup the state */
state->config = config; state->config = config;
state->i2c = i2c; state->i2c = i2c;
state->lastber = 0;
state->snr = 0;
state->VCAarg = 0; state->VCAarg = 0;
state->VGAarg = 0; state->VGAarg = 0;
state->bandselectarg = 0; state->bandselectarg = 0;
...@@ -1003,11 +1016,12 @@ static struct dvb_frontend_ops cx24123_ops = { ...@@ -1003,11 +1016,12 @@ static struct dvb_frontend_ops cx24123_ops = {
.read_ber = cx24123_read_ber, .read_ber = cx24123_read_ber,
.read_signal_strength = cx24123_read_signal_strength, .read_signal_strength = cx24123_read_signal_strength,
.read_snr = cx24123_read_snr, .read_snr = cx24123_read_snr,
.read_ucblocks = cx24123_read_ucblocks,
.diseqc_send_master_cmd = cx24123_send_diseqc_msg, .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
.diseqc_send_burst = cx24123_diseqc_send_burst, .diseqc_send_burst = cx24123_diseqc_send_burst,
.set_tone = cx24123_set_tone, .set_tone = cx24123_set_tone,
.set_voltage = cx24123_set_voltage, .set_voltage = cx24123_set_voltage,
.tune = cx24123_tune,
.get_frontend_algo = cx24123_get_algo,
}; };
module_param(debug, int, 0644); module_param(debug, int, 0644);
......
...@@ -30,9 +30,21 @@ struct cx24123_config ...@@ -30,9 +30,21 @@ struct cx24123_config
/* Need to set device param for start_dma */ /* Need to set device param for start_dma */
int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
/* 0 = LNB voltage normal, 1 = LNB voltage inverted */
int lnb_polarity;
}; };
#if defined(CONFIG_DVB_CX24123) || defined(CONFIG_DVB_CX24123_MODULE)
extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
struct i2c_adapter* i2c); struct i2c_adapter* i2c);
#else
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__);
return NULL;
}
#endif // CONFIG_DVB_CX24123
#endif /* CX24123_H */ #endif /* CX24123_H */
#include "dib3000-common.h"
#ifdef CONFIG_DVB_DIBCOM_DEBUG
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
#endif
#define deb_info(args...) dprintk(0x01,args)
#define deb_i2c(args...) dprintk(0x02,args)
#define deb_srch(args...) dprintk(0x04,args)
int dib3000_read_reg(struct dib3000_state *state, u16 reg)
{
u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
u8 rb[2];
struct i2c_msg msg[] = {
{ .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
{ .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
};
if (i2c_transfer(state->i2c, msg, 2) != 2)
deb_i2c("i2c read error\n");
deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
(rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
return (rb[0] << 8) | rb[1];
}
int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
{
u8 b[] = {
(reg >> 8) & 0xff, reg & 0xff,
(val >> 8) & 0xff, val & 0xff,
};
struct i2c_msg msg[] = {
{ .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
};
deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
}
int dib3000_search_status(u16 irq,u16 lock)
{
if (irq & 0x02) {
if (lock & 0x01) {
deb_srch("auto search succeeded\n");
return 1; // auto search succeeded
} else {
deb_srch("auto search not successful\n");
return 0; // auto search failed
}
} else if (irq & 0x01) {
deb_srch("auto search failed\n");
return 0; // auto search failed
}
return -1; // try again
}
/* for auto search */
u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
{ /* fft */
{ /* gua */
{ 0, 1 }, /* 0 0 { 0,1 } */
{ 3, 9 }, /* 0 1 { 0,1 } */
},
{
{ 2, 5 }, /* 1 0 { 0,1 } */
{ 6, 11 }, /* 1 1 { 0,1 } */
}
};
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb frontend drivers");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(dib3000_seq);
EXPORT_SYMBOL(dib3000_read_reg);
EXPORT_SYMBOL(dib3000_write_reg);
EXPORT_SYMBOL(dib3000_search_status);
/*
* .h-files for the common use of the frontend drivers made by DiBcom
* DiBcom 3000M-B/C, 3000P
*
* DiBcom (http://www.dibcom.fr/)
*
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
*
* based on GPL code from DibCom, which has
*
* Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*
* Acknowledgements
*
* Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
* sources, on which this driver (and the dvb-dibusb) are based.
*
* see Documentation/dvb/README.dibusb for more information
*
*/
#ifndef DIB3000_COMMON_H
#define DIB3000_COMMON_H
#include "dvb_frontend.h"
#include "dib3000.h"
/* info and err, taken from usb.h, if there is anything available like by default. */
#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
/* frontend state */
struct dib3000_state {
struct i2c_adapter* i2c;
/* configuration settings */
struct dib3000_config config;
struct dvb_frontend frontend;
int timing_offset;
int timing_offset_comp_done;
fe_bandwidth_t last_tuned_bw;
u32 last_tuned_freq;
};
/* commonly used methods by the dib3000mb/mc/p frontend */
extern int dib3000_read_reg(struct dib3000_state *state, u16 reg);
extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val);
extern int dib3000_search_status(u16 irq,u16 lock);
/* handy shortcuts */
#define rd(reg) dib3000_read_reg(state,reg)
#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
{ err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
#define wr_foreach(a,v) { int i; \
if (sizeof(a) != sizeof(v)) \
err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
for (i=0; i < sizeof(a)/sizeof(u16); i++) \
wr(a[i],v[i]); \
}
#define set_or(reg,val) wr(reg,rd(reg) | val)
#define set_and(reg,val) wr(reg,rd(reg) & val)
/* debug */
#ifdef CONFIG_DVB_DIBCOM_DEBUG
#define dprintk(level,args...) \
do { if ((debug & level)) { printk(args); } } while (0)
#else
#define dprintk(args...) do { } while (0)
#endif
/* mask for enabling a specific pid for the pid_filter */
#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
/* common values for tuning */
#define DIB3000_ALPHA_0 ( 0)
#define DIB3000_ALPHA_1 ( 1)
#define DIB3000_ALPHA_2 ( 2)
#define DIB3000_ALPHA_4 ( 4)
#define DIB3000_CONSTELLATION_QPSK ( 0)
#define DIB3000_CONSTELLATION_16QAM ( 1)
#define DIB3000_CONSTELLATION_64QAM ( 2)
#define DIB3000_GUARD_TIME_1_32 ( 0)
#define DIB3000_GUARD_TIME_1_16 ( 1)
#define DIB3000_GUARD_TIME_1_8 ( 2)
#define DIB3000_GUARD_TIME_1_4 ( 3)
#define DIB3000_TRANSMISSION_MODE_2K ( 0)
#define DIB3000_TRANSMISSION_MODE_8K ( 1)
#define DIB3000_SELECT_LP ( 0)
#define DIB3000_SELECT_HP ( 1)
#define DIB3000_FEC_1_2 ( 1)
#define DIB3000_FEC_2_3 ( 2)
#define DIB3000_FEC_3_4 ( 3)
#define DIB3000_FEC_5_6 ( 5)
#define DIB3000_FEC_7_8 ( 7)
#define DIB3000_HRCH_OFF ( 0)
#define DIB3000_HRCH_ON ( 1)
#define DIB3000_DDS_INVERSION_OFF ( 0)
#define DIB3000_DDS_INVERSION_ON ( 1)
#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
/* for auto search */
extern u16 dib3000_seq[2][2][2];
#define DIB3000_REG_MANUFACTOR_ID ( 1025)
#define DIB3000_I2C_ID_DIBCOM (0x01b3)
#define DIB3000_REG_DEVICE_ID ( 1026)
#define DIB3000MB_DEVICE_ID (0x3000)
#define DIB3000MC_DEVICE_ID (0x3001)
#define DIB3000P_DEVICE_ID (0x3002)
#endif // DIB3000_COMMON_H
...@@ -41,9 +41,16 @@ struct dib_fe_xfer_ops ...@@ -41,9 +41,16 @@ struct dib_fe_xfer_ops
int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
}; };
#if defined(CONFIG_DVB_DIB3000MB) || defined(CONFIG_DVB_DIB3000MB_MODULE)
extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
#else
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__);
return NULL;
}
#endif // CONFIG_DVB_DIB3000MB
extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
#endif // DIB3000_H #endif // DIB3000_H
...@@ -29,9 +29,10 @@ ...@@ -29,9 +29,10 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "dib3000-common.h" #include "dvb_frontend.h"
#include "dib3000mb_priv.h"
#include "dib3000.h" #include "dib3000.h"
#include "dib3000mb_priv.h"
/* Version information */ /* Version information */
#define DRIVER_VERSION "0.1" #define DRIVER_VERSION "0.1"
...@@ -44,10 +45,81 @@ module_param(debug, int, 0644); ...@@ -44,10 +45,81 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
#endif #endif
#define deb_info(args...) dprintk(0x01,args) #define deb_info(args...) dprintk(0x01,args)
#define deb_i2c(args...) dprintk(0x02,args)
#define deb_srch(args...) dprintk(0x04,args)
#define deb_info(args...) dprintk(0x01,args)
#define deb_xfer(args...) dprintk(0x02,args) #define deb_xfer(args...) dprintk(0x02,args)
#define deb_setf(args...) dprintk(0x04,args) #define deb_setf(args...) dprintk(0x04,args)
#define deb_getf(args...) dprintk(0x08,args) #define deb_getf(args...) dprintk(0x08,args)
#ifdef CONFIG_DVB_DIBCOM_DEBUG
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
#endif
static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
{
u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
u8 rb[2];
struct i2c_msg msg[] = {
{ .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
{ .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
};
if (i2c_transfer(state->i2c, msg, 2) != 2)
deb_i2c("i2c read error\n");
deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
(rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
return (rb[0] << 8) | rb[1];
}
static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
{
u8 b[] = {
(reg >> 8) & 0xff, reg & 0xff,
(val >> 8) & 0xff, val & 0xff,
};
struct i2c_msg msg[] = {
{ .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
};
deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
}
static int dib3000_search_status(u16 irq,u16 lock)
{
if (irq & 0x02) {
if (lock & 0x01) {
deb_srch("auto search succeeded\n");
return 1; // auto search succeeded
} else {
deb_srch("auto search not successful\n");
return 0; // auto search failed
}
} else if (irq & 0x01) {
deb_srch("auto search failed\n");
return 0; // auto search failed
}
return -1; // try again
}
/* for auto search */
static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
{ /* fft */
{ /* gua */
{ 0, 1 }, /* 0 0 { 0,1 } */
{ 3, 9 }, /* 0 1 { 0,1 } */
},
{
{ 2, 5 }, /* 1 0 { 0,1 } */
{ 6, 11 }, /* 1 1 { 0,1 } */
}
};
static int dib3000mb_get_frontend(struct dvb_frontend* fe, static int dib3000mb_get_frontend(struct dvb_frontend* fe,
struct dvb_frontend_parameters *fep); struct dvb_frontend_parameters *fep);
......
...@@ -13,6 +13,99 @@ ...@@ -13,6 +13,99 @@
#ifndef __DIB3000MB_PRIV_H_INCLUDED__ #ifndef __DIB3000MB_PRIV_H_INCLUDED__
#define __DIB3000MB_PRIV_H_INCLUDED__ #define __DIB3000MB_PRIV_H_INCLUDED__
/* info and err, taken from usb.h, if there is anything available like by default. */
#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
/* handy shortcuts */
#define rd(reg) dib3000_read_reg(state,reg)
#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
{ err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
#define wr_foreach(a,v) { int i; \
if (sizeof(a) != sizeof(v)) \
err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
for (i=0; i < sizeof(a)/sizeof(u16); i++) \
wr(a[i],v[i]); \
}
#define set_or(reg,val) wr(reg,rd(reg) | val)
#define set_and(reg,val) wr(reg,rd(reg) & val)
/* debug */
#ifdef CONFIG_DVB_DIBCOM_DEBUG
#define dprintk(level,args...) \
do { if ((debug & level)) { printk(args); } } while (0)
#else
#define dprintk(args...) do { } while (0)
#endif
/* mask for enabling a specific pid for the pid_filter */
#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
/* common values for tuning */
#define DIB3000_ALPHA_0 ( 0)
#define DIB3000_ALPHA_1 ( 1)
#define DIB3000_ALPHA_2 ( 2)
#define DIB3000_ALPHA_4 ( 4)
#define DIB3000_CONSTELLATION_QPSK ( 0)
#define DIB3000_CONSTELLATION_16QAM ( 1)
#define DIB3000_CONSTELLATION_64QAM ( 2)
#define DIB3000_GUARD_TIME_1_32 ( 0)
#define DIB3000_GUARD_TIME_1_16 ( 1)
#define DIB3000_GUARD_TIME_1_8 ( 2)
#define DIB3000_GUARD_TIME_1_4 ( 3)
#define DIB3000_TRANSMISSION_MODE_2K ( 0)
#define DIB3000_TRANSMISSION_MODE_8K ( 1)
#define DIB3000_SELECT_LP ( 0)
#define DIB3000_SELECT_HP ( 1)
#define DIB3000_FEC_1_2 ( 1)
#define DIB3000_FEC_2_3 ( 2)
#define DIB3000_FEC_3_4 ( 3)
#define DIB3000_FEC_5_6 ( 5)
#define DIB3000_FEC_7_8 ( 7)
#define DIB3000_HRCH_OFF ( 0)
#define DIB3000_HRCH_ON ( 1)
#define DIB3000_DDS_INVERSION_OFF ( 0)
#define DIB3000_DDS_INVERSION_ON ( 1)
#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
#define DIB3000_REG_MANUFACTOR_ID ( 1025)
#define DIB3000_I2C_ID_DIBCOM (0x01b3)
#define DIB3000_REG_DEVICE_ID ( 1026)
#define DIB3000MB_DEVICE_ID (0x3000)
#define DIB3000MC_DEVICE_ID (0x3001)
#define DIB3000P_DEVICE_ID (0x3002)
/* frontend state */
struct dib3000_state {
struct i2c_adapter* i2c;
/* configuration settings */
struct dib3000_config config;
struct dvb_frontend frontend;
int timing_offset;
int timing_offset_comp_done;
fe_bandwidth_t last_tuned_bw;
u32 last_tuned_freq;
};
/* register addresses and some of their default values */ /* register addresses and some of their default values */
/* restart subsystems */ /* restart subsystems */
......
This diff is collapsed.
/*
* Driver for DiBcom DiB3000MC/P-demodulator.
*
* Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de)
*
* This code is partially based on the previous dib3000mc.c .
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*/
#ifndef DIB3000MC_H
#define DIB3000MC_H
#include "dibx000_common.h"
struct dib3000mc_config {
struct dibx000_agc_config *agc;
u8 phase_noise_mode;
u8 impulse_noise_mode;
u8 pwm3_inversion;
u8 use_pwm3;
u16 pwm3_value;
u16 max_time;
u16 ln_adc_level;
u8 mobile_mode;
u8 output_mpeg2_in_188_bytes;
};
#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
#define DEFAULT_DIB3000P_I2C_ADDRESS 24
#if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE)
extern int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr,
u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[]);
#else
static inline struct dvb_frontend* dib3000mc_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__);
return NULL;
}
#endif // CONFIG_DVB_DIB3000MC
extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
extern void dib3000mc_set_config(struct dvb_frontend *, struct dib3000mc_config *);
#endif
This diff is collapsed.
#include <linux/i2c.h>
#include "dibx000_common.h"
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0)
static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
{
u8 b[4] = {
(reg >> 8) & 0xff, reg & 0xff,
(val >> 8) & 0xff, val & 0xff,
};
struct i2c_msg msg = {
.addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4
};
return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}
static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf)
{
if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
dprintk("selecting interface: %d\n",intf);
mst->selected_interface = intf;
return dibx000_write_word(mst, mst->base_reg + 4, intf);
}
return 0;
}
static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff)
{
u16 val;
if (onoff)
val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
else
val = 1 << 7;
if (mst->device_rev > DIB7000)
val <<= 1;
tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
tx[1] = ( (mst->base_reg + 1) & 0xff);
tx[2] = val >> 8;
tx[3] = val & 0xff;
return 0;
}
static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
}
static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
{
struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
struct i2c_msg m[2 + num];
u8 tx_open[4], tx_close[4];
memset(m,0, sizeof(struct i2c_msg) * (2 + num));
dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
m[0].addr = mst->i2c_addr;
m[0].buf = tx_open;
m[0].len = 4;
memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
m[num+1].addr = mst->i2c_addr;
m[num+1].buf = tx_close;
m[num+1].len = 4;
return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO;
}
static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
.master_xfer = dibx000_i2c_gated_tuner_xfer,
.functionality = dibx000_i2c_func,
};
struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating)
{
struct i2c_adapter *i2c = NULL;
switch (intf) {
case DIBX000_I2C_INTERFACE_TUNER:
if (gating)
i2c = &mst->gated_tuner_i2c_adap;
break;
default:
printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
break;
}
return i2c;
}
EXPORT_SYMBOL(dibx000_get_i2c_adapter);
static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char name[I2C_NAME_SIZE], struct dibx000_i2c_master *mst)
{
strncpy(i2c_adap->name, name, I2C_NAME_SIZE);
i2c_adap->class = I2C_CLASS_TV_DIGITAL,
i2c_adap->algo = algo;
i2c_adap->algo_data = NULL;
i2c_set_adapdata(i2c_adap, mst);
if (i2c_add_adapter(i2c_adap) < 0)
return -ENODEV;
return 0;
}
int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr)
{
u8 tx[4];
struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 };
mst->device_rev = device_rev;
mst->i2c_adap = i2c_adap;
mst->i2c_addr = i2c_addr >> 1;
if (device_rev == DIB7000P)
mst->base_reg = 1024;
else
mst->base_reg = 768;
if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0)
printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n");
/* initialize the i2c-master by closing the gate */
dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
return i2c_transfer(i2c_adap, &m, 1) == 1;
}
EXPORT_SYMBOL(dibx000_init_i2c_master);
void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
{
i2c_del_adapter(&mst->gated_tuner_i2c_adap);
}
EXPORT_SYMBOL(dibx000_exit_i2c_master);
MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
...@@ -57,8 +57,8 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, ...@@ -57,8 +57,8 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
* @param pll_addr i2c address of the PLL (if used). * @param pll_addr i2c address of the PLL (if used).
* @param i2c i2c adapter to use (set to NULL if not used). * @param i2c i2c adapter to use (set to NULL if not used).
* @param desc dvb_pll_desc to use. * @param desc dvb_pll_desc to use.
* @return 0 on success, nonzero on failure. * @return Frontend pointer on success, NULL on failure
*/ */
extern int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc); extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc);
#endif #endif
This diff is collapsed.
...@@ -39,8 +39,17 @@ ...@@ -39,8 +39,17 @@
#define ISL6421_ISEL1 0x20 #define ISL6421_ISEL1 0x20
#define ISL6421_DCL 0x40 #define ISL6421_DCL 0x40
#if defined(CONFIG_DVB_ISL6421) || defined(CONFIG_DVB_ISL6421_MODULE)
/* override_set and override_clear control which system register bits (above) to always set & clear */ /* override_set and override_clear control which system register bits (above) to always set & clear */
extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
u8 override_set, u8 override_clear); u8 override_set, u8 override_clear);
#else
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__);
return NULL;
}
#endif // CONFIG_DVB_ISL6421
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment