⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ivtv-driver.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
}static v4l2_std_id ivtv_parse_std(struct ivtv *itv){	switch (pal[0]) {		case '6':			return V4L2_STD_PAL_60;		case 'b':		case 'B':		case 'g':		case 'G':			return V4L2_STD_PAL_BG;		case 'h':		case 'H':			return V4L2_STD_PAL_H;		case 'n':		case 'N':			if (pal[1] == 'c' || pal[1] == 'C')				return V4L2_STD_PAL_Nc;			return V4L2_STD_PAL_N;		case 'i':		case 'I':			return V4L2_STD_PAL_I;		case 'd':		case 'D':		case 'k':		case 'K':			return V4L2_STD_PAL_DK;		case 'M':		case 'm':			return V4L2_STD_PAL_M;		case '-':			break;		default:			IVTV_WARN("pal= argument not recognised\n");			return 0;	}	switch (secam[0]) {		case 'b':		case 'B':		case 'g':		case 'G':		case 'h':		case 'H':			return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;		case 'd':		case 'D':		case 'k':		case 'K':			return V4L2_STD_SECAM_DK;		case 'l':		case 'L':			if (secam[1] == 'C' || secam[1] == 'c')				return V4L2_STD_SECAM_LC;			return V4L2_STD_SECAM_L;		case '-':			break;		default:			IVTV_WARN("secam= argument not recognised\n");			return 0;	}	switch (ntsc[0]) {		case 'm':		case 'M':			return V4L2_STD_NTSC_M;		case 'j':		case 'J':			return V4L2_STD_NTSC_M_JP;		case 'k':		case 'K':			return V4L2_STD_NTSC_M_KR;		case '-':			break;		default:			IVTV_WARN("ntsc= argument not recognised\n");			return 0;	}	/* no match found */	return 0;}static void ivtv_process_options(struct ivtv *itv){	const char *chipname;	int i, j;	itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers * 1024;	itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers * 1024;	itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers * 1024;	itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;	itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers * 1024;	itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers * 1024;	itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;	itv->options.cardtype = cardtype[itv->num];	itv->options.tuner = tuner[itv->num];	itv->options.radio = radio[itv->num];	itv->options.newi2c = newi2c;	itv->std = ivtv_parse_std(itv);	itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15);	chipname = itv->has_cx23415 ? "cx23415" : "cx23416";	if (itv->options.cardtype == -1) {		IVTV_INFO("Ignore card (detected %s based chip)\n", chipname);		return;	}	if ((itv->card = ivtv_get_card(itv->options.cardtype - 1))) {		IVTV_INFO("User specified %s card (detected %s based chip)\n",				itv->card->name, chipname);	} else if (itv->options.cardtype != 0) {		IVTV_ERR("Unknown user specified type, trying to autodetect card\n");	}	if (itv->card == NULL) {		if (itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||		    itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||		    itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {			itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150);			IVTV_INFO("Autodetected Hauppauge card (%s based)\n",					chipname);		}	}	if (itv->card == NULL) {		for (i = 0; (itv->card = ivtv_get_card(i)); i++) {			if (itv->card->pci_list == NULL)				continue;			for (j = 0; itv->card->pci_list[j].device; j++) {				if (itv->dev->device !=				    itv->card->pci_list[j].device)					continue;				if (itv->dev->subsystem_vendor !=				    itv->card->pci_list[j].subsystem_vendor)					continue;				if (itv->dev->subsystem_device !=				    itv->card->pci_list[j].subsystem_device)					continue;				IVTV_INFO("Autodetected %s card (%s based)\n",						itv->card->name, chipname);				goto done;			}		}	}done:	if (itv->card == NULL) {		itv->card = ivtv_get_card(IVTV_CARD_PVR_150);		IVTV_ERR("Unknown card: vendor/device: %04x/%04x\n",		     itv->dev->vendor, itv->dev->device);		IVTV_ERR("              subsystem vendor/device: %04x/%04x\n",		     itv->dev->subsystem_vendor, itv->dev->subsystem_device);		IVTV_ERR("              %s based\n", chipname);		IVTV_ERR("Defaulting to %s card\n", itv->card->name);		IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");		IVTV_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");		IVTV_ERR("Prefix your subject line with [UNKNOWN CARD].\n");	}	itv->v4l2_cap = itv->card->v4l2_capabilities;	itv->card_name = itv->card->name;}/* Precondition: the ivtv structure has been memset to 0. Only   the dev and num fields have been filled in.   No assumptions on the card type may be made here (see ivtv_init_struct2   for that). */static int __devinit ivtv_init_struct1(struct ivtv *itv){	itv->base_addr = pci_resource_start(itv->dev, 0);	itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */	itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */	mutex_init(&itv->serialize_lock);	mutex_init(&itv->i2c_bus_lock);	mutex_init(&itv->udma.lock);	spin_lock_init(&itv->lock);	spin_lock_init(&itv->dma_reg_lock);	itv->irq_work_queues = create_workqueue(itv->name);	if (itv->irq_work_queues == NULL) {		IVTV_ERR("Could not create ivtv workqueue\n");		return -1;	}	INIT_WORK(&itv->irq_work_queue, ivtv_irq_work_handler);	/* start counting open_id at 1 */	itv->open_id = 1;	/* Initial settings */	cx2341x_fill_defaults(&itv->params);	itv->params.port = CX2341X_PORT_MEMORY;	itv->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;	init_waitqueue_head(&itv->eos_waitq);	init_waitqueue_head(&itv->event_waitq);	init_waitqueue_head(&itv->vsync_waitq);	init_waitqueue_head(&itv->dma_waitq);	init_timer(&itv->dma_timer);	itv->dma_timer.function = ivtv_unfinished_dma;	itv->dma_timer.data = (unsigned long)itv;	itv->cur_dma_stream = -1;	itv->cur_pio_stream = -1;	itv->audio_stereo_mode = AUDIO_STEREO;	itv->audio_bilingual_mode = AUDIO_MONO_LEFT;	/* Ctrls */	itv->speed = 1000;	/* VBI */	itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;	itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;	/* Init the sg table for osd/yuv output */	sg_init_table(itv->udma.SGlist, IVTV_DMA_SG_OSD_ENT);	/* OSD */	itv->osd_global_alpha_state = 1;	itv->osd_global_alpha = 255;	/* YUV */	atomic_set(&itv->yuv_info.next_dma_frame, -1);	itv->yuv_info.lace_mode = ivtv_yuv_mode;	itv->yuv_info.lace_threshold = ivtv_yuv_threshold;	return 0;}/* Second initialization part. Here the card type has been   autodetected. */static void __devinit ivtv_init_struct2(struct ivtv *itv){	int i;	for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++)		if (itv->card->video_inputs[i].video_type == 0)			break;	itv->nof_inputs = i;	for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++)		if (itv->card->audio_inputs[i].audio_type == 0)			break;	itv->nof_audio_inputs = i;	if (itv->card->hw_all & IVTV_HW_CX25840) {		itv->vbi.sliced_size = 288;  /* multiple of 16, real size = 284 */	} else {		itv->vbi.sliced_size = 64;   /* multiple of 16, real size = 52 */	}	/* Find tuner input */	for (i = 0; i < itv->nof_inputs; i++) {		if (itv->card->video_inputs[i].video_type ==				IVTV_CARD_INPUT_VID_TUNER)			break;	}	if (i == itv->nof_inputs)		i = 0;	itv->active_input = i;	itv->audio_input = itv->card->video_inputs[i].audio_index;	if (itv->card->hw_all & IVTV_HW_CX25840)		itv->video_dec_func = ivtv_cx25840;	else if (itv->card->hw_all & IVTV_HW_SAA717X)		itv->video_dec_func = ivtv_saa717x;	else		itv->video_dec_func = ivtv_saa7115;}static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,			  const struct pci_device_id *pci_id){	u16 cmd;	u8 card_rev;	unsigned char pci_latency;	IVTV_DEBUG_INFO("Enabling pci device\n");	if (pci_enable_device(dev)) {		IVTV_ERR("Can't enable device %d!\n", itv->num);		return -EIO;	}	if (pci_set_dma_mask(dev, 0xffffffff)) {		IVTV_ERR("No suitable DMA available on card %d.\n", itv->num);		return -EIO;	}	if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) {		IVTV_ERR("Cannot request encoder memory region on card %d.\n", itv->num);		return -EIO;	}	if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET,				IVTV_REG_SIZE, "ivtv registers")) {		IVTV_ERR("Cannot request register memory region on card %d.\n", itv->num);		release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);		return -EIO;	}	if (itv->has_cx23415 &&	    !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,				IVTV_DECODER_SIZE, "ivtv decoder")) {		IVTV_ERR("Cannot request decoder memory region on card %d.\n", itv->num);		release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);		release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);		return -EIO;	}	/* Check for bus mastering */	pci_read_config_word(dev, PCI_COMMAND, &cmd);	if (!(cmd & PCI_COMMAND_MASTER)) {		IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n");		pci_set_master(dev);		pci_read_config_word(dev, PCI_COMMAND, &cmd);		if (!(cmd & PCI_COMMAND_MASTER)) {			IVTV_ERR("Bus Mastering is not enabled\n");			return -ENXIO;		}	}	IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");	pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev);	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);	if (pci_latency < 64 && ivtv_pci_latency) {		IVTV_INFO("Unreasonably low latency timer, "			       "setting to 64 (was %d)\n", pci_latency);		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);		pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);	}	/* This config space value relates to DMA latencies. The	   default value 0x8080 is too low however and will lead	   to DMA errors. 0xffff is the max value which solves	   these problems. */	pci_write_config_dword(dev, 0x40, 0xffff);	IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "		   "irq: %d, latency: %d, memory: 0x%lx\n",		   itv->dev->device, card_rev, dev->bus->number,		   PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),		   itv->dev->irq, pci_latency, (unsigned long)itv->base_addr);	return 0;}static void ivtv_request_module(struct ivtv *itv, const char *name){	if (request_module(name) != 0) {		IVTV_ERR("Failed to load module %s\n", name);	} else {		IVTV_DEBUG_INFO("Loaded module %s\n", name);	}}static void ivtv_load_and_init_modules(struct ivtv *itv){	u32 hw = itv->card->hw_all;	int i;	/* load modules */#ifndef CONFIG_VIDEO_TUNER	if (hw & IVTV_HW_TUNER) {		if (itv->options.tuner == TUNER_XCEIVE_XC3028) {			IVTV_INFO("Xceive tuner not yet supported, only composite and S-Video inputs will be available\n");			itv->tunerid = 1;		}		else {			ivtv_request_module(itv, "tuner");		}	}#endif#ifndef CONFIG_VIDEO_CX25840	if (hw & IVTV_HW_CX25840)		ivtv_request_module(itv, "cx25840");#endif#ifndef CONFIG_VIDEO_SAA711X	if (hw & IVTV_HW_SAA711X)		ivtv_request_module(itv, "saa7115");#endif#ifndef CONFIG_VIDEO_SAA7127	if (hw & IVTV_HW_SAA7127)		ivtv_request_module(itv, "saa7127");#endif	if (hw & IVTV_HW_SAA717X)		ivtv_request_module(itv, "saa717x");#ifndef CONFIG_VIDEO_UPD64031A	if (hw & IVTV_HW_UPD64031A)		ivtv_request_module(itv, "upd64031a");#endif#ifndef CONFIG_VIDEO_UPD64083	if (hw & IVTV_HW_UPD6408X)		ivtv_request_module(itv, "upd64083");#endif#ifndef CONFIG_VIDEO_MSP3400	if (hw & IVTV_HW_MSP34XX)		ivtv_request_module(itv, "msp3400");#endif#ifndef CONFIG_VIDEO_VP27SMPX	if (hw & IVTV_HW_VP27SMPX)		ivtv_request_module(itv, "vp27smpx");#endif	if (hw & IVTV_HW_TVAUDIO)		ivtv_request_module(itv, "tvaudio");#ifndef CONFIG_VIDEO_WM8775	if (hw & IVTV_HW_WM8775)		ivtv_request_module(itv, "wm8775");#endif#ifndef CONFIG_VIDEO_WM8739	if (hw & IVTV_HW_WM8739)		ivtv_request_module(itv, "wm8739");#endif#ifndef CONFIG_VIDEO_CS53L32A	if (hw & IVTV_HW_CS53L32A)		ivtv_request_module(itv, "cs53l32a");#endif	/* check which i2c devices are actually found */	for (i = 0; i < 32; i++) {		u32 device = 1 << i;		if (!(device & hw))			continue;		if (device == IVTV_HW_GPIO) {			/* GPIO is always available */			itv->hw_flags |= IVTV_HW_GPIO;			continue;		}		if (ivtv_i2c_hw_addr(itv, device) > 0)			itv->hw_flags |= device;	}	hw = itv->hw_flags;	if (itv->card->type == IVTV_CARD_CX23416GYC) {		/* Several variations of this card exist, detect which card		   type should be used. */		if ((hw & (IVTV_HW_UPD64031A | IVTV_HW_UPD6408X)) == 0)			itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGRYCS);		else if ((hw & IVTV_HW_UPD64031A) == 0)			itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGR);	}	else if (itv->card->type == IVTV_CARD_GV_MVPRX ||		 itv->card->type == IVTV_CARD_GV_MVPRX2E) {		struct v4l2_crystal_freq crystal_freq;		/* The crystal frequency of GVMVPRX is 24.576MHz */		crystal_freq.freq = SAA7115_FREQ_24_576_MHZ;		crystal_freq.flags = SAA7115_FREQ_FL_UCGC;		itv->video_dec_func(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);	}	if (hw & IVTV_HW_CX25840) {		itv->vbi.raw_decoder_line_size = 1444;		itv->vbi.raw_decoder_sav_odd_field = 0x20;		itv->vbi.raw_decoder_sav_even_field = 0x60;		itv->vbi.sliced_decoder_line_size = 272;		itv->vbi.sliced_decoder_sav_odd_field = 0xB0;		itv->vbi.sliced_decoder_sav_even_field = 0xF0;	}	if (hw & IVTV_HW_SAA711X) {		struct v4l2_chip_ident v = { V4L2_CHIP_MATCH_I2C_DRIVER, I2C_DRIVERID_SAA711X };		/* determine the exact saa711x model */		itv->hw_flags &= ~IVTV_HW_SAA711X;		ivtv_saa7115(itv, VIDIOC_G_CHIP_IDENT, &v);		if (v.ident == V4L2_IDENT_SAA7114) {			itv->hw_flags |= IVTV_HW_SAA7114;			/* VBI is not yet supported by the saa7114 driver. */			itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE);		}		else {			itv->hw_flags |= IVTV_HW_SAA7115;		}		itv->vbi.raw_decoder_line_size = 1443;		itv->vbi.raw_decoder_sav_odd_field = 0x25;		itv->vbi.raw_decoder_sav_even_field = 0x62;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -