📄 bttv-cards.c
字号:
static struct HAUPPAUGE_TUNER { int id; char *name;} hauppauge_tuner[] __devinitdata = { { TUNER_ABSENT, "" }, { TUNER_ABSENT, "External" }, { TUNER_ABSENT, "Unspecified" }, { TUNER_ABSENT, "Philips FI1216" }, { TUNER_PHILIPS_SECAM, "Philips FI1216MF" }, { TUNER_PHILIPS_NTSC, "Philips FI1236" }, { TUNER_ABSENT, "Philips FI1246" }, { TUNER_ABSENT, "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_ABSENT, "Philips FI1256 MK2" }, { TUNER_ABSENT, "Temic 4032FY5" }, { TUNER_TEMIC_PAL, "Temic 4002FH5" }, { TUNER_TEMIC_PAL_I, "Temic 4062FY5" }, { TUNER_ABSENT, "Philips FR1216 MK2" }, { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" }, { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" }, { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" }, { TUNER_ABSENT, "Philips FR1256 MK2" }, { TUNER_PHILIPS_PAL, "Philips FM1216" }, { TUNER_ABSENT, "Philips FM1216MF" }, { TUNER_PHILIPS_NTSC, "Philips FM1236" }, { TUNER_PHILIPS_PAL_I, "Philips FM1246" }, { TUNER_ABSENT, "Philips FM1256" }, { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" }, { TUNER_ABSENT, "Samsung TCPN9082D" }, { TUNER_ABSENT, "Samsung TCPM9092P" }, { TUNER_TEMIC_PAL, "Temic 4006FH5" }, { TUNER_ABSENT, "Samsung TCPN9085D" }, { TUNER_ABSENT, "Samsung TCPB9085P" }, { TUNER_ABSENT, "Samsung TCPL9091P" }, { TUNER_ABSENT, "Temic 4039FR5" }, { TUNER_ABSENT, "Philips FQ1216 ME" }, { TUNER_TEMIC_PAL_I, "Temic 4066FY5" }, { TUNER_ABSENT, "Philips TD1536" }, { TUNER_ABSENT, "Philips TD1536D" }, { TUNER_ABSENT, "Philips FMR1236" }, { TUNER_ABSENT, "Philips FI1256MP" }, { TUNER_ABSENT, "Samsung TCPQ9091P" }, { TUNER_ABSENT, "Temic 4006FN5" }, { TUNER_ABSENT, "Temic 4009FR5" }, { TUNER_ABSENT, "Temic 4046FM5" },};static void __devinit hauppauge_eeprom(struct bttv *btv){ if (eeprom_data[9] < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { btv->tuner_type = hauppauge_tuner[eeprom_data[9]].id; if (bttv_verbose) printk("bttv%d: Hauppauge eeprom: model=%d, tuner=%s (%d)\n",btv->nr, eeprom_data[12] << 8 | eeprom_data[11], hauppauge_tuner[eeprom_data[9]].name,btv->tuner_type); }}void __devinit bttv_hauppauge_boot_msp34xx(struct bttv *btv){ /* reset/enable the MSP on some Hauppauge cards */ /* Thanks to Ky鰏ti M鋖kki (kmalkki@cc.hut.fi)! */ btaor(32, ~32, BT848_GPIO_OUT_EN); btaor(0, ~32, BT848_GPIO_DATA); udelay(2500); btaor(32, ~32, BT848_GPIO_DATA); if (bttv_gpio) bttv_gpio_tracking(btv,"msp34xx"); if (bttv_verbose) printk("bttv%d: Hauppauge msp34xx: reset line init\n",btv->nr);}/* ----------------------------------------------------------------------- *//* 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 const int vals[] = { 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 *//* bus bits on the GPIO port */#define TEA_WE 6#define TEA_DATA 9#define TEA_CLK 8#define TEA_MOST 7#define BUS_LOW(bit) btand(~(1<<TEA_##bit), BT848_GPIO_DATA)#define BUS_HIGH(bit) btor((1<<TEA_##bit), BT848_GPIO_DATA)#define BUS_IN(bit) ((btread(BT848_GPIO_DATA) >> TEA_##bit) & 1)/* 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 tea_read(struct bttv *btv){ int value = 0; long timeout; int i; /* better safe than sorry */ btaor((1<<TEA_CLK) | (1<<TEA_WE), ~((1<<TEA_CLK) | (1<<TEA_DATA) | (1<<TEA_WE) | (1<<TEA_MOST)), BT848_GPIO_OUT_EN); if (bttv_gpio) bttv_gpio_tracking(btv,"miro tea read"); BUS_LOW(WE); BUS_LOW(CLK); udelay(10); for(timeout = jiffies + 10 * HZ; BUS_IN(DATA) == 1 && time_before(jiffies, timeout); schedule()); /* 10 s */ if (BUS_IN(DATA) == 1) { printk("tea5757: read timeout\n"); return -1; } for(timeout = jiffies + HZ/5; BUS_IN(MOST) == 1 && time_before(jiffies, timeout); schedule()); /* 0.2 s */ if (bttv_debug) printk("tea5757:"); for(i = 0; i < 24; i++) { udelay(10); BUS_HIGH(CLK); udelay(10); if (bttv_debug) printk("%c", (BUS_IN(MOST) == 0)?'T':'-'); BUS_LOW(CLK); value <<= 1; value |= (BUS_IN(DATA) == 0)?0:1; /* MSB first */ if (bttv_debug) printk("%c", (BUS_IN(MOST) == 0)?'S':'M'); } if (bttv_debug) printk("\ntea5757: read 0x%X\n", value); return value;}static int tea_write(struct bttv *btv, int value){ int i; int reg = value; btaor((1<<TEA_CLK) | (1<<TEA_WE) | (1<<TEA_DATA), ~((1<<TEA_CLK) | (1<<TEA_DATA) | (1<<TEA_WE) | (1<<TEA_MOST)), BT848_GPIO_OUT_EN); if (bttv_gpio) bttv_gpio_tracking(btv,"miro tea write"); if (bttv_debug) printk("tea5757: write 0x%X\n", value); BUS_LOW(CLK); BUS_HIGH(WE); for(i = 0; i < 25; i++) { if (reg & 0x1000000) BUS_HIGH(DATA); else BUS_LOW(DATA); reg <<= 1; BUS_HIGH(CLK); udelay(10); BUS_LOW(CLK); udelay(10); } BUS_LOW(WE); /* unmute !!! */ return 0;}void tea5757_set_freq(struct bttv *btv, unsigned short freq){ tea_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */ if (bttv_debug) tea_read(btv);}#if 0void init_tea5757(struct bttv *btv){ BUS_LOW(CLK); BUS_LOW(WE); /* just to be on the safe side... */ /* software CLK (unused) */ btaor(0, BT848_GPIO_DMA_CTL_GPCLKMODE, BT848_GPIO_DMA_CTL); /* normal mode for GPIO */ btaor(0, BT848_GPIO_DMA_CTL_GPIOMODE, BT848_GPIO_DMA_CTL);}#endif/* ----------------------------------------------------------------------- *//* winview */void winview_audio(struct bttv *btv, struct video_audio *v, int set){ /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */ int bits_out, loops, vol, data; if (!set) { v->mode |= VIDEO_AUDIO_VOLUME; return; } /* 32 levels logarithmic */ vol = 32 - ((v->volume>>11)); /* units */ bits_out = (PT2254_DBS_IN_2>>(vol%5)); /* tens */ bits_out |= (PT2254_DBS_IN_10>>(vol/5)); bits_out |= PT2254_L_CHANEL | PT2254_R_CHANEL; data = btread(BT848_GPIO_DATA); data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA| WINVIEW_PT2254_STROBE); for (loops = 17; loops >= 0 ; loops--) { if (bits_out & (1<<loops)) data |= WINVIEW_PT2254_DATA; else data &= ~WINVIEW_PT2254_DATA; btwrite(data, BT848_GPIO_DATA); udelay(5); data |= WINVIEW_PT2254_CLK; btwrite(data, BT848_GPIO_DATA); udelay(5); data &= ~WINVIEW_PT2254_CLK; btwrite(data, BT848_GPIO_DATA); } data |= WINVIEW_PT2254_STROBE; data &= ~WINVIEW_PT2254_DATA; btwrite(data, BT848_GPIO_DATA); udelay(10); data &= ~WINVIEW_PT2254_STROBE; btwrite(data, BT848_GPIO_DATA);}/* ----------------------------------------------------------------------- *//* mono/stereo control for various cards (which don't use i2c chips but *//* connect something to the GPIO pins */static voidgvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set){ unsigned int con = 0; if (set) { btor(0x100, BT848_GPIO_OUT_EN); if (v->mode & VIDEO_SOUND_LANG1) con = 0x000; if (v->mode & VIDEO_SOUND_LANG2) con = 0x300; if (v->mode & VIDEO_SOUND_STEREO) con = 0x200;// if (v->mode & VIDEO_SOUND_MONO)// con = 0x100; btaor(con, ~0x300, BT848_GPIO_DATA); } else { v->mode = VIDEO_SOUND_STEREO | VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; }}/* * Mario Medina Nussbaum <medisoft@alohabbs.org.mx> * I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo, * 0xdde enables mono and 0xccd enables sap * * Petr Vandrovec <VANDROVE@vc.cvut.cz> * P.S.: At least mask in line above is wrong - GPIO pins 3,2 select * input/output sound connection, so both must be set for output mode. * */static voidavermedia_tvphone_audio(struct bttv *btv, struct video_audio *v, int set){#if 0 /* needs more testing -- might be we need two versions for PAL/NTSC */ int val = 0; if (set) { if (v->mode & VIDEO_SOUND_LANG1) /* SAP */ val = 0xce; if (v->mode & VIDEO_SOUND_STEREO) val = 0xcd; if (val) { btaor(val, 0xff, BT848_GPIO_OUT_EN); btaor(val, 0xff, BT848_GPIO_DATA); if (bttv_gpio) bttv_gpio_tracking(btv,"avermedia"); } } else { v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | VIDEO_SOUND_LANG1; return; }#endif}static voidterratv_audio(struct bttv *btv, struct video_audio *v, int set){ unsigned int con = 0; if (set) { btor(0x180000, BT848_GPIO_OUT_EN); if (v->mode & VIDEO_SOUND_LANG2) con = 0x080000; if (v->mode & VIDEO_SOUND_STEREO) con = 0x180000; btaor(con, ~0x180000, BT848_GPIO_DATA); if (bttv_gpio) bttv_gpio_tracking(btv,"terratv"); } else { v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; }}/* ----------------------------------------------------------------------- *//* motherboard chipset specific stuff */static struct { char *name; unsigned short vendor; unsigned short device;} needs_etbf[] __devinitdata = { { "Intel 82437FX [Triton PIIX]", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437 }, { "VIA VT82C597 [Apollo VP3]", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0 }, { NULL, 0, 0 }};void __devinit bttv_check_chipset(void){ int i; struct pci_dev *dev = NULL; if(pci_pci_problems & PCIPCI_FAIL) printk(KERN_WARNING "BT848 and your chipset may not work together.\n"); while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, dev))) { unsigned char b; pci_read_config_byte(dev, 0x53, &b); if (bttv_debug) printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, " "bufcon=0x%02x\n",b); } if(pci_pci_problems & (PCIPCI_TRITON|PCIPCI_VIAETBF)) { printk(KERN_INFO "bttv: Host bridge needs ETBF enabled.\n"); triton1=1; }}int __devinit bttv_handle_chipset(struct bttv *btv){ unsigned char command; if (!triton1) return 0; if (bttv_verbose) printk("bttv%d: enabling 430FX/VP3 compatibilty\n",btv->nr); if (btv->id < 878) { /* bt848 (mis)uses a bit in the irq mask */ btv->triton1 = BT848_INT_ETBF; } else { /* bt878 has a bit in the pci config space for it */ pci_read_config_byte(btv->dev, BT878_DEVCTRL, &command); command |= BT878_EN_TBFX; pci_write_config_byte(btv->dev, BT878_DEVCTRL, command); pci_read_config_byte(btv->dev, BT878_DEVCTRL, &command); if (!(command&BT878_EN_TBFX)) { printk("bttv: 430FX compatibility could not be enabled\n"); return -1; } } return 0;}#ifndef MODULEstatic int __init bttv_card_setup(char *str){ int i,number,res = 2; for (i = 0; res == 2 && i < BTTV_MAX; i++) { res = get_option(&str,&number); if (res) card[i] = number; } return 1;}__setup("bttv_card=", bttv_card_setup);#endif /* not MODULE *//* * Local variables: * c-basic-offset: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -