📄 bttv-cards.c
字号:
printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", btv->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->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,0,0,0 };static void miro_pinnacle_gpio(struct bttv *btv){ int id,msp; id = ((btread(BT848_GPIO_DATA)>>10) & 31) -1; msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); btv->tuner_type = miro_tunermap[id]; if (0 == (btread(BT848_GPIO_DATA) & 0x20)) { btv->has_radio = 1; if (!miro_fmtuner[id]) { btv->has_matchbox = 1; btv->mbox_we = (1<<6); btv->mbox_most = (1<<7); btv->mbox_clk = (1<<8); btv->mbox_data = (1<<9); btv->mbox_mask = (1<<6)|(1<<7)|(1<<8)|(1<<9); } } else { btv->has_radio = 0; } if (-1 != msp) { if (btv->type == BTTV_MIRO) btv->type = BTTV_MIROPRO; if (btv->type == BTTV_PINNACLE) btv->type = BTTV_PINNACLEPRO; } printk(KERN_INFO "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", btv->nr, id+1, btv->tuner_type, !btv->has_radio ? "no" : (btv->has_matchbox ? "matchbox" : "fmtuner"), (-1 == msp) ? "no" : "yes");}/* initialization part one -- before registering i2c bus */void __devinit bttv_init_card1(struct bttv *btv){ switch (btv->type) { case BTTV_HAUPPAUGE: case BTTV_HAUPPAUGE878: boot_msp34xx(btv,5); break; case BTTV_VOODOOTV_FM: boot_msp34xx(btv,20); break; case BTTV_HAUPPAUGEPVR: pvr_boot(btv); break; }}/* initialization part two -- after registering i2c bus */void __devinit bttv_init_card2(struct bttv *btv){ btv->tuner_type = -1; switch (btv->type) { case BTTV_MIRO: case BTTV_MIROPRO: case BTTV_PINNACLE: case BTTV_PINNACLEPRO: /* miro/pinnacle */ miro_pinnacle_gpio(btv); break; case BTTV_FLYVIDEO_98: case BTTV_MAXI: case BTTV_LIFE_FLYKIT: case BTTV_FLYVIDEO: case BTTV_TYPHOON_TVIEW: case BTTV_CHRONOS_VS2: case BTTV_FLYVIDEO_98FM: case BTTV_FLYVIDEO2000: case BTTV_FLYVIDEO98EZ: case BTTV_CONFERENCETV: case BTTV_LIFETEC_9415: flyvideo_gpio(btv); break; case BTTV_HAUPPAUGE: case BTTV_HAUPPAUGE878: case BTTV_HAUPPAUGEPVR: /* pick up some config infos from the eeprom */ bttv_readee(btv,eeprom_data,0xa0); hauppauge_eeprom(btv); break; case BTTV_AVERMEDIA98: case BTTV_AVPHONE98: bttv_readee(btv,eeprom_data,0xa0); avermedia_eeprom(btv); break; case BTTV_PXC200: init_PXC200(btv); break; case BTTV_VHX: btv->has_radio = 1; btv->has_matchbox = 1; btv->mbox_we = 0x20; btv->mbox_most = 0; btv->mbox_clk = 0x08; btv->mbox_data = 0x10; btv->mbox_mask = 0x38; break; case BTTV_MAGICTVIEW061: if (btv->cardid == 0x4002144f) { btv->has_radio=1; printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->nr); } break; } /* pll configuration */ if (!(btv->id==848 && btv->revision==0x11)) { /* defaults from card list */ if (PLL_28 == bttv_tvcards[btv->type].pll) { btv->pll.pll_ifreq=28636363; btv->pll.pll_crystal=BT848_IFORM_XT0; } if (PLL_35 == bttv_tvcards[btv->type].pll) { btv->pll.pll_ifreq=35468950; btv->pll.pll_crystal=BT848_IFORM_XT1; } /* insmod options can override */ switch (pll[btv->nr]) { case 0: /* none */ btv->pll.pll_crystal = 0; btv->pll.pll_ifreq = 0; btv->pll.pll_ofreq = 0; break; case 1: /* 28 MHz */ case 28: btv->pll.pll_ifreq = 28636363; btv->pll.pll_ofreq = 0; btv->pll.pll_crystal = BT848_IFORM_XT0; break; case 2: /* 35 MHz */ case 35: btv->pll.pll_ifreq = 35468950; btv->pll.pll_ofreq = 0; btv->pll.pll_crystal = BT848_IFORM_XT1; break; } } /* tuner configuration (from card list / autodetect / insmod option) */ if (-1 != bttv_tvcards[btv->type].tuner_type) if( -1 == btv->tuner_type) btv->tuner_type = bttv_tvcards[btv->type].tuner_type; if (-1 != tuner[btv->nr]) btv->tuner_type = tuner[btv->nr]; if (btv->tuner_type != -1) bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type); printk("bttv%d: using tuner=%d\n",btv->nr,btv->tuner_type); if (bttv_tvcards[btv->type].has_radio) btv->has_radio=1; if (bttv_tvcards[btv->type].audio_hook) btv->audio_hook=bttv_tvcards[btv->type].audio_hook; /* try to detect audio/fader chips */ if (!bttv_tvcards[btv->type].no_msp34xx && bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) { if (autoload) request_module("msp3400"); } if (!bttv_tvcards[btv->type].no_tda9875 && bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) { if (autoload) request_module("tda9875"); } if (bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) { if (autoload) request_module("tda7432"); } if (bttv_tvcards[btv->type].needs_tvaudio) { if (autoload) request_module("tvaudio"); } if (bttv_tvcards[btv->type].tuner != -1) { if (autoload) request_module("tuner"); }}/* ----------------------------------------------------------------------- *//* some hauppauge specific stuff */static struct HAUPPAUGE_TUNER { int id; char *name;} hauppauge_tuner[] __devinitdata = { { TUNER_ABSENT, "" }, { TUNER_ABSENT, "External" }, { TUNER_ABSENT, "Unspecified" }, { TUNER_PHILIPS_PAL, "Philips FI1216" }, { TUNER_PHILIPS_SECAM, "Philips FI1216MF" }, { TUNER_PHILIPS_NTSC, "Philips FI1236" }, { TUNER_PHILIPS_PAL_I, "Philips FI1246" }, { TUNER_PHILIPS_PAL_DK,"Philips FI1256" }, { TUNER_PHILIPS_PAL, "Philips FI1216 MK2" }, { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" }, { TUNER_PHILIPS_NTSC, "Philips FI1236 MK2" }, { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" }, { TUNER_PHILIPS_PAL_DK,"Philips FI1256 MK2" }, { TUNER_TEMIC_NTSC, "Temic 4032FY5" }, { TUNER_TEMIC_PAL, "Temic 4002FH5" }, { TUNER_TEMIC_PAL_I, "Temic 4062FY5" }, { TUNER_PHILIPS_PAL, "Philips FR1216 MK2" }, { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" }, { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" }, { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" }, { TUNER_PHILIPS_PAL_DK,"Philips FR1256 MK2" }, { TUNER_PHILIPS_PAL, "Philips FM1216" }, { TUNER_PHILIPS_SECAM, "Philips FM1216MF" }, { TUNER_PHILIPS_NTSC, "Philips FM1236" }, { TUNER_PHILIPS_PAL_I, "Philips FM1246" }, { TUNER_PHILIPS_PAL_DK,"Philips FM1256" }, { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" }, { TUNER_ABSENT, "Samsung TCPN9082D" }, { TUNER_ABSENT, "Samsung TCPM9092P" }, { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" }, { TUNER_ABSENT, "Samsung TCPN9085D" }, { TUNER_ABSENT, "Samsung TCPB9085P" }, { TUNER_ABSENT, "Samsung TCPL9091P" }, { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, { TUNER_ABSENT, "Philips TD1536" }, { TUNER_ABSENT, "Philips TD1536D" }, { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ { TUNER_ABSENT, "Philips FI1256MP" }, { TUNER_ABSENT, "Samsung TCPQ9091P" }, { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" }, { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" }, { TUNER_TEMIC_4046FM5, "Temic 4046FM5" }, { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" }, { TUNER_ABSENT, "Philips TD1536D_FH_44"}, { TUNER_LG_NTSC_FM, "LG TP18NSR01F"}, { TUNER_LG_PAL_FM, "LG TP18PSB01D"}, { TUNER_LG_PAL, "LG TP18PSB11D"}, { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"}, { TUNER_LG_PAL_I, "LG TAPC-I701D"}};static void __devinit hauppauge_eeprom(struct bttv *btv){ int blk2,tuner,radio,model; if (eeprom_data[0] != 0x84 || eeprom_data[2] != 0) printk(KERN_WARNING "bttv%d: Hauppauge eeprom: invalid\n", btv->nr); /* Block 2 starts after len+3 bytes header */ blk2 = eeprom_data[1] + 3; /* decode + use some config infos */ model = eeprom_data[12] << 8 | eeprom_data[11]; tuner = eeprom_data[9]; radio = eeprom_data[blk2-1] & 0x01; if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) btv->tuner_type = hauppauge_tuner[tuner].id; if (radio) btv->has_radio = 1; if (bttv_verbose) printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, " "tuner=%s (%d), radio=%s\n", btv->nr, model, hauppauge_tuner[tuner].name, btv->tuner_type, radio ? "yes" : "no");}/* ----------------------------------------------------------------------- *//* * minimal bootstrap for the WinTV/PVR -- upload altera firmware. * * The hcwamc.rbf firmware file is on the Hauppauge driver CD. Have * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be * unpacked with unzip). */static char *firm_altera = "/usr/lib/video4linux/hcwamc.rbf";MODULE_PARM(firm_altera,"s");MODULE_PARM_DESC(firm_altera,"WinTV/PVR firmware " "(driver CD => unzip pvr45xxx.exe => hcwamc.rbf)");/* drivers/sound/sound_firmware.c => soundcore.o */extern int mod_firmware_load(const char *fn, char **fp);#define PVR_GPIO_DELAY 10#define BTTV_ALT_DATA 0x000001#define BTTV_ALT_DCLK 0x100000#define BTTV_ALT_NCONFIG 0x800000static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen){ u32 n; u8 bits; int i; btwrite(BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG, BT848_GPIO_OUT_EN); btwrite(0,BT848_GPIO_DATA); udelay(PVR_GPIO_DELAY); btwrite(BTTV_ALT_NCONFIG,BT848_GPIO_DATA); udelay(PVR_GPIO_DELAY); for (n = 0; n < microlen; n++) { bits = micro[n]; for ( i = 0 ; i < 8 ; i++ ) { btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA); if (bits & 0x01) btor(BTTV_ALT_DATA,BT848_GPIO_DATA); else btand(~BTTV_ALT_DATA,BT848_GPIO_DATA); btor(BTTV_ALT_DCLK,BT848_GPIO_DATA); bits >>= 1; } } btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA); udelay(PVR_GPIO_DELAY); /* begin Altera init loop (Not necessary,but doesn't hurt) */ for (i = 0 ; i < 30 ; i++) { btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA); btor(BTTV_ALT_DCLK,BT848_GPIO_DATA); } btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA); return 0;}int __devinit pvr_boot(struct bttv *btv){ u32 microlen; u8 *micro; int result; microlen = mod_firmware_load(firm_altera, (char**) µ); if (!microlen) return -1; printk(KERN_INFO "bttv%d: uploading altera firmware [%s] ...\n", btv->nr, firm_altera); result = pvr_altera_load(btv, micro, microlen); printk(KERN_INFO "bttv%d: ... upload %s\n", btv->nr, (result < 0) ? "failed" : "ok"); vfree(micro); return result;}/* ----------------------------------------------------------------------- *//* AVermedia specific stuff, from bktr_card.c */int tuner_0_table[] = { TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL};#if 0int tuner_0_fm_table[] = { PHILIPS_FR1236_NTSC, PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL, PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};#endifint tuner_1_table[] = { TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, //TUNER_TEMIC_SECAM TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};static void __devinit avermedia_eeprom(struct bttv *btv){ int tuner_make,tuner_tv_fm,tuner_format,tuner=0,remote; tuner_make = (eeprom_data[0x41] & 0x7); tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; remote = (eeprom_data[0x42] & 0x01); if (tuner_make == 0 || tuner_make == 2) if(tuner_format <=9) tuner = tuner_0_table[tuner_format]; if (tuner_make == 1) if(tuner_format <=9) tuner = tuner_1_table[tuner_format]; printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=", btv->nr,eeprom_data[0x41],eeprom_data[0x42]); if(tuner) { btv->tuner_type=tuner; printk("%d",tuner); } else printk("Unknown type"); printk(" radio:%s remote control:%s\n", tuner_tv_fm?"yes":"no", remote?"yes":"no");}/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */void bttv_tda9880_setnorm(struct bttv *btv, int norm){ // fix up our card entry if(norm==VIDEO_MODE_NTSC) { bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff; bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff; dprintk("bttv_tda9880_setnorm to NTSC\n"); } else { bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff; bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff; dprintk("bttv_tda9880_setnorm to PAL\n"); } // set GPIO according btaor(bttv_tvcards[btv->type].audiomux[btv->audio], ~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA);}/* * reset/enable the MSP on some Hauppauge cards * Thanks to Ky鰏ti M鋖kki (kmalkki@cc.hut.fi)! * * Hauppauge: pin 5 * Voodoo: pin 20 */static void __devinit boot_msp34xx(struct bttv *btv, int pin){ int mask = (1 << pin); btaor(mask, ~mask, BT848_GPIO_OUT_EN); btaor(0, ~mask, BT848_GPIO_DATA); udelay(2500);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -