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

📄 neofb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    default:      break;    }	  par->ExtCRTDispAddr = 0x10;  /* Vertical Extension */  par->VerticalExt = (((timings.VTotal -2) & 0x400) >> 10 )    | (((timings.VDisplay -1) & 0x400) >> 9 )    | (((timings.VSyncStart) & 0x400) >> 8 )    | (((timings.VSyncStart) & 0x400) >> 7 );  /* Fast write bursts on unless disabled. */  if (info->pci_burst)    par->SysIfaceCntl1 = 0x30;   else    par->SysIfaceCntl1 = 0x00;   par->SysIfaceCntl2 = 0xc0; /* VESA Bios sets this to 0x80! */  /* Enable any user specified display devices. */  par->PanelDispCntlReg1 = 0x00;  if (info->internal_display)    par->PanelDispCntlReg1 |= 0x02;  if (info->external_display)    par->PanelDispCntlReg1 |= 0x01;  /* If the user did not specify any display devices, then... */  if (par->PanelDispCntlReg1 == 0x00) {    /* Default to internal (i.e., LCD) only. */    par->PanelDispCntlReg1 |= 0x02;  }  /* If we are using a fixed mode, then tell the chip we are. */  switch (var->xres)    {    case 1280:      par->PanelDispCntlReg1 |= 0x60;      break;    case 1024:      par->PanelDispCntlReg1 |= 0x40;      break;    case 800:      par->PanelDispCntlReg1 |= 0x20;      break;    case 640:    default:      break;    }    /* Setup shadow register locking. */  switch (par->PanelDispCntlReg1 & 0x03)    {    case 0x01: /* External CRT only mode: */      par->GeneralLockReg = 0x00;      /* We need to program the VCLK for external display only mode. */      par->ProgramVCLK = 1;      break;    case 0x02: /* Internal LCD only mode: */    case 0x03: /* Simultaneous internal/external (LCD/CRT) mode: */      par->GeneralLockReg = 0x01;      /* Don't program the VCLK when using the LCD. */      par->ProgramVCLK = 0;      break;    }  /*   * If the screen is to be stretched, turn on stretching for the   * various modes.   *   * OPTION_LCD_STRETCH means stretching should be turned off!   */  par->PanelDispCntlReg2 = 0x00;  par->PanelDispCntlReg3 = 0x00;  if (info->lcd_stretch &&      (par->PanelDispCntlReg1 == 0x02) &&  /* LCD only */      (var->xres != info->NeoPanelWidth))    {      switch (var->xres)	{	case  320: /* Needs testing.  KEM -- 24 May 98 */	case  400: /* Needs testing.  KEM -- 24 May 98 */	case  640:	case  800:	case 1024:	  lcd_stretch = 1;	  par->PanelDispCntlReg2 |= 0xC6;	  break;	default:	  lcd_stretch = 0;	  /* No stretching in these modes. */	}    }  else    lcd_stretch = 0;  /*   * If the screen is to be centerd, turn on the centering for the   * various modes.   */  par->PanelVertCenterReg1  = 0x00;  par->PanelVertCenterReg2  = 0x00;  par->PanelVertCenterReg3  = 0x00;  par->PanelVertCenterReg4  = 0x00;  par->PanelVertCenterReg5  = 0x00;  par->PanelHorizCenterReg1 = 0x00;  par->PanelHorizCenterReg2 = 0x00;  par->PanelHorizCenterReg3 = 0x00;  par->PanelHorizCenterReg4 = 0x00;  par->PanelHorizCenterReg5 = 0x00;  if (par->PanelDispCntlReg1 & 0x02)    {      if (var->xres == info->NeoPanelWidth)	{	  /*	   * No centering required when the requested display width	   * equals the panel width.	   */	}      else	{	  par->PanelDispCntlReg2 |= 0x01;	  par->PanelDispCntlReg3 |= 0x10;	  /* Calculate the horizontal and vertical offsets. */	  if (!lcd_stretch)	    {	      hoffset = ((info->NeoPanelWidth - var->xres) >> 4) - 1;	      voffset = ((info->NeoPanelHeight - var->yres) >> 1) - 2;	    }	  else	    {	      /* Stretched modes cannot be centered. */	      hoffset = 0;	      voffset = 0;	    }	  switch (var->xres)	    {	    case  320: /* Needs testing.  KEM -- 24 May 98 */	      par->PanelHorizCenterReg3 = hoffset;	      par->PanelVertCenterReg2  = voffset;	      break;	    case  400: /* Needs testing.  KEM -- 24 May 98 */	      par->PanelHorizCenterReg4 = hoffset;	      par->PanelVertCenterReg1  = voffset;	      break;	    case  640:	      par->PanelHorizCenterReg1 = hoffset;	      par->PanelVertCenterReg3  = voffset;	      break;	    case  800:	      par->PanelHorizCenterReg2 = hoffset;	      par->PanelVertCenterReg4  = voffset;	      break;	    case 1024:	      par->PanelHorizCenterReg5 = hoffset;	      par->PanelVertCenterReg5  = voffset;	      break;	    case 1280:	    default:	      /* No centering in these modes. */	      break;	    }	}    }  par->biosMode = neoFindMode (var->xres, var->yres, var->bits_per_pixel);      /*   * Calculate the VCLK that most closely matches the requested dot   * clock.   */  neoCalcVCLK (info, par, timings.pixclock);  /* Since we program the clocks ourselves, always use VCLK3. */  par->MiscOutReg |= 0x0C;  return 0;}static int neofb_set_var (struct fb_var_screeninfo *var, int con,                          struct fb_info *fb){  struct neofb_info *info = (struct neofb_info *)fb;  struct display *display;  struct neofb_par par;  int err, chgvar = 0;  DBG("neofb_set_var");  err = neofb_decode_var (var, info, &par);  if (err)    return err;  if (var->activate & FB_ACTIVATE_TEST)    return 0;  if (con < 0)    {      display = fb->disp;      chgvar = 0;    }  else    {      display = fb_display + con;      if (fb->var.xres != var->xres)	chgvar = 1;      if (fb->var.yres != var->yres)	chgvar = 1;      if (fb->var.xres_virtual != var->xres_virtual)	chgvar = 1;      if (fb->var.yres_virtual != var->yres_virtual)	chgvar = 1;      if (fb->var.bits_per_pixel != var->bits_per_pixel)	chgvar = 1;    }  if (!info->neo2200)    var->accel_flags &= ~FB_ACCELF_TEXT;  var->red.msb_right	= 0;  var->green.msb_right	= 0;  var->blue.msb_right	= 0;  switch (var->bits_per_pixel)    {#ifdef FBCON_HAS_CFB8    case 8:	/* PSEUDOCOLOUR, 256 */      var->transp.offset   = 0;      var->transp.length   = 0;      var->red.offset      = 0;      var->red.length      = 8;      var->green.offset	   = 0;      var->green.length	   = 8;      var->blue.offset	   = 0;      var->blue.length	   = 8;            fb->fix.visual       = FB_VISUAL_PSEUDOCOLOR;      info->dispsw         = &fbcon_cfb8;      display->dispsw_data = NULL;      display->next_line   = var->xres_virtual;      break;#endif#ifdef FBCON_HAS_CFB16    case 16: /* DIRECTCOLOUR, 64k */      var->transp.offset   = 0;      var->transp.length   = 0;      var->red.offset      = 11;      var->red.length      = 5;      var->green.offset    = 5;      var->green.length    = 6;      var->blue.offset     = 0;      var->blue.length     = 5;      fb->fix.visual       = FB_VISUAL_DIRECTCOLOR;      info->dispsw         = &fbcon_cfb16;      display->dispsw_data = fb->pseudo_palette;      display->next_line   = var->xres_virtual * 2;      break;#endif#ifdef FBCON_HAS_CFB24    case 24: /* TRUECOLOUR, 16m */      var->transp.offset   = 0;      var->transp.length   = 0;      var->red.offset      = 16;      var->red.length      = 8;      var->green.offset    = 8;      var->green.length    = 8;      var->blue.offset     = 0;      var->blue.length     = 8;      fb->fix.visual       = FB_VISUAL_TRUECOLOR;      info->dispsw         = &fbcon_cfb24;      display->dispsw_data = fb->pseudo_palette;      display->next_line   = var->xres_virtual * 3;      var->accel_flags    &= ~FB_ACCELF_TEXT;      break;#endif#ifdef NO_32BIT_SUPPORT_YET# ifdef FBCON_HAS_CFB32    case 32: /* TRUECOLOUR, 16m */      var->transp.offset   = 24;      var->transp.length   = 8;      var->red.offset      = 16;      var->red.length      = 8;      var->green.offset    = 8;      var->green.length    = 8;      var->blue.offset     = 0;      var->blue.length     = 8;      fb->fix.visual       = FB_VISUAL_TRUECOLOR;      info->dispsw         = &fbcon_cfb32;      display->dispsw_data = fb->pseudo_palette;      display->next_line   = var->xres_virtual * 4;      var->accel_flags    &= ~FB_ACCELF_TEXT;      break;# endif#endif    default:      printk (KERN_WARNING "neofb: no support for %dbpp\n", var->bits_per_pixel);      info->dispsw      = &fbcon_dummy;      var->accel_flags &= ~FB_ACCELF_TEXT;      break;    }  if (var->accel_flags & FB_ACCELF_TEXT)    display->dispsw = &fbcon_neo2200_accel;  else    display->dispsw = info->dispsw;  fb->fix.line_length = display->next_line;  display->screen_base    = fb->screen_base;  display->line_length    = fb->fix.line_length;  display->visual         = fb->fix.visual;  display->type	          = fb->fix.type;  display->type_aux       = fb->fix.type_aux;  display->ypanstep       = fb->fix.ypanstep;  display->ywrapstep      = fb->fix.ywrapstep;  display->can_soft_blank = 1;  display->inverse        = 0;  fb->var = *var;  fb->var.activate &= ~FB_ACTIVATE_ALL;  /*   * Update the old var.  The fbcon drivers still use this.   * Once they are using cfb->fb.var, this can be dropped.   *					--rmk   */  display->var = fb->var;  /*   * If we are setting all the virtual consoles, also set the   * defaults used to create new consoles.   */  if (var->activate & FB_ACTIVATE_ALL)    fb->disp->var = fb->var;  if (chgvar && fb && fb->changevar)    fb->changevar (con);  if (con == info->currcon)    {      if (chgvar || con < 0)        neofb_set_par (info, &par);      neofb_update_start (info, var);      fb_set_cmap (&fb->cmap, 1, neo_setcolreg, fb);      if (var->accel_flags & FB_ACCELF_TEXT)	neo2200_accel_init (info, var);    }  return 0;}/* *    Pan or Wrap the Display */static int neofb_pan_display (struct fb_var_screeninfo *var, int con,			      struct fb_info *fb){  struct neofb_info *info = (struct neofb_info *)fb;  u_int y_bottom;  y_bottom = var->yoffset;  if (!(var->vmode & FB_VMODE_YWRAP))    y_bottom += var->yres;  if (var->xoffset > (var->xres_virtual - var->xres))    return -EINVAL;  if (y_bottom > fb->var.yres_virtual)    return -EINVAL;  neofb_update_start (info, var);  fb->var.xoffset = var->xoffset;  fb->var.yoffset = var->yoffset;  if (var->vmode & FB_VMODE_YWRAP)    fb->var.vmode |= FB_VMODE_YWRAP;  else    fb->var.vmode &= ~FB_VMODE_YWRAP;  return 0;}/* *    Update the `var' structure (called by fbcon.c) * *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. *    Since it's called by a kernel driver, no range checking is done. */static int neofb_updatevar (int con, struct fb_info *fb){  struct neofb_info *info = (struct neofb_info *)fb;  neofb_update_start (info, &fb_display[con].var);  return 0;}static int neofb_switch (int con, struct fb_info *fb){  struct neofb_info *info = (struct neofb_info *)fb;  struct display *disp;  struct fb_cmap *cmap;  if (info->currcon >= 0)    {      disp = fb_display + info->currcon;      /*       * Save the old colormap and video mode.       */      disp->var = fb->var;      if (disp->cmap.len)	fb_copy_cmap(&fb->cmap, &disp->cmap, 0);    }  info->currcon = con;  disp = fb_display + con;  /*   * Install the new colormap and change the video mode.  By default,   * fbcon sets all the colormaps and video modes to the default   * values at bootup.   *   * Really, we want to set the colourmap size depending on the   * depth of the new video mode.  For now, we leave it at its   * default 256 entry.   */  if (disp->cmap.len)    cmap = &disp->cmap;  else    cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);  fb_copy_cmap(cmap, &fb->cmap, 0);  disp->var.activate = FB_ACTIVATE_NOW;  neofb_set_var(&disp->var, con, fb);  return 0;}/* *    (Un)Blank the display. */static void neofb_blank (int blank, struct fb_info *fb){  //  struct neofb_info *info = (struct neofb_info *)fb;  /*   *  Blank the screen if blank_mode != 0, else unblank. If   *  blank == NULL then the caller blanks by setting the CLUT   *  (Color Look Up Table) to all black. Return 0 if blanking   *  succeeded, != 0 if un-/blanking failed due to e.g. a   *  video mode which doesn't support it. Implements VESA   *  suspend and powerdown modes on hardware that supports   *  disabling hsync/vsync:   *    blank_mode == 2: suspend vsync   *    blank_mode == 3: suspend hsync   *    blank_mode == 4: powerdown   *   *  wms...Enable VESA DMPS compatible powerdown mode   *  run "setterm -powersave powerdown" to take advantage   */       switch (blank)    {    case 4:	/* powerdown - both sync lines down */      break;	    case 3:	/* hsync off */      break;	    case 2:	/* vsync off */      break;	    case 1:	/* just software blanking of screen */      break;    default: /* case 0, or anything else: unblank */      break;    }}/* * Get the currently displayed virtual consoles colormap. */static int gen_get_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *fb){  fb_copy_cmap (&fb->cmap, cmap, kspc ? 0 : 2);  return 0;}/* * Get the currently displayed virtual consoles fixed part of the display. */static int gen_get_fix (struct fb_fix_screeninfo *fix, int con, struct fb_info *fb){  *fix = fb->fix;  return 0;}/* * Get the current user defined part of the display. */static int gen_get_var (struct fb_var_screeninfo *var, int con, struct fb_info *fb){  *var = fb->var;  return 0;}static struct fb_ops neofb_ops = {  owner:          THIS_MODULE,  fb_set_var:     neofb_set_var,  fb_set_cmap:    neofb_set_cmap,  fb_pan_display: neofb_pan_display,  fb_get_fix:     gen_get_fix,  fb_get_var:     gen_get_var,  fb_get_cmap:    gen_get_cmap,};/* --------------------------------------------------------------------- */static struct fb_var_screeninfo __devinitdata neofb_var640x480x8 = {	accel_flags:	FB_ACCELF_TEXT,	xres:		640,	yres:		480,	xres_virtual:   640,	yres_virtual:   30000,	bits_per_pixel: 8,	pixclock:	39722,	left_margin:	48,	right_margin:	16,	upper_margin:	33,	lower_margin:	10,	hsync_len:	96,	vsync_len:	2,	sync:		0,	vmode:		FB_VMODE_NONINTERLACED};static struct fb_var_screeninfo __devinitdata neofb_var800x600x8 = {	accel_flags:	FB_ACCELF_TEXT,	xres:		800,	yres:		600,	xres_virtual:   800,	yres_virtual:   30000,	bits_per_pixel: 8,	pixclock:	25000,	left_margin:	88,	right_margin:	40,	upper_margin:	23,	lower_margin:	1,	hsync_len:	128,	vsync_len:	4,	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,	vmode:		FB_VMODE_NONINTERLACED};static struct fb_var_screeninfo __devinitdata neofb_var1024x768x8 = {	accel_flags:	FB_ACCELF_TEXT,	xres:		1024,	yres:		768,	xres_virtual:   1024,	yres_virtual:   30000,	bits_per_pixel: 8,	pixclock:	15385,	left_margin:	160,	right_margin:	24,	upper_margin:	29,	lower_margin:	3,	hsync_len:	136,	vsync_len:	6,	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,	vmode:		FB_VMODE_NONINTERLACED};#ifdef NOT_DONEstatic struct fb_var_screeninfo __devinitdata neofb_var1280x1024x8 = {	accel_flags:	FB_ACCELF_TEXT,	xres:		1280,	yres:		1024,	xres_virtual:   1280,	yres_virtual:   30000,	bits_per_pixel: 8,	pixclock:	9260,	left_margin:	248,	right_margin:	48,	upper_margin:	38,	lower_margin:	1,	hsync_len:	112,	vsync_len:	3,	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,

⌨️ 快捷键说明

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