📄 bttv-cards.c
字号:
if (bttv_verbose) 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");#if 0 if (btv->has_matchbox) { if (bttv_verbose) printk(KERN_INFO "Initializing TEA5757...\n"); init_tea5757(btv); }#endif } if (btv->type == BTTV_FLYVIDEO_98 || btv->type == BTTV_FLYVIDEO || btv->type == BTTV_TYPHOON_TVIEW || btv->type == BTTV_CHRONOS_VS2 || btv->type == BTTV_FLYVIDEO_98FM || btv->type == BTTV_FLYVIDEO2000 || btv->type == BTTV_FLYVIDEO98EZ) flyvideo_gpio(btv); if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878) { /* pick up some config infos from the eeprom */ bttv_readee(btv,eeprom_data,0xa0); hauppauge_eeprom(btv); } if (btv->type == BTTV_AVERMEDIA98 || btv->type == BTTV_AVPHONE98) { bttv_readee(btv,eeprom_data,0xa0); avermedia_eeprom(btv); } if (btv->type == BTTV_PXC200) init_PXC200(btv); if (btv->type == 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; } if (btv->type == BTTV_LIFETEC_9415) { if (btread(BT848_GPIO_DATA) & 0x4000) printk("bttv%d: lifetec: tv mono/fm stereo card\n", btv->nr); else printk("bttv%d: lifetec: stereo(TDA9821) card\n",btv->nr); } if (btv->type == BTTV_MAGICTVIEW061) { if(btv->cardid == 0x4002144f) { btv->has_radio=1; printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->nr); } } /* 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 / insmod option) */ if (-1 != bttv_tvcards[btv->type].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); if (bttv_tvcards[btv->type].has_radio) btv->has_radio=1; /* 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");}/* ----------------------------------------------------------------------- *//* 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); btaor(mask, ~mask, BT848_GPIO_DATA); if (bttv_gpio) bttv_gpio_tracking(btv,"msp34xx"); if (bttv_verbose) printk(KERN_INFO "bttv%d: Hauppauge/Voodoo msp34xx: reset line " "init [%d]\n", btv->nr, pin);}/* ----------------------------------------------------------------------- *//* Imagenation L-Model PXC200 Framegrabber *//* This is basically the same procedure as * used by Alessandro Rubini in his pxc200 * driver, but using BTTV functions */static void __devinit init_PXC200(struct bttv *btv){ static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00 }; int i,tmp; /* Initialise GPIO-connevted stuff */ btwrite(1<<13,BT848_GPIO_OUT_EN); /* Reset pin only */ btwrite(0,BT848_GPIO_DATA); udelay(3); btwrite(1<<13,BT848_GPIO_DATA); /* GPIO inputs are pulled up, so no need to drive * reset pin any longer */ btwrite(0,BT848_GPIO_OUT_EN); if (bttv_gpio) bttv_gpio_tracking(btv,"pxc200"); /* we could/should try and reset/control the AD pots? but right now we simply turned off the crushing. Without this the AGC drifts drifts remember the EN is reverse logic --> setting BT848_ADC_AGC_EN disable the AGC tboult@eecs.lehigh.edu */ btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC); /* Initialise MAX517 DAC */ printk(KERN_INFO "Setting DAC reference voltage level ...\n"); bttv_I2CWrite(btv,0x5E,0,0x80,1); /* Initialise 12C508 PIC */ /* The I2CWrite and I2CRead commmands are actually to the * same chips - but the R/W bit is included in the address * argument so the numbers are different */ printk(KERN_INFO "Initialising 12C508 PIC chip ...\n"); for (i = 0; i < sizeof(vals)/sizeof(int); i++) { tmp=bttv_I2CWrite(btv,0x1E,vals[i],0,1); printk(KERN_INFO "I2C Write(0x08) = %i\nI2C Read () = %x\n\n", tmp,bttv_I2CRead(btv,0x1F,NULL)); } printk(KERN_INFO "PXC200 Initialised.\n");}/* ----------------------------------------------------------------------- *//* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports *//* * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu> * This code is placed under the terms of the GNU General Public License * * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00 */#if 0/* bus bits on the GPIO port */#define TEA_WE 6#define TEA_DATA 9#define TEA_CLK 8#define TEA_MOST 7#endif#define BUS_LOW(bit) btand(~(bit), BT848_GPIO_DATA)#define BUS_HIGH(bit) btor((bit), BT848_GPIO_DATA)#define BUS_IN(bit) (btread(BT848_GPIO_DATA) & (bit))/* TEA5757 register bits */#define TEA_FREQ 0:14#define TEA_BUFFER 15:15#define TEA_SIGNAL_STRENGTH 16:17#define TEA_PORT1 18:18#define TEA_PORT0 19:19#define TEA_BAND 20:21#define TEA_BAND_FM 0#define TEA_BAND_MW 1#define TEA_BAND_LW 2#define TEA_BAND_SW 3#define TEA_MONO 22:22#define TEA_ALLOW_STEREO 0#define TEA_FORCE_MONO 1#define TEA_SEARCH_DIRECTION 23:23#define TEA_SEARCH_DOWN 0#define TEA_SEARCH_UP 1#define TEA_STATUS 24:24#define TEA_STATUS_TUNED 0#define TEA_STATUS_SEARCHING 1/* Low-level stuff */static int tea5757_read(struct bttv *btv){ int value = 0; long timeout; int i; /* better safe than sorry */ btaor((btv->mbox_clk | btv->mbox_we), ~btv->mbox_mask, BT848_GPIO_OUT_EN); if (bttv_gpio) bttv_gpio_tracking(btv,"tea5757 read"); BUS_LOW(btv->mbox_we); BUS_LOW(btv->mbox_clk); udelay(10); for(timeout = jiffies + 10 * HZ; BUS_IN(btv->mbox_data) && time_before(jiffies, timeout); schedule()); /* 10 s */ if (BUS_IN(btv->mbox_data)) { printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->nr); return -1; } for(timeout = jiffies + HZ/5; BUS_IN(btv->mbox_data) == 1 && time_before(jiffies, timeout); schedule()); /* 0.2 s */ dprintk("bttv%d: tea5757:",btv->nr); for(i = 0; i < 24; i++) { udelay(5);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -