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>
---------------------------
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
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
......
......@@ -7,10 +7,10 @@
6 -> AverTV Studio 303 (M126) [1461:000b]
7 -> MSI TV-@nywhere Master [1462:8606]
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]
11 -> Prolink PlayTV PVR
12 -> ASUS PVR-416 [1043:4823]
12 -> ASUS PVR-416 [1043:4823,1461:c111]
13 -> MSI TV-@nywhere
14 -> KWorld/VStream XPert DVB-T [17de:08a6]
15 -> DViCO FusionHDTV DVB-T1 [18ac:db00]
......@@ -51,3 +51,7 @@
50 -> NPG Tech Real TV FM Top 10 [14f1:0842]
51 -> WinFast DTV2000 H [107d:665e]
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 @@
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370]
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]
62 -> Compro VideoMate TV Gold+II
63 -> Kworld Xpert TV PVR7134
......@@ -83,7 +83,7 @@
82 -> MSI TV@Anywhere plus [1462:6231]
83 -> Terratec Cinergy 250 PCI TV [153b:1160]
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]
87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421]
88 -> Tevion/KWorld DVB-T 220RF [17de:7201]
......@@ -94,3 +94,6 @@
93 -> Medion 7134 Bridge #2 [16be:0005]
94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502]
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
dropouts.
chroma_agc=0/1 AGC of chroma signal, off 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
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
config VIDEO_SAA7146_VV
tristate
select VIDEO_V4L2
select VIDEO_BUF
select VIDEO_VIDEOBUF
select VIDEO_SAA7146
......
......@@ -32,6 +32,37 @@ IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
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 */
IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
[ 0x28 ] = KEY_0, //'0' / 'enter'
......@@ -1473,3 +1504,51 @@ IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = {
};
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)
static struct video_device device_template =
{
.hardware = VID_HARDWARE_SAA7146,
.fops = &video_fops,
.minor = -1,
};
......
......@@ -2,13 +2,13 @@ config DVB_B2C2_FLEXCOP
tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
depends on DVB_CORE && I2C
select DVB_PLL
select DVB_STV0299
select DVB_MT352
select DVB_MT312
select DVB_NXT200X
select DVB_STV0297
select DVB_BCM3510
select DVB_LGDT330X
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_MT312 if !DVB_FE_CUSTOMISE
select DVB_NXT200X if !DVB_FE_CUSTOMISE
select DVB_STV0297 if !DVB_FE_CUSTOMISE
select DVB_BCM3510 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes.
......
......@@ -505,7 +505,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
struct dvb_frontend_ops *ops;
/* 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->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
......@@ -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);
} else
/* 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->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
} else
/* 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;
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);
} else
/* 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->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);
} else
/* 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;
info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
} else
/* 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->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
} else
/* 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->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
......@@ -571,9 +571,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
} else {
if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
err("frontend registration failed!");
ops = &fc->fe->ops;
if (ops->release != NULL)
ops->release(fc->fe);
dvb_frontend_detach(fc->fe);
fc->fe = NULL;
return -EINVAL;
}
......@@ -584,8 +582,10 @@ int flexcop_frontend_init(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_frontend_detach(fc->fe);
}
fc->init_state &= ~FC_STATE_FE_INIT;
}
......@@ -2,13 +2,13 @@ config DVB_BT8XX
tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && I2C && VIDEO_BT848
select DVB_PLL
select DVB_MT352
select DVB_SP887X
select DVB_NXT6000
select DVB_CX24110
select DVB_OR51211
select DVB_LGDT330X
select DVB_ZL10353
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_SP887X if !DVB_FE_CUSTOMISE
select DVB_NXT6000 if !DVB_FE_CUSTOMISE
select DVB_CX24110 if !DVB_FE_CUSTOMISE
select DVB_OR51211 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select FW_LOADER
help
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
static void dst_release(struct dvb_frontend *fe)
{
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);
}
......
......@@ -699,12 +699,17 @@ static struct dvb_device dvbdev_ca = {
.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;
dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA);
return 0;
if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
dst->dst_ca = dvbdev;
return dst->dst_ca;
}
return NULL;
}
EXPORT_SYMBOL(dst_ca_attach);
......
......@@ -140,6 +140,7 @@ struct dst_state {
char *tuner_name;
struct mutex dst_mutex;
u8 fw_name[8];
struct dvb_device *dst_ca;
};
struct tuner_types {
......@@ -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);
u8 dst_check_sum(u8 * buf, u32 len);
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_command(struct dst_state* state, u8 * data, u8 len);
......
......@@ -67,7 +67,7 @@ static void dvb_bt8xx_task(unsigned long data)
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;
int rc;
......@@ -595,15 +595,14 @@ static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
{
int ret;
struct dst_state* state = NULL;
switch(type) {
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)
card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config,
card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config,
card->i2c_adapter);
if (card->fe != NULL) {
......@@ -615,7 +614,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
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) {
card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params;
dprintk ("dvb_bt8xx: lgdt330x detected\n");
......@@ -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 */
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) {
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");
......@@ -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 */
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) {
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)
break;
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) {
card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params;
}
break;
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) {
card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs;
card->fe->ops.info.frequency_min = 174000000;
......@@ -670,22 +669,21 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
state->config = &dst_config;
state->i2c = card->i2c_adapter;
state->bt = card->bt;
state->dst_ca = NULL;
/* 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__);
break;
}
card->fe = &state->frontend;
/* Attach other DST peripherals if any */
/* Conditional Access device */
card->fe = &state->frontend;
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;
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) {
card->fe->ops.tuner_ops.init = pinnsat_tuner_init;
card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep;
......@@ -694,7 +692,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
break;
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;
}
......@@ -707,8 +705,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
else
if (dvb_register_frontend(&card->dvb_adapter, card->fe)) {
printk("dvb-bt8xx: Frontend registration failed!\n");
if (card->fe->ops.release)
card->fe->ops.release(card->fe);
dvb_frontend_detach(card->fe);
card->fe = NULL;
}
}
......@@ -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);
dvb_dmxdev_release(&card->dmxdev);
dvb_dmx_release(&card->demux);
if (card->fe)
if (card->fe) {
dvb_unregister_frontend(card->fe);
dvb_frontend_detach(card->fe);
}
dvb_unregister_adapter(&card->dvb_adapter);
kfree(card);
......
......@@ -9,3 +9,16 @@ config DVB_CORE
in-kernel drivers will select this automatically if needed.
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)
mutex_lock(&frontend_mutex);
dvb_unregister_device (fepriv->dvbdev);
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 */
kfree(fepriv);
mutex_unlock(&frontend_mutex);
return 0;
}
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 {
struct dvb_frontend_info info;
void (*release)(struct dvb_frontend* fe);
void (*release_sec)(struct dvb_frontend* fe);
int (*init)(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 */
int (*tune)(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params,
......@@ -147,7 +150,7 @@ struct dvb_frontend {
void* demodulator_priv;
void* tuner_priv;
void* frontend_priv;
void* misc_priv;
void* sec_priv;
};
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 void dvb_frontend_detach(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);
......
......@@ -102,4 +102,26 @@ extern int dvb_usercopy(struct inode *inode, struct file *file,
int (*func)(struct inode *inode, struct file *file,
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_ */
......@@ -26,6 +26,7 @@ config DVB_USB_A800
tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
depends on DVB_USB
select DVB_DIB3000MC
select DVB_TUNER_MT2060
help
Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
......@@ -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)"
depends on DVB_USB
select DVB_DIB3000MB
select DVB_TUNER_MT2060
help
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.
......@@ -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)"
depends on DVB_USB
select DVB_DIB3000MC
select DVB_TUNER_MT2060
help
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.
......@@ -80,16 +83,17 @@ config DVB_USB_UMT_010
tristate "HanfTek UMT-010 DVB-T USB2.0 support"
depends on DVB_USB
select DVB_DIB3000MC
select DVB_TUNER_MT2060
help
Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
config DVB_USB_CXUSB
tristate "Conexant USB2.0 hybrid reference design support"
depends on DVB_USB
select DVB_CX22702
select DVB_LGDT330X
select DVB_MT352
select DVB_ZL10353
select DVB_CX22702 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
help
Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode
......@@ -101,8 +105,8 @@ config DVB_USB_CXUSB
config DVB_USB_DIGITV
tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
depends on DVB_USB
select DVB_NXT6000
select DVB_MT352
select DVB_NXT6000 if !DVB_FE_CUSTOMISE
select DVB_MT352 if !DVB_FE_CUSTOMISE
help
Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
......@@ -145,6 +149,7 @@ config DVB_USB_NOVA_T_USB2
tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
depends on DVB_USB
select DVB_DIB3000MC
select DVB_TUNER_MT2060
help
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)
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[] = {
{ 0x02, 0x01, KEY_PROG1 }, /* SOURCE */
{ 0x02, 0x00, KEY_POWER }, /* POWER */
......@@ -113,6 +120,7 @@ static struct dvb_usb_properties a800_properties = {
.power_ctrl = a800_power_ctrl,
.frontend_attach = dibusb_dib3000mc_frontend_attach,
.tuner_attach = dibusb_dib3000mc_tuner_attach,
.identify_state = a800_identify_state,
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = a800_rc_keys,
......
......@@ -349,6 +349,7 @@ static struct mt352_config cxusb_dee1601_config = {
static struct zl10353_config cxusb_zl10353_dee1601_config = {
.demod_address = 0x0f,
.parallel_ts = 1,
};
static struct mt352_config cxusb_mt352_config = {
......@@ -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);
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 -EIO;
......@@ -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);
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 -EIO;
......@@ -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);
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 -EIO;
......@@ -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);
if (((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
((d->fe = zl10353_attach(&cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
if (((d->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
((d->fe = dvb_attach(zl10353_attach, &cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
return 0;
return -EIO;
......
......@@ -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)
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++) {
/* write/read request */
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)
}
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)
{
struct dib3000_config demod_cfg;
if (dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000P_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0 ||
dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000MC_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0) {
if (d->priv != NULL) {
struct dibusb_state *st = d->priv;
for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
if ((d->fe = dib3000mc_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;
d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
st->ops.pid_parse = dib3000mc_pid_parse;
st->ops.pid_ctrl = dib3000mc_pid_control;
}
return 0;
}
return -ENODEV;
}
EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
static struct mt2060_config stk3000p_mt2060_config = {
0x60
};
int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
{
d->pll_addr = 0x60;
d->pll_desc = &dvb_pll_env57h1xd5;
d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
struct dibusb_state *st = d->priv;
int ret;
u8 a,b;
u16 if1 = 1220;
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;
}
EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
......@@ -267,6 +370,67 @@ struct dvb_usb_rc_key dibusb_rc_keys[] = {
{ 0x86, 0x1e, KEY_DOWN },
{ 0x86, 0x1f, KEY_LEFT },
{ 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);
......
......@@ -21,11 +21,11 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
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)
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;
return -ENODEV;
}
d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
......@@ -169,7 +169,7 @@ static struct dvb_usb_properties dibusb1_1_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.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,
.i2c_algo = &dibusb_i2c_algo,
......@@ -247,7 +247,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.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,
.i2c_algo = &dibusb_i2c_algo,
......@@ -272,8 +272,8 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
#endif
.devices = {
{ "Artec T1 USB1.1 TVBOX with AN2235",
{ &dibusb_dib3000mb_table[20], NULL },
{ &dibusb_dib3000mb_table[21], NULL },
{ &dibusb_dib3000mb_table[22], NULL },
},
#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
{ "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
......@@ -304,7 +304,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.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,
.i2c_algo = &dibusb_i2c_algo,
......@@ -355,7 +355,7 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.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,
.i2c_algo = &dibusb_i2c_algo,
......
......@@ -28,6 +28,17 @@ static struct usb_device_id dibusb_dib3000mc_table [] = {
/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
/* 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 */
};
MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
......@@ -50,7 +61,7 @@ static struct dvb_usb_properties dibusb_mc_properties = {
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dibusb_rc_keys,
.rc_key_map_size = 63, /* FIXME */
.rc_key_map_size = 111, /* FIXME */
.rc_query = dibusb_rc_query,
.i2c_algo = &dibusb_i2c_algo,
......@@ -68,16 +79,38 @@ static struct dvb_usb_properties dibusb_mc_properties = {
}
},
.num_device_descs = 2,
.num_device_descs = 7,
.devices = {
{ "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
{ &dibusb_dib3000mc_table[0], 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 },
{ 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 @@
#include "dvb-usb.h"
#include "dib3000.h"
#include "dib3000mc.h"
#include "mt2060.h"
/*
* protocol of all dibusb related devices
......@@ -96,6 +98,7 @@
struct dibusb_state {
struct dib_fe_xfer_ops ops;
int mt2060_present;
/* for RC5 remote control */
int old_toggle;
......
......@@ -128,11 +128,11 @@ static struct nxt6000_config digitv_nxt6000_config = {
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;
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;
return 0;
}
......@@ -147,21 +147,91 @@ static int digitv_tuner_attach(struct dvb_usb_device *d)
}
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)
{
int i;
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);
/* 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)
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)
deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
return 0;
......
......@@ -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 wt220u_fc_properties;
static struct dvb_usb_properties wt220u_properties;
static struct dvb_usb_properties wt220u_zl0353_properties;
......@@ -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 ||
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)
return 0;
......@@ -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_ZL0353_COLD) },
{ 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 },
};
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
......@@ -193,13 +198,54 @@ static struct dvb_usb_properties wt220u_properties = {
.num_device_descs = 1,
.devices = {
{ .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 },
},
{ 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 = {
.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
.pid_filter_count = 15,
......@@ -271,6 +317,6 @@ module_init(dtt200u_usb_module_init);
module_exit(dtt200u_usb_module_exit);
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_LICENSE("GPL");
......@@ -175,36 +175,36 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
int dvb_usb_fe_init(struct dvb_usb_device* d)
{
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;
}
d->props.frontend_attach(d);
/* 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_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep;
if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
err("Frontend registration failed.");
if (d->fe->ops.release)
d->fe->ops.release(d->fe);
dvb_frontend_detach(d->fe);
d->fe = NULL;
return -ENODEV;
}
} else
err("no frontend was attached by '%s'",d->desc->name);
/* only attach the tuner if the demod is there */
if (d->props.tuner_attach != NULL)
d->props.tuner_attach(d);
} else
err("no frontend was attached by '%s'",d->desc->name);
return 0;
}
int dvb_usb_fe_exit(struct dvb_usb_device *d)
{
if (d->fe != NULL)
if (d->fe != NULL) {
dvb_unregister_frontend(d->fe);
dvb_frontend_detach(d->fe);
}
return 0;
}
......@@ -12,7 +12,6 @@
/* Vendor IDs */
#define USB_VID_ADSTECH 0x06e1
#define USB_VID_ANCHOR 0x0547
#define USB_VID_WIDEVIEW 0x14aa
#define USB_VID_AVERMEDIA 0x07ca
#define USB_VID_COMPRO 0x185b
#define USB_VID_COMPRO_UNK 0x145f
......@@ -20,18 +19,21 @@
#define USB_VID_DIBCOM 0x10b8
#define USB_VID_DVICO 0x0fe9
#define USB_VID_EMPIA 0xeb1a
#define USB_VID_GENPIX 0x09c0
#define USB_VID_GRANDTEC 0x5032
#define USB_VID_HANFTEK 0x15f4
#define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025
#define USB_VID_KWORLD 0xeb2a
#define USB_VID_KYE 0x0458
#define USB_VID_LEADTEK 0x0413
#define USB_VID_LITEON 0x04ca
#define USB_VID_MEDION 0x1660
#define USB_VID_PINNACLE 0x2304
#define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
#define USB_VID_GENPIX 0x09c0
#define USB_VID_WIDEVIEW 0x14aa
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
......@@ -74,6 +76,8 @@
#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
#define USB_PID_ARTEC_T14_COLD 0x810b
#define USB_PID_ARTEC_T14_WARM 0x810c
#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
......@@ -82,8 +86,11 @@
#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
#define USB_PID_DTT200U_COLD 0x0201
#define USB_PID_DTT200U_WARM 0x0301
#define USB_PID_WT220U_ZAP250_COLD 0x0220
#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_WARM 0x022b
#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
......@@ -105,6 +112,15 @@
#define USB_PID_KYE_DVB_T_WARM 0x701f
#define USB_PID_PCTV_200E 0x020e
#define USB_PID_PCTV_400E 0x020f
#define USB_PID_LITEON_DVB_T_COLD 0xf000
#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
......@@ -6,6 +6,7 @@
* This file contains functions for initializing the the input-device and for handling remote-control-queries.
*/
#include "dvb-usb-common.h"
#include <linux/usb/input.h>
/* Remote-control poll function - called every dib->rc_query_interval ms to see
* whether the remote control has received anything.
......@@ -96,7 +97,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
return 0;
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();
if (!d->rc_input_dev)
......@@ -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->name = "IR-receiver inside an USB DVB receiver";
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 */
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 = {
.pid_filter_count = 32,
.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),
......
......@@ -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_address = 0xf;
d->fe = mt352_attach(&umt_config, &d->i2c_adap);
d->fe = dvb_attach(mt352_attach, &umt_config, &d->i2c_adap);
return 0;
}
......
menu "Customise DVB Frontends"
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"
depends on DVB_CORE
config DVB_STV0299
tristate "ST STV0299 based"
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_CX24110
tristate "Conexant CX24110 based"
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_CX24123
tristate "Conexant CX24123 based"
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_TDA8083
tristate "Philips TDA8083 based"
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_MT312
tristate "Zarlink VP310/MT312 based"
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_VES1X93
tristate "VLSI VES1893 or VES1993 based"
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_S5H1420
tristate "Samsung S5H1420 based"
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
A DVB-S tuner module. Say Y when you want to support this frontend.
......@@ -52,6 +77,7 @@ comment "DVB-T (terrestrial) frontends"
config DVB_SP8870
tristate "Spase sp8870 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
......@@ -64,6 +90,7 @@ config DVB_SP8870
config DVB_SP887X
tristate "Spase sp887x based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
......@@ -76,24 +103,28 @@ config DVB_SP887X
config DVB_CX22700
tristate "Conexant CX22700 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_CX22702
tristate "Conexant cx22702 demodulator (OFDM)"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_L64781
tristate "LSI L64781"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
......@@ -107,24 +138,28 @@ config DVB_TDA1004X
config DVB_NXT6000
tristate "NxtWave Communications NXT6000 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_MT352
tristate "Zarlink MT352 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_ZL10353
tristate "Zarlink ZL10353 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DIB3000MB
tristate "DiBcom 3000M-B"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
......@@ -132,6 +167,7 @@ config DVB_DIB3000MB
config DVB_DIB3000MC
tristate "DiBcom 3000P/M-C"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
......@@ -142,18 +178,21 @@ comment "DVB-C (cable) frontends"
config DVB_VES1820
tristate "VLSI VES1820 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_TDA10021
tristate "Philips TDA10021 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_STV0297
tristate "ST STV0297 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
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"
config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
......@@ -177,6 +217,7 @@ config DVB_NXT200X
config DVB_OR51211
tristate "Oren OR51211 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
......@@ -189,6 +230,7 @@ config DVB_OR51211
config DVB_OR51132
tristate "Oren OR51132 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
......@@ -204,6 +246,7 @@ config DVB_OR51132
config DVB_BCM3510
tristate "Broadcom BCM3510"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
......@@ -212,28 +255,52 @@ config DVB_BCM3510
config DVB_LGDT330X
tristate "LG Electronics LGDT3302/LGDT3303 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
comment "Miscellaneous devices"
comment "Tuners/PLL support"
depends on DVB_CORE
config DVB_PLL
tristate
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
tristate "LNBP21 SEC controller"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
An SEC control chip.
config DVB_ISL6421
tristate "ISL6421 SEC controller"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
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
......@@ -11,8 +11,8 @@ obj-$(CONFIG_DVB_CX22700) += cx22700.o
obj-$(CONFIG_DVB_CX24110) += cx24110.o
obj-$(CONFIG_DVB_TDA8083) += tda8083.o
obj-$(CONFIG_DVB_L64781) += l64781.o
obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o dib3000-common.o
obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dib3000-common.o
obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
obj-$(CONFIG_DVB_MT312) += mt312.o
obj-$(CONFIG_DVB_VES1820) += ves1820.o
obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
......@@ -33,3 +33,7 @@ obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.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
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,
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
......@@ -31,7 +31,16 @@ struct cx22700_config
u8 demod_address;
};
#if defined(CONFIG_DVB_CX22700) || defined(CONFIG_DVB_CX22700_MODULE)
extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
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
......@@ -399,7 +399,9 @@ static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
{
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;
}
......
......@@ -41,7 +41,16 @@ struct cx22702_config
u8 output_mode;
};
#if defined(CONFIG_DVB_CX22702) || defined(CONFIG_DVB_CX22702_MODULE)
extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
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
/*
/*
cx24110 - Single Chip Satellite Channel Receiver driver module
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)
}
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;
if (len != 3)
return -EINVAL;
/* 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 */
/* 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,0x70,0x15); /* auto mode 21 bits */
......@@ -329,19 +330,19 @@ int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
cx24110_writereg(state,0x72,0);
/* 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 */
while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
;
/* send another 8 bytes */
cx24110_writereg(state,0x72,(data>>16)&0xff);
cx24110_writereg(state,0x72,buf[1]);
while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
;
/* 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)
;
......@@ -642,6 +643,7 @@ static struct dvb_frontend_ops cx24110_ops = {
.release = cx24110_release,
.init = cx24110_initfe,
.write = _cx24110_pll_write,
.set_frontend = cx24110_set_frontend,
.get_frontend = cx24110_get_frontend,
.read_status = cx24110_read_status,
......@@ -664,4 +666,3 @@ MODULE_AUTHOR("Peter Hettkamp");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(cx24110_attach);
EXPORT_SYMBOL(cx24110_pll_write);
......@@ -33,9 +33,24 @@ struct cx24110_config
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,
struct i2c_adapter* i2c);
extern int cx24110_pll_write(struct dvb_frontend* fe, u32 data);
#else
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
......@@ -45,9 +45,6 @@ struct cx24123_state
struct dvb_frontend frontend;
u32 lastber;
u16 snr;
/* Some PLL specifics for tuning */
u32 VCAarg;
u32 VGAarg;
......@@ -194,7 +191,7 @@ static struct {
{0x06, 0x31}, /* MPEG (default) */
{0x0b, 0x00}, /* Freq search start point (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) */
{0x0f, 0xfe}, /* FEC search mask (all supported codes) */
{0x10, 0x01}, /* Default search inversion, no repeat (default) */
......@@ -223,8 +220,9 @@ static struct {
{0x44, 0x00}, /* Constellation (default) */
{0x45, 0x00}, /* Symbol count (default) */
{0x46, 0x0d}, /* Symbol rate estimator on (default) */
{0x56, 0x41}, /* Various (default) */
{0x56, 0xc1}, /* Error Counter = Viterbi BER */
{0x57, 0xff}, /* Error Counter Window (default) */
{0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
{0x67, 0x83}, /* Non-DCII symbol clock */
};
......@@ -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) )
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) {
case FEC_1_2:
dprintk("%s: set FEC to 1/2\n",__FUNCTION__);
......@@ -657,6 +661,10 @@ static int cx24123_initfe(struct dvb_frontend* fe)
for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
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;
}
......@@ -674,6 +682,9 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
case SEC_VOLTAGE_18:
dprintk("%s: setting voltage 18V\n", __FUNCTION__);
return cx24123_writereg(state, 0x29, val | 0x80);
case SEC_VOLTAGE_OFF:
/* already handled in cx88-dvb */
return 0;
default:
return -EINVAL;
};
......@@ -776,13 +787,15 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
if (lock & 0x01)
*status |= FE_HAS_SIGNAL;
if (sync & 0x02)
*status |= FE_HAS_CARRIER;
*status |= FE_HAS_CARRIER; /* Phase locked */
if (sync & 0x04)
*status |= FE_HAS_VITERBI;
/* Reed-Solomon Status */
if (sync & 0x08)
*status |= FE_HAS_SYNC;
if (sync & 0x80)
*status |= FE_HAS_LOCK;
*status |= FE_HAS_LOCK; /*Full Sync */
return 0;
}
......@@ -795,29 +808,13 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
{
struct cx24123_state *state = fe->demodulator_priv;
state->lastber =
((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
/* The true bit error rate is this value divided by
the window size (set as 256 * 255) */
*ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
(cx24123_readreg(state, 0x1d) << 8 |
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;
}
......@@ -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)
{
struct cx24123_state *state = fe->demodulator_priv;
*signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength);
......@@ -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)
{
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)
{
struct cx24123_state *state = fe->demodulator_priv;
*ucblocks = state->lastber;
dprintk("%s: ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks);
dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr);
return 0;
}
......@@ -922,6 +914,29 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
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)
{
struct cx24123_state* state = fe->demodulator_priv;
......@@ -949,8 +964,6 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
/* setup the state */
state->config = config;
state->i2c = i2c;
state->lastber = 0;
state->snr = 0;
state->VCAarg = 0;
state->VGAarg = 0;
state->bandselectarg = 0;
......@@ -1003,11 +1016,12 @@ static struct dvb_frontend_ops cx24123_ops = {
.read_ber = cx24123_read_ber,
.read_signal_strength = cx24123_read_signal_strength,
.read_snr = cx24123_read_snr,
.read_ucblocks = cx24123_read_ucblocks,
.diseqc_send_master_cmd = cx24123_send_diseqc_msg,
.diseqc_send_burst = cx24123_diseqc_send_burst,
.set_tone = cx24123_set_tone,
.set_voltage = cx24123_set_voltage,
.tune = cx24123_tune,
.get_frontend_algo = cx24123_get_algo,
};
module_param(debug, int, 0644);
......
......@@ -30,9 +30,21 @@ struct cx24123_config
/* Need to set device param for start_dma */
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,
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 */
#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
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,
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
......@@ -29,9 +29,10 @@
#include <linux/string.h>
#include <linux/slab.h>
#include "dib3000-common.h"
#include "dib3000mb_priv.h"
#include "dvb_frontend.h"
#include "dib3000.h"
#include "dib3000mb_priv.h"
/* Version information */
#define DRIVER_VERSION "0.1"
......@@ -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)).");
#endif
#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_setf(args...) dprintk(0x04,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,
struct dvb_frontend_parameters *fep);
......
......@@ -13,6 +13,99 @@
#ifndef __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 */
/* 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");
#ifndef DIBX000_COMMON_H
#define DIBX000_COMMON_H
enum dibx000_i2c_interface {
DIBX000_I2C_INTERFACE_TUNER = 0,
DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
DIBX000_I2C_INTERFACE_GPIO_3_4 = 2
};
struct dibx000_i2c_master {
#define DIB3000MC 1
#define DIB7000 2
#define DIB7000P 11
#define DIB7000MC 12
u16 device_rev;
enum dibx000_i2c_interface selected_interface;
// struct i2c_adapter tuner_i2c_adap;
struct i2c_adapter gated_tuner_i2c_adap;
struct i2c_adapter *i2c_adap;
u8 i2c_addr;
u16 base_reg;
};
extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr);
extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating);
extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
#define BAND_LBAND 0x01
#define BAND_UHF 0x02
#define BAND_VHF 0x04
struct dibx000_agc_config {
/* defines the capabilities of this AGC-setting - using the BAND_-defines*/
u8 band_caps;
u16 setup;
u16 inv_gain;
u16 time_stabiliz;
u8 alpha_level;
u16 thlock;
u8 wbd_inv;
u16 wbd_ref;
u8 wbd_sel;
u8 wbd_alpha;
u16 agc1_max;
u16 agc1_min;
u16 agc2_max;
u16 agc2_min;
u8 agc1_pt1;
u8 agc1_pt2;
u8 agc1_pt3;
u8 agc1_slope1;
u8 agc1_slope2;
u8 agc2_pt1;
u8 agc2_pt2;
u8 agc2_slope1;
u8 agc2_slope2;
u8 alpha_mant;
u8 alpha_exp;
u8 beta_mant;
u8 beta_exp;
u8 perform_agc_softsplit;
struct {
u16 min;
u16 max;
u16 min_thres;
u16 max_thres;
} split;
};
struct dibx000_bandwidth_config {
u32 internal;
u32 sampling;
u8 pll_prediv;
u8 pll_ratio;
u8 pll_range;
u8 pll_reset;
u8 pll_bypass;
u8 enable_refdiv;
u8 bypclk_div;
u8 IO_CLK_en_core;
u8 ADClkSrc;
u8 modulo;
u16 sad_cfg;
u32 ifreq;
u32 timf;
};
enum dibx000_adc_states {
DIBX000_SLOW_ADC_ON = 0,
DIBX000_SLOW_ADC_OFF,
DIBX000_ADC_ON,
DIBX000_ADC_OFF,
DIBX000_VBG_ENABLE,
DIBX000_VBG_DISABLE,
};
#define BW_INDEX_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \
(v) == BANDWIDTH_7_MHZ ? 7000 : \
(v) == BANDWIDTH_6_MHZ ? 6000 : 8000 )
/* Chip output mode. */
#define OUTMODE_HIGH_Z 0
#define OUTMODE_MPEG2_PAR_GATED_CLK 1
#define OUTMODE_MPEG2_PAR_CONT_CLK 2
#define OUTMODE_MPEG2_SERIAL 7
#define OUTMODE_DIVERSITY 4
#define OUTMODE_MPEG2_FIFO 5
/* I hope I can get rid of the following kludge in the near future */
struct dibx000_ofdm_channel {
u8 Bw;
s16 nfft;
s16 guard;
s16 nqam;
s16 vit_hrch;
s16 vit_select_hp;
s16 vit_alpha;
s16 vit_code_rate_hp;
s16 vit_code_rate_lp;
};
#define FEP2DIB(fep,ch) \
(ch)->Bw = (fep)->u.ofdm.bandwidth; \
(ch)->nfft = (fep)->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ? -1 : (fep)->u.ofdm.transmission_mode; \
(ch)->guard = (fep)->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ? -1 : (fep)->u.ofdm.guard_interval; \
(ch)->nqam = (fep)->u.ofdm.constellation == QAM_AUTO ? -1 : (fep)->u.ofdm.constellation == QAM_64 ? 2 : (fep)->u.ofdm.constellation; \
(ch)->vit_hrch = 0; /* linux-dvb is not prepared for HIERARCHICAL TRANSMISSION */ \
(ch)->vit_select_hp = 1; \
(ch)->vit_alpha = 1; \
(ch)->vit_code_rate_hp = (fep)->u.ofdm.code_rate_HP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_HP; \
(ch)->vit_code_rate_lp = (fep)->u.ofdm.code_rate_LP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_LP;
#define INIT_OFDM_CHANNEL(ch) do {\
(ch)->Bw = 0; \
(ch)->nfft = -1; \
(ch)->guard = -1; \
(ch)->nqam = -1; \
(ch)->vit_hrch = -1; \
(ch)->vit_select_hp = -1; \
(ch)->vit_alpha = -1; \
(ch)->vit_code_rate_hp = -1; \
(ch)->vit_code_rate_lp = -1; \
} while (0)
#endif
This diff is collapsed.
......@@ -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 i2c i2c adapter to use (set to NULL if not used).
* @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
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.
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