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

📄 sis_main.c

📁 linux下的VIDEO接口驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	sisfb_heap.max_freesize = poh->size;	sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;	sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;	sisfb_heap.oh_used.size = SENTINEL;	return 0;}static SIS_OH *sisfb_poh_new_node(void){	int i;	unsigned long cOhs;	SIS_OHALLOC *poha;	SIS_OH *poh;	if (sisfb_heap.poh_freelist == NULL) {		poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);		poha->poha_next = sisfb_heap.poha_chain;		sisfb_heap.poha_chain = poha;		cOhs =		    (OH_ALLOC_SIZE -		     sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;		poh = &poha->aoh[0];		for (i = cOhs - 1; i != 0; i--) {			poh->poh_next = poh + 1;			poh = poh + 1;		}		poh->poh_next = NULL;		sisfb_heap.poh_freelist = &poha->aoh[0];	}	poh = sisfb_heap.poh_freelist;	sisfb_heap.poh_freelist = poh->poh_next;	return (poh);}static SIS_OH *sisfb_poh_allocate(unsigned long size){	SIS_OH *pohThis;	SIS_OH *pohRoot;	int bAllocated = 0;	if (size > sisfb_heap.max_freesize) {		DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",			(unsigned int) size / 1024);		return (NULL);	}	pohThis = sisfb_heap.oh_free.poh_next;	while (pohThis != &sisfb_heap.oh_free) {		if (size <= pohThis->size) {			bAllocated = 1;			break;		}		pohThis = pohThis->poh_next;	}	if (!bAllocated) {		DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",			(unsigned int) size / 1024);		return (NULL);	}	if (size == pohThis->size) {		pohRoot = pohThis;		sisfb_delete_node(pohThis);	} else {		pohRoot = sisfb_poh_new_node();		if (pohRoot == NULL) {			return (NULL);		}		pohRoot->offset = pohThis->offset;		pohRoot->size = size;		pohThis->offset += size;		pohThis->size -= size;	}	sisfb_heap.max_freesize -= size;	pohThis = &sisfb_heap.oh_used;	sisfb_insert_node(pohThis, pohRoot);	return (pohRoot);}static void sisfb_delete_node(SIS_OH *poh){	SIS_OH *poh_prev;	SIS_OH *poh_next;	poh_prev = poh->poh_prev;	poh_next = poh->poh_next;	poh_prev->poh_next = poh_next;	poh_next->poh_prev = poh_prev;	return;}static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh){	SIS_OH *pohTemp;	pohTemp = pohList->poh_next;	pohList->poh_next = poh;	pohTemp->poh_prev = poh;	poh->poh_prev = pohList;	poh->poh_next = pohTemp;}static SIS_OH *sisfb_poh_free(unsigned long base){	SIS_OH *pohThis;	SIS_OH *poh_freed;	SIS_OH *poh_prev;	SIS_OH *poh_next;	unsigned long ulUpper;	unsigned long ulLower;	int foundNode = 0;	poh_freed = sisfb_heap.oh_used.poh_next;	while (poh_freed != &sisfb_heap.oh_used) {		if (poh_freed->offset == base) {			foundNode = 1;			break;		}		poh_freed = poh_freed->poh_next;	}	if (!foundNode)		return (NULL);	sisfb_heap.max_freesize += poh_freed->size;	poh_prev = poh_next = NULL;	ulUpper = poh_freed->offset + poh_freed->size;	ulLower = poh_freed->offset;	pohThis = sisfb_heap.oh_free.poh_next;	while (pohThis != &sisfb_heap.oh_free) {		if (pohThis->offset == ulUpper) {			poh_next = pohThis;		}			else if ((pohThis->offset + pohThis->size) ==				 ulLower) {			poh_prev = pohThis;		}		pohThis = pohThis->poh_next;	}	sisfb_delete_node(poh_freed);	if (poh_prev && poh_next) {		poh_prev->size += (poh_freed->size + poh_next->size);		sisfb_delete_node(poh_next);		sisfb_free_node(poh_freed);		sisfb_free_node(poh_next);		return (poh_prev);	}	if (poh_prev) {		poh_prev->size += poh_freed->size;		sisfb_free_node(poh_freed);		return (poh_prev);	}	if (poh_next) {		poh_next->size += poh_freed->size;		poh_next->offset = poh_freed->offset;		sisfb_free_node(poh_freed);		return (poh_next);	}	sisfb_insert_node(&sisfb_heap.oh_free, poh_freed);	return (poh_freed);}static void sisfb_free_node(SIS_OH *poh){	if (poh == NULL) {		return;	}	poh->poh_next = sisfb_heap.poh_freelist;	sisfb_heap.poh_freelist = poh;	return;}void sis_malloc(struct sis_memreq *req){	SIS_OH *poh;	poh = sisfb_poh_allocate(req->size);	if (poh == NULL) {		req->offset = 0;		req->size = 0;		DPRINTK("sisfb: Video RAM allocation failed\n");	} else {		DPRINTK("sisfb: Video RAM allocation succeeded: 0x%p\n",			(char *) (poh->offset +				  (unsigned long) ivideo.video_vbase));		req->offset = poh->offset;		req->size = poh->size;	}}void sis_free(unsigned long base){	SIS_OH *poh;	poh = sisfb_poh_free(base);	if (poh == NULL) {		DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",			(unsigned int) base);	}}/* ------------------ SetMode Routines ------------------------------- */static void sisfb_pre_setmode(void){	u8 cr30 = 0, cr31 = 0;	vgawb(CRTC_ADR, 0x31);	cr31 = vgarb(CRTC_DATA) & ~0x60;	switch (ivideo.disp_state & DISPTYPE_DISP2) {	   case DISPTYPE_CRT2:		printk(KERN_INFO "sisfb: CRT2 type is VGA\n");		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);		cr31 |= SIS_DRIVER_MODE;		break;	   case DISPTYPE_LCD:		printk(KERN_INFO "sisfb: CRT2 type is LCD\n");		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);		cr31 |= SIS_DRIVER_MODE;		break;	   case DISPTYPE_TV:		printk(KERN_INFO "sisfb: CRT2 type is TV\n");		if (ivideo.TV_type == TVMODE_HIVISION)			cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE);		else if (ivideo.TV_plug == TVPLUG_SVIDEO)			cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);		else if (ivideo.TV_plug == TVPLUG_COMPOSITE)			cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);		else if (ivideo.TV_plug == TVPLUG_SCART)			cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);		cr31 |= SIS_DRIVER_MODE;		cr31 &= ~0x04; /* TW: No Slavemode by default  */                /*karl*/	        if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL)			cr31 |= 0x1;                if (sisfb_tvmode == 2 || ivideo.TV_type == TVMODE_NTSC)                        cr31 &= ~0x1;		break;	   default:	/* CRT2 disable */		printk(KERN_INFO "sisfb: CRT2 is disabled\n");		cr30 = 0x00;		cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);	}	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR30);	vgawb(CRTC_DATA, cr30);	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR31);	vgawb(CRTC_DATA, cr31);	/* printk(KERN_INFO "sisfb: 0x30=%x 0x31=%x\n", cr30, cr31); */	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR33);/*	if (ivideo.disp_state & DISPTYPE_CRT2) {		sisfb_rate_idx &= 0x0F;		sisfb_rate_idx |= (sisfb_rate_idx << 4);		vgawb(CRTC_DATA, sisfb_rate_idx);	} else {		vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);	}*/	vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);}static void sisfb_post_setmode(void){	u8 reg;	vgawb(CRTC_ADR, 0x17);	reg = vgarb(CRTC_DATA);	if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL))		if (ivideo.video_bpp == 8)   			sisfb_crt1off = 0;	if (sisfb_crt1off)	  		reg &= ~0x80;	else 	      		reg |= 0x80;	vgawb(CRTC_DATA, reg);		vgawb(SEQ_ADR, IND_SIS_RAMDAC_CONTROL);	reg = vgarb(SEQ_DATA);	reg &= ~0x04;	vgawb(SEQ_DATA, reg);	if ((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {		/*karl*/		vgawb(VB_PART4_ADR,0x01);		reg = vgarb(VB_PART4_DATA);			   if ((reg != 0xB1) && (reg != 0xB0)) /*301B Revision ID*/           {			// Eden Chen		switch (ivideo.video_width) {		   case 320:			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;			break;		   case 640:			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;			break;		   case 720:			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;			break;		   case 800:			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;			break;		   default:			filter = -1;			break;		}		// ~Eden Chen		// Eden Chen		//vgawb(VB_PART1_ADR,  0x24);		vgawb(VB_PART1_ADR,  sisfb_CRT2_write_enable);		// ~Eden Chen		vgawb(VB_PART1_DATA, 0x1);				// Eden Chen for Debug/*		if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {			vgawb(VB_PART1_ADR,  0x2D);			vgawb(VB_PART1_DATA, 0x11);			if (sisfb_mode_no == 0x63) {				vgawb(VB_PART2_ADR,  0x15);				vgawb(VB_PART2_DATA, 0x0A);				vgawb(VB_PART2_ADR,  0x28);				vgawb(VB_PART2_DATA, 0x62);				vgawb(VB_PART2_ADR,  0x2D);				vgawb(VB_PART2_DATA, 0xF8);				vgawb(VB_PART2_ADR,  0x2E);				vgawb(VB_PART2_DATA, 0x14);				vgawb(VB_PART2_ADR,  0x33);				vgawb(VB_PART2_DATA, 0x8A);				vgawb(VB_PART2_ADR,  0x35);				vgawb(VB_PART2_DATA, 0xF4);				vgawb(VB_PART2_ADR,  0x36);				vgawb(VB_PART2_DATA, 0x10);				vgawb(VB_PART2_ADR,  0x37);				vgawb(VB_PART2_DATA, 0x1C);				vgawb(VB_PART2_ADR,  0x38);				vgawb(VB_PART2_DATA, 0x00);				vgawb(VB_PART2_ADR,  0x44);				vgawb(VB_PART2_DATA, 0x29);				vgawb(VB_PART2_ADR,  0x45);				vgawb(VB_PART2_DATA, 0x54);				vgawb(VB_PART4_ADR,  0x0D);				vgawb(VB_PART4_DATA, 0x0F);				vgawb(VB_PART4_ADR,  0x0F);				vgawb(VB_PART4_DATA, 0x0F);				vgawb(VB_PART4_ADR,  0x10);				vgawb(VB_PART4_DATA, 0x83);				vgawb(VB_PART4_ADR,  0x11);				vgawb(VB_PART4_DATA, 0xFF);				vgawb(VB_PART4_ADR,  0x18);				vgawb(VB_PART4_DATA, 0x20);				vgawb(VB_PART4_ADR,  0x19);				vgawb(VB_PART4_DATA, 0x52);			}		}*/		// ~Eden Chen		if (ivideo.TV_type == TVMODE_NTSC) {			vgawb(VB_PART2_ADR, 0x3A);			reg = vgarb(VB_PART2_DATA);			reg &= 0x1F;			vgawb(VB_PART2_DATA, reg);			if (ivideo.TV_plug == TVPLUG_SVIDEO) {				vgawb(VB_PART2_ADR, 0x30);				reg = vgarb(VB_PART2_DATA);				reg &= 0xDF;				vgawb(VB_PART2_DATA, reg);			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {				vgawb(VB_PART2_ADR, 0x30);				reg = vgarb(VB_PART2_DATA);				reg |= 0x20;				vgawb(VB_PART2_DATA, reg);				switch (ivideo.video_width) {				case 640:					vgawb(VB_PART2_ADR,  0x35);					vgawb(VB_PART2_DATA, 0xEB);					vgawb(VB_PART2_ADR,  0x36);					vgawb(VB_PART2_DATA, 0x04);					vgawb(VB_PART2_ADR,  0x37);					vgawb(VB_PART2_DATA, 0x25);					vgawb(VB_PART2_ADR,  0x38);					vgawb(VB_PART2_DATA, 0x18);					break;				case 720:					vgawb(VB_PART2_ADR,  0x35);					vgawb(VB_PART2_DATA, 0xEE);					vgawb(VB_PART2_ADR,  0x36);					vgawb(VB_PART2_DATA, 0x0C);					vgawb(VB_PART2_ADR,  0x37);					vgawb(VB_PART2_DATA, 0x22);					vgawb(VB_PART2_ADR,  0x38);					vgawb(VB_PART2_DATA, 0x08);					break;				case 800:					vgawb(VB_PART2_ADR,  0x35);					vgawb(VB_PART2_DATA, 0xEB);					vgawb(VB_PART2_ADR,  0x36);					vgawb(VB_PART2_DATA, 0x15);					vgawb(VB_PART2_ADR,  0x37);					vgawb(VB_PART2_DATA, 0x25);					vgawb(VB_PART2_ADR,  0x38);					vgawb(VB_PART2_DATA, 0xF6);					break;				}			}		} else if (ivideo.TV_type == TVMODE_PAL) {			vgawb(VB_PART2_ADR, 0x3A);			reg = vgarb(VB_PART2_DATA);			reg &= 0x1F;			vgawb(VB_PART2_DATA, reg);			if (ivideo.TV_plug == TVPLUG_SVIDEO) {				vgawb(VB_PART2_ADR, 0x30);				reg = vgarb(VB_PART2_DATA);				reg &= 0xDF;				vgawb(VB_PART2_DATA, reg);			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {				vgawb(VB_PART2_ADR, 0x30);				reg = vgarb(VB_PART2_DATA);				reg |= 0x20;				vgawb(VB_PART2_DATA, reg);				switch (ivideo.video_width) {				case 640:					vgawb(VB_PART2_ADR,  0x35);					vgawb(VB_PART2_DATA, 0xF1);					vgawb(VB_PART2_ADR,  0x36);					vgawb(VB_PART2_DATA, 0xF7);					vgawb(VB_PART2_ADR,  0x37);					vgawb(VB_PART2_DATA, 0x1F);					vgawb(VB_PART2_ADR,  0x38);					vgawb(VB_PART2_DATA, 0x32);					break;				case 720:					vgawb(VB_PART2_ADR,  0x35);					vgawb(VB_PART2_DATA, 0xF3);					vgawb(VB_PART2_ADR,  0x36);					vgawb(VB_PART2_DATA, 0x00);					vgawb(VB_PART2_ADR,  0x37);					vgawb(VB_PART2_DATA, 0x1D);					vgawb(VB_PART2_ADR,  0x38);					vgawb(VB_PART2_DATA, 0x20);					break;				case 800:					vgawb(VB_PART2_ADR,  0x35);					vgawb(VB_PART2_DATA, 0xFC);					vgawb(VB_PART2_ADR,  0x36);					vgawb(VB_PART2_DATA, 0xFB);					vgawb(VB_PART2_ADR,  0x37);					vgawb(VB_PART2_DATA, 0x14);					vgawb(VB_PART2_ADR,  0x38);					vgawb(VB_PART2_DATA, 0x2A);					break;				}			}		}		// Eden 		if ((filter >= 0) && (filter <=7)) {			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter, 				sis_TV_filter[filter_tb].filter[filter][0],				sis_TV_filter[filter_tb].filter[filter][1],				sis_TV_filter[filter_tb].filter[filter][2],				sis_TV_filter[filter_tb].filter[filter][3]			);			vgawb(VB_PART2_ADR,  0x35);			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][0]);			vgawb(VB_PART2_ADR,  0x36);			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][1]);			vgawb(VB_PART2_ADR,  0x37);			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][2]);			vgawb(VB_PART2_ADR,  0x38);			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][3]);		}		// ~Eden 

⌨️ 快捷键说明

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