📄 bttv-cards.c
字号:
.audiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = -1,
},{
/* Hiroshi Takekawa <sian@big.or.jp> */
/* This card lacks subsystem ID */
.name = "AD-TVK503", /* 0x63 */
.video_inputs = 4,
.audio_inputs = 1,
.tuner = 0,
.svhs = 2,
.gpiomask = 0x001e8007,
.muxsel = { 2, 3, 1, 0 },
/* Tuner, Radio, external, internal, off, on */
.audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = 2,
.audio_hook = adtvk503_audio,
},{
/* ---- card 0x64 ---------------------------------- */
.name = "Hercules Smart TV Stereo",
.video_inputs = 4,
.audio_inputs = 1,
.tuner = 0,
.svhs = 2,
.gpiomask = 0x00,
.muxsel = { 2, 3, 1, 1 },
.needs_tvaudio = 1,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = 5,
/* Notes:
- card lacks subsystem ID
- stereo variant w/ daughter board with tda9874a @0xb0
- Audio Routing:
always from tda9874 independent of GPIO (?)
external line in: unknown
- Other chips: em78p156elp @ 0x96 (probably IR remote control)
hef4053 (instead 4052) for unknown function
*/
},{
.name = "Pace TV & Radio Card",
.video_inputs = 4,
.audio_inputs = 1,
.tuner = 0,
.svhs = 2,
.muxsel = { 2, 3, 1, 1}, // Tuner, CVid, SVid, CVid over SVid connector
.gpiomask = 0,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = 1,
.has_radio = 1,
.pll = PLL_28,
/* Bt878, Bt832, FI1246 tuner; no pci subsystem id
only internal line out: (4pin header) RGGL
Radio must be decoded by msp3410d (not routed through)*/
// .digital_mode = DIGITAL_MODE_CAMERA, // todo!
},{
/* Chris Willing <chris@vislab.usyd.edu.au> */
.name = "IVC-200",
.video_inputs = 1,
.audio_inputs = 0,
.tuner = -1,
.tuner_type = -1,
.svhs = -1,
.gpiomask = 0xdf,
.muxsel = { 2 },
.pll = PLL_28,
},{
.name = "Grand X-Guard / Trust 814PCI",
.video_inputs = 16,
.audio_inputs = 0,
.tuner = -1,
.svhs = -1,
.tuner_type = 4,
.gpiomask2 = 0xff,
.muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
.muxsel_hook = xguard_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
},{
/* ---- card 0x68 ---------------------------------- */
.name = "Nebula Electronics DigiTV",
.svhs = -1,
.muxsel = { 2, 3, 1, 0},
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.tuner_type = -1,
.has_dvb = 1,
.no_gpioirq = 1,
},{
/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
.name = "ProVideo PV143",
.video_inputs = 4,
.audio_inputs = 0,
.tuner = -1,
.svhs = -1,
.gpiomask = 0,
.muxsel = { 2, 3, 1, 0 },
.audiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = -1,
},{
/* M.Klahr@phytec.de */
.name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
.video_inputs = 4,
.audio_inputs = 0,
.tuner = -1, /* card has no tuner */
.svhs = 3,
.gpiomask = 0x00,
.muxsel = { 2, 3, 1, 0},
.audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
},{
.name = "PHYTEC VD-009-X1 Combi (bt878)",
.video_inputs = 4,
.audio_inputs = 0,
.tuner = -1, /* card has no tuner */
.svhs = 3,
.gpiomask = 0x00,
.muxsel = { 2, 3, 1, 1},
.audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
},{
/* ---- card 0x6c ---------------------------------- */
.name = "PHYTEC VD-009 MiniDIN (bt878)",
.video_inputs = 10,
.audio_inputs = 0,
.tuner = -1, /* card has no tuner */
.svhs = 9,
.gpiomask = 0x00,
.gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
via the upper nibble of muxsel. here: used for
xternal video-mux */
.muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
.audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
},{
.name = "PHYTEC VD-009 Combi (bt878)",
.video_inputs = 10,
.audio_inputs = 0,
.tuner = -1, /* card has no tuner */
.svhs = 9,
.gpiomask = 0x00,
.gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
via the upper nibble of muxsel. here: used for
xternal video-mux */
.muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
.audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = -1,
},{
.name = "IVC-100",
.video_inputs = 4,
.audio_inputs = 0,
.tuner = -1,
.tuner_type = -1,
.svhs = -1,
.gpiomask = 0xdf,
.muxsel = { 2, 3, 1, 0 },
.pll = PLL_28,
},{
/* IVC-120G - Alan Garfield <alan@fromorbit.com> */
.name = "IVC-120G",
.video_inputs = 16,
.audio_inputs = 0, /* card has no audio */
.tuner = -1, /* card has no tuner */
.tuner_type = -1,
.svhs = -1, /* card has no svhs */
.needs_tvaudio = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.gpiomask = 0x00,
.muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
.muxsel_hook = ivc120_muxsel,
.pll = PLL_28,
},{
/* ---- card 0x70 ---------------------------------- */
.name = "pcHDTV HD-2000 TV",
.video_inputs = 4,
.audio_inputs = 1,
.tuner = 0,
.svhs = 2,
.muxsel = { 2, 3, 1, 0},
.tuner_type = TUNER_PHILIPS_ATSC,
},{
.name = "Twinhan DST + clones",
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.no_video = 1,
.has_dvb = 1,
},{
.name = "Winfast VC100",
.video_inputs = 3,
.audio_inputs = 0,
.svhs = 1,
.tuner = -1, // no tuner
.muxsel = { 3, 1, 1, 3}, // Vid In, SVid In, Vid over SVid in connector
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.no_video = 1,
.pll = PLL_28,
},{
.name = "Teppro TEV-560/InterVision IV-560",
.video_inputs = 3,
.audio_inputs = 1,
.tuner = 0,
.svhs = 2,
.gpiomask = 3,
.muxsel = { 2, 3, 1, 1},
.audiomux = { 1, 1, 1, 1, 0},
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.pll = PLL_35,
}};
const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
/* ----------------------------------------------------------------------- */
static unsigned char eeprom_data[256];
/*
* identify card
*/
void __devinit bttv_idcard(struct bttv *btv)
{
unsigned int gpiobits;
int i,type;
unsigned short tmp;
/* read PCI subsystem ID */
pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_ID, &tmp);
btv->cardid = tmp << 16;
pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_VENDOR_ID, &tmp);
btv->cardid |= tmp;
if (0 != btv->cardid && 0xffffffff != btv->cardid) {
/* look for the card */
for (type = -1, i = 0; cards[i].id != 0; i++)
if (cards[i].id == btv->cardid)
type = i;
if (type != -1) {
/* found it */
printk(KERN_INFO "bttv%d: detected: %s [card=%d], "
"PCI subsystem ID is %04x:%04x\n",
btv->c.nr,cards[type].name,cards[type].cardnr,
btv->cardid & 0xffff,
(btv->cardid >> 16) & 0xffff);
btv->c.type = cards[type].cardnr;
} else {
/* 404 */
printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n",
btv->c.nr, btv->cardid & 0xffff,
(btv->cardid >> 16) & 0xffff);
printk(KERN_DEBUG "please mail id, board name and "
"the correct card= insmod option to kraxel@bytesex.org\n");
}
}
/* let the user override the autodetected type */
if (card[btv->c.nr] < bttv_num_tvcards)
btv->c.type=card[btv->c.nr];
/* print which card config we are using */
printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->c.nr,
bttv_tvcards[btv->c.type].name, btv->c.type,
card[btv->c.nr] < bttv_num_tvcards
? "insmod option" : "autodetected");
/* overwrite gpio stuff ?? */
if (UNSET == audioall && UNSET == audiomux[0])
return;
if (UNSET != audiomux[0]) {
gpiobits = 0;
for (i = 0; i < 5; i++) {
bttv_tvcards[btv->c.type].audiomux[i] = audiomux[i];
gpiobits |= audiomux[i];
}
} else {
gpiobits = audioall;
for (i = 0; i < 5; i++) {
bttv_tvcards[btv->c.type].audiomux[i] = audioall;
}
}
bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=",
btv->c.nr,bttv_tvcards[btv->c.type].gpiomask);
for (i = 0; i < 5; i++) {
printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].audiomux[i]);
}
printk("\n");
}
/*
* (most) board specific initialisations goes here
*/
/* Some Modular Technology cards have an eeprom, but no subsystem ID */
void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
{
int type = -1;
if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
type = BTTV_MODTEC_205;
else if (0 == strncmp(eeprom_data+20,"Picolo",7))
type = BTTV_EURESYS_PICOLO;
else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
type = BTTV_HAUPPAUGE; /* old bt848 */
if (-1 != type) {
btv->c.type = type;
printk("bttv%d: detected by eeprom: %s [card=%d]\n",
btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type);
}
}
static void flyvideo_gpio(struct bttv *btv)
{
int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821;
int tuner=-1,ttype;
gpio_inout(0xffffff, 0);
udelay(8); // without this we would see the 0x1800 mask
gpio = gpio_read();
/* FIXME: must restore OUR_EN ??? */
// all cards provide GPIO info, some have an additional eeprom
// LR50: GPIO coding can be found lower right CP1 .. CP9
// CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1.
// GPIO14-12: n.c.
// LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
// lowest 3 bytes are remote control codes (no handshake needed)
// xxxFFF: No remote control chip soldered
// xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
// Note: Some bits are Audio_Mask !
ttype=(gpio&0x0f0000)>>16;
switch(ttype) {
case 0x0: tuner=2; // NTSC, e.g. TPI8NSR11P
break;
case 0x2: tuner=39;// LG NTSC (newer TAPC series) TAPC-H701P
break;
case 0x4: tuner=5; // Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216
break;
case 0x6: tuner=37; // LG PAL (newer TAPC series) TAPC-G702P
break;
case 0xC: tuner=3; // Philips SECAM(+PAL) FQ1216ME or FI1216MF
break;
default:
printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr);
}
has_remote = gpio & 0x800000;
has_radio = gpio & 0x400000;
// unknown 0x200000;
// unknown2 0x100000;
is_capture_only = !(gpio & 0x008000); //GPIO15
has_tda9820_tda9821 = !(gpio & 0x004000);
is_lr90 = !(gpio & 0x002000); // else LR26/LR50 (LR38/LR51 f. capture only)
// gpio & 0x001000 // output bit for audio routing
if(is_capture_only)
tuner=4; // No tuner present
printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio);
printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n",
btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ",
is_capture_only?"yes":"no ");
if(tuner!= -1) // only set if known tuner autodetected, else let insmod option through
btv->tuner_type = tuner;
btv->has_radio = has_radio;
// LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
// LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
// Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute
if(has_tda9820_tda9821) btv->audio_hook = lt9415_audio;
//todo: if(has_tda9874) btv->audio_hook = fv2000s_audio;
}
int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1,
14,2,17,1, 4,1,4,3, 1,2,16,1, 4,4,4,4 };
int miro_fmtuner[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1,
1,1,1,1, 1,1,1,0, 0,0,0,0, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -