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

📄 sis_main.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno){	USHORT  temp, i, realcrtno = crtno;   	u8      buffer[256];	monitor->datavalid = FALSE;	if(crtno) {       	   if(ivideo->vbflags & CRT2_LCD)      realcrtno = 1;      	   else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;      	   else return;   	}	if((ivideo->sisfb_crt1off) && (!crtno)) return;    	temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,				realcrtno, 0, &buffer[0]);   	if((!temp) || (temp == 0xffff)) {      	   printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);	   return;   	} else {      	   printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);      	   printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",	   	crtno + 1,	   	(temp & 0x1a) ? "" : "[none of the supported]",	   	(temp & 0x02) ? "2 " : "",	   	(temp & 0x08) ? "D&P" : "",           	(temp & 0x10) ? "FPDI-2" : "");      	   if(temp & 0x02) {	      i = 3;  /* Number of retrys */	      do {	    	 temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,				     realcrtno, 1, &buffer[0]);	      } while((temp) && i--);              if(!temp) {	    	 if(sisfb_interpret_edid(monitor, &buffer[0])) {		    printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",		    	monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,			monitor->dclockmax / 1000);		 } else {	       	    printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);	    	 }	      } else {            	 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);	      }	   } else {	      printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");	   }	}}static BOOLEANsisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,		int mode_idx, int rate_idx, int rate){	int htotal, vtotal;	unsigned int dclock, hsync;	if(!monitor->datavalid) return TRUE;	if(mode_idx < 0) return FALSE;	/* Skip for 320x200, 320x240, 640x400 */    	switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {    	case 0x59:    	case 0x41:    	case 0x4f:    	case 0x50:    	case 0x56:    	case 0x53:    	case 0x2f:    	case 0x5d:    	case 0x5e:    		return TRUE;#ifdef CONFIG_FB_SIS_315	case 0x5a:	case 0x5b:		if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE;#endif    	}	if(rate < (monitor->vmin - 1)) return FALSE;	if(rate > (monitor->vmax + 1)) return FALSE;	if(sisfb_gettotalfrommode(&ivideo->SiS_Pr, &ivideo->sishw_ext,				  sisbios_mode[mode_idx].mode_no[ivideo->mni],	                          &htotal, &vtotal, rate_idx)) {		dclock = (htotal * vtotal * rate) / 1000;		if(dclock > (monitor->dclockmax + 1000)) return FALSE;		hsync = dclock / htotal;		if(hsync < (monitor->hmin - 1)) return FALSE;		if(hsync > (monitor->hmax + 1)) return FALSE;        } else {	  	return FALSE;	}	return TRUE;}static intsisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags){   u16 xres=0, yres, myres;#ifdef CONFIG_FB_SIS_300   if(ivideo->sisvga_engine == SIS_300_VGA) {      if(!(sisbios_mode[myindex].chipset & MD_SIS300)) return(-1);   }#endif#ifdef CONFIG_FB_SIS_315   if(ivideo->sisvga_engine == SIS_315_VGA) {      if(!(sisbios_mode[myindex].chipset & MD_SIS315)) return(-1);   }#endif   myres = sisbios_mode[myindex].yres;   switch(vbflags & VB_DISPTYPE_DISP2) {     case CRT2_LCD:        xres = ivideo->lcdxres; yres = ivideo->lcdyres;	if(ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) {	   	if(sisbios_mode[myindex].xres > xres) return(-1);           	if(myres > yres) return(-1);	}	if(vbflags & (VB_LVDS | VB_30xBDH)) {	   if(sisbios_mode[myindex].xres == 320) {	      if((myres == 240) || (myres == 480)) {		 if(!ivideo->sisfb_fstn) {		    if(sisbios_mode[myindex].mode_no[1] == 0x5a ||		       sisbios_mode[myindex].mode_no[1] == 0x5b)		       return(-1);		 } else {		    if(sisbios_mode[myindex].mode_no[1] == 0x50 ||		       sisbios_mode[myindex].mode_no[1] == 0x56 ||		       sisbios_mode[myindex].mode_no[1] == 0x53)		       return(-1);		 }	      }	   }	}	if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,			     sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,			     ivideo->SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {	   	return(-1);	}	break;     case CRT2_TV:	if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,	                    sisbios_mode[myindex].yres, 0) < 0x14) {	   	return(-1);	}	break;     case CRT2_VGA:        if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,	                      sisbios_mode[myindex].yres, 0) < 0x14) {	   	return(-1);	}	break;     }     return(myindex);}static u8sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx){	u16 xres, yres;	int i = 0;	xres = sisbios_mode[mode_idx].xres;	yres = sisbios_mode[mode_idx].yres;	ivideo->rate_idx = 0;	while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {		if((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {			if(sisfb_vrate[i].refresh == rate) {				ivideo->rate_idx = sisfb_vrate[i].idx;				break;			} else if(sisfb_vrate[i].refresh > rate) {				if((sisfb_vrate[i].refresh - rate) <= 3) {					DPRINTK("sisfb: Adjusting rate from %d up to %d\n",						rate, sisfb_vrate[i].refresh);					ivideo->rate_idx = sisfb_vrate[i].idx;					ivideo->refresh_rate = sisfb_vrate[i].refresh;				} else if(((rate - sisfb_vrate[i-1].refresh) <= 2)						&& (sisfb_vrate[i].idx != 1)) {					DPRINTK("sisfb: Adjusting rate from %d down to %d\n",						rate, sisfb_vrate[i-1].refresh);					ivideo->rate_idx = sisfb_vrate[i-1].idx;					ivideo->refresh_rate = sisfb_vrate[i-1].refresh;				} 				break;			} else if((rate - sisfb_vrate[i].refresh) <= 2) {				DPRINTK("sisfb: Adjusting rate from %d down to %d\n",						rate, sisfb_vrate[i].refresh);	           		ivideo->rate_idx = sisfb_vrate[i].idx;		   		break;	       		}		}		i++;	}	if(ivideo->rate_idx > 0) {		return ivideo->rate_idx;	} else {		printk(KERN_INFO "sisfb: Unsupported rate %d for %dx%d\n",				rate, xres, yres);		return 0;	}}static BOOLEANsisfb_bridgeisslave(struct sis_video_info *ivideo){   unsigned char P1_00;   if(!(ivideo->vbflags & VB_VIDEOBRIDGE)) return FALSE;   inSISIDXREG(SISPART1,0x00,P1_00);   if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||       ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {	   return TRUE;   } else {           return FALSE;   }}static BOOLEANsisfballowretracecrt1(struct sis_video_info *ivideo){   u8 temp;   inSISIDXREG(SISCR,0x17,temp);   if(!(temp & 0x80)) return FALSE;   inSISIDXREG(SISSR,0x1f,temp);   if(temp & 0xc0) return FALSE;   return TRUE;}static BOOLEANsisfbcheckvretracecrt1(struct sis_video_info *ivideo){   if(!sisfballowretracecrt1(ivideo)) return FALSE;   if(inSISREG(SISINPSTAT) & 0x08) return TRUE;   else 			   return FALSE;}static voidsisfbwaitretracecrt1(struct sis_video_info *ivideo){   int watchdog;   if(!sisfballowretracecrt1(ivideo)) return;   watchdog = 65536;   while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);   watchdog = 65536;   while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);}static BOOLEANsisfbcheckvretracecrt2(struct sis_video_info *ivideo){   unsigned char temp, reg;   switch(ivideo->sisvga_engine) {   case SIS_300_VGA: reg = 0x25; break;   case SIS_315_VGA: reg = 0x30; break;   default:          return FALSE;   }   inSISIDXREG(SISPART1, reg, temp);   if(temp & 0x02) return FALSE;   else 	   return TRUE;}static BOOLEANsisfb_CheckVBRetrace(struct sis_video_info *ivideo){   if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {      if(sisfb_bridgeisslave(ivideo)) {         return(sisfbcheckvretracecrt1(ivideo));      } else {         return(sisfbcheckvretracecrt2(ivideo));      }   }    return(sisfbcheckvretracecrt1(ivideo));}static u32sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount){   u8 idx, reg1, reg2, reg3, reg4;   u32 ret = 0;   (*vcount) = (*hcount) = 0;   if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {      ret |= (FB_VBLANK_HAVE_VSYNC  |      	      FB_VBLANK_HAVE_HBLANK |              FB_VBLANK_HAVE_VBLANK |	      FB_VBLANK_HAVE_VCOUNT |	      FB_VBLANK_HAVE_HCOUNT);      switch(ivideo->sisvga_engine) {         case SIS_300_VGA: idx = 0x25; break;	 default:         case SIS_315_VGA: idx = 0x30; break;      }      inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */      inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */      inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */      inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */      if(!(reg1 & 0x01)) ret |= FB_VBLANK_VBLANKING;      if(!(reg1 & 0x02)) ret |= FB_VBLANK_VSYNCING;      if(!(reg4 & 0x80)) ret |= FB_VBLANK_HBLANKING;      (*vcount) = reg3 | ((reg4 & 0x70) << 4);      (*hcount) = reg2 | ((reg4 & 0x0f) << 8);   } else if(sisfballowretracecrt1(ivideo)) {      ret |= (FB_VBLANK_HAVE_VSYNC  |              FB_VBLANK_HAVE_VBLANK |	      FB_VBLANK_HAVE_VCOUNT |	      FB_VBLANK_HAVE_HCOUNT);      reg1 = inSISREG(SISINPSTAT);      if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;      if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;      inSISIDXREG(SISCR,0x20,reg1);      inSISIDXREG(SISCR,0x1b,reg1);      inSISIDXREG(SISCR,0x1c,reg2);      inSISIDXREG(SISCR,0x1d,reg3);      (*vcount) = reg2 | ((reg3 & 0x07) << 8);      (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;   }   return ret;}static intsisfb_myblank(struct sis_video_info *ivideo, int blank){   u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;   BOOLEAN backlight = TRUE;   switch(blank) {   case 0:	/* on */      sr01  = 0x00;      sr11  = 0x00;      sr1f  = 0x00;      cr63  = 0x00;      p2_0  = 0x20;      p1_13 = 0x00;      backlight = TRUE;      break;   case 1:	/* blank */      sr01  = 0x20;      sr11  = 0x00;      sr1f  = 0x00;      cr63  = 0x00;      p2_0  = 0x20;      p1_13 = 0x00;      backlight = TRUE;      break;   case 2:	/* no vsync */      sr01  = 0x20;      sr11  = 0x08;      sr1f  = 0x80;      cr63  = 0x40;      p2_0  = 0x40;      p1_13 = 0x80;      backlight = FALSE;      break;   case 3:	/* no hsync */      sr01  = 0x20;      sr11  = 0x08;      sr1f  = 0x40;      cr63  = 0x40;      p2_0  = 0x80;      p1_13 = 0x40;      backlight = FALSE;      break;   case 4:	/* off */      sr01  = 0x20;      sr11  = 0x08;      sr1f  = 0xc0;      cr63  = 0x40;      p2_0  = 0xc0;      p1_13 = 0xc0;      backlight = FALSE;      break;   default:      return 1;   }   if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {      if( (!ivideo->sisfb_thismonitor.datavalid) ||          ((ivideo->sisfb_thismonitor.datavalid) &&           (ivideo->sisfb_thismonitor.feature & 0xe0))) {	 if(ivideo->sisvga_engine == SIS_315_VGA) {	    setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);	 }	 if(!(sisfb_bridgeisslave(ivideo))) {	    setSISIDXREG(SISSR, 0x01, ~0x20, sr01);	    setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);	 }      }   }   if(ivideo->currentvbflags & CRT2_LCD) {      if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {	 if(backlight) {	    SiS_SiS30xBLOn(&ivideo->SiS_Pr, &ivideo->sishw_ext);	 } else {	    SiS_SiS30xBLOff(&ivideo->SiS_Pr, &ivideo->sishw_ext);	 }      } else if(ivideo->sisvga_engine == SIS_315_VGA) {	 if(ivideo->vbflags & VB_CHRONTEL) {	    if(backlight) {	       SiS_Chrontel701xBLOn(&ivideo->SiS_Pr,&ivideo->sishw_ext);	    } else {	       SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);	    }	 }      }      if(((ivideo->sisvga_engine == SIS_300_VGA) &&          (ivideo->vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||         ((ivideo->sisvga_engine == SIS_315_VGA) &&          ((ivideo->vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {          setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);      }      if(ivideo->sisvga_engine == SIS_300_VGA) {         if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&            (!(ivideo->vbflags & VB_30xBDH))) {	    setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);	 }      } else if(ivideo->sisvga_engine == SIS_315_VGA) {         if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&            (!(ivideo->vbflags & VB_30xBDH))) {	    setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);	 }      }   } else if(ivideo->currentvbflags & CRT2_VGA) {      if(ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) {         setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);      }   }   return(0);}/* ----------- FBDev related routines for all series ----------- */static intsisfb_get_cmap_len(const struct fb_var_screeninfo *var){	return (var->bits_per_pixel == 8) ? 256 : 16;}static voidsisfb_set_vparms(struct sis_video_info *ivideo){

⌨️ 快捷键说明

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