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

📄 neofb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	vmode:		FB_VMODE_NONINTERLACED};#endifstatic struct fb_var_screeninfo *neofb_var = NULL;static int __devinit neo_map_mmio (struct neofb_info *info){  DBG("neo_map_mmio");  info->mmio.pbase = pci_resource_start (info->pcidev, 1);  info->mmio.len   = MMIO_SIZE;  if (!request_mem_region (info->mmio.pbase, MMIO_SIZE, "memory mapped I/O"))    {      printk ("neofb: memory mapped IO in use\n");      return -EBUSY;    }  info->mmio.vbase = ioremap (info->mmio.pbase, MMIO_SIZE);  if (!info->mmio.vbase)    {      printk ("neofb: unable to map memory mapped IO\n");      release_mem_region (info->mmio.pbase, info->mmio.len);      return -ENOMEM;    }  else    printk (KERN_INFO "neofb: mapped io at %p\n", info->mmio.vbase);  info->fb.fix.mmio_start = info->mmio.pbase;  info->fb.fix.mmio_len   = info->mmio.len;  return 0;}static void __devinit neo_unmap_mmio (struct neofb_info *info){  DBG("neo_unmap_mmio");  if (info->mmio.vbase)    {      iounmap (info->mmio.vbase);      info->mmio.vbase = NULL;      release_mem_region (info->mmio.pbase, info->mmio.len);    }}static int __devinit neo_map_video (struct neofb_info *info, int video_len){  DBG("neo_map_video");  info->video.pbase = pci_resource_start (info->pcidev, 0);  info->video.len   = video_len;  if (!request_mem_region (info->video.pbase, info->video.len, "frame buffer"))    {      printk ("neofb: frame buffer in use\n");      return -EBUSY;    }  info->video.vbase = ioremap (info->video.pbase, info->video.len);  if (!info->video.vbase)    {      printk ("neofb: unable to map screen memory\n");      release_mem_region (info->video.pbase, info->video.len);      return -ENOMEM;    }  else    printk (KERN_INFO "neofb: mapped framebuffer at %p\n", info->video.vbase);  info->fb.fix.smem_start = info->video.pbase;  info->fb.fix.smem_len   = info->video.len;  info->fb.screen_base    = info->video.vbase;#ifdef CONFIG_MTRR  info->video.mtrr = mtrr_add (info->video.pbase, pci_resource_len (info->pcidev, 0), MTRR_TYPE_WRCOMB, 1);#endif  /* Clear framebuffer, it's all white in memory after boot */  memset (info->video.vbase, 0, info->video.len);  return 0;}static void __devinit neo_unmap_video (struct neofb_info *info){  DBG("neo_unmap_video");  if (info->video.vbase)    {#ifdef CONFIG_MTRR      mtrr_del (info->video.mtrr, info->video.pbase, info->video.len);#endif      iounmap (info->video.vbase);      info->video.vbase = NULL;      info->fb.screen_base = NULL;      release_mem_region (info->video.pbase, info->video.len);    }}static int __devinit neo_init_hw (struct neofb_info *info){  int videoRam = 896;  int maxClock = 65000;  int CursorMem = 1024;  int CursorOff = 0x100;  int linearSize = 1024;  int maxWidth = 1024;  int maxHeight = 1024;  unsigned char type, display;  int w;      DBG("neo_init_hw");  neoUnlock();#if 0  printk (KERN_DEBUG "--- Neo extended register dump ---\n");  for (w=0; w<0x85; w++)    printk (KERN_DEBUG "CR %p: %p\n", (void*)w, (void*)VGArCR (w));  for (w=0; w<0xC7; w++)    printk (KERN_DEBUG "GR %p: %p\n", (void*)w, (void*)VGArGR (w));#endif  /* Determine the panel type */  VGAwGR(0x09,0x26);  type = VGArGR(0x21);  display = VGArGR(0x20);      /* Determine panel width -- used in NeoValidMode. */  w = VGArGR(0x20);  VGAwGR(0x09,0x00);  switch ((w & 0x18) >> 3)    {    case 0x00:      info->NeoPanelWidth  = 640;      info->NeoPanelHeight = 480;      neofb_var = &neofb_var640x480x8;      break;    case 0x01:      info->NeoPanelWidth  = 800;      info->NeoPanelHeight = 600;      neofb_var = &neofb_var800x600x8;      break;    case 0x02:      info->NeoPanelWidth  = 1024;      info->NeoPanelHeight = 768;      neofb_var = &neofb_var1024x768x8;      break;    case 0x03:      /* 1280x1024 panel support needs to be added */#ifdef NOT_DONE      info->NeoPanelWidth  = 1280;      info->NeoPanelHeight = 1024;      neofb_var = &neofb_var1280x1024x8;      break;#else      printk (KERN_ERR "neofb: Only 640x480, 800x600 and 1024x768 panels are currently supported\n");      return -1;#endif    default:      info->NeoPanelWidth  = 640;      info->NeoPanelHeight = 480;      neofb_var = &neofb_var640x480x8;      break;    }  printk (KERN_INFO "Panel is a %dx%d %s %s display\n",	  info->NeoPanelWidth,	  info->NeoPanelHeight,	  (type & 0x02) ? "color" : "monochrome",	  (type & 0x10) ? "TFT" : "dual scan");  switch (info->accel)    {    case FB_ACCEL_NEOMAGIC_NM2070:      videoRam   = 896;      maxClock   = 65000;      CursorMem  = 2048;      CursorOff  = 0x100;      linearSize = 1024;      maxWidth   = 1024;      maxHeight  = 1024;      break;    case FB_ACCEL_NEOMAGIC_NM2090:    case FB_ACCEL_NEOMAGIC_NM2093:      videoRam   = 1152;      maxClock   = 80000;      CursorMem  = 2048;      CursorOff  = 0x100;      linearSize = 2048;      maxWidth   = 1024;      maxHeight  = 1024;      break;    case FB_ACCEL_NEOMAGIC_NM2097:      videoRam   = 1152;      maxClock   = 80000;      CursorMem  = 1024;      CursorOff  = 0x100;      linearSize = 2048;      maxWidth   = 1024;      maxHeight  = 1024;      break;    case FB_ACCEL_NEOMAGIC_NM2160:      videoRam   = 2048;      maxClock   = 90000;      CursorMem  = 1024;      CursorOff  = 0x100;      linearSize = 2048;      maxWidth   = 1024;      maxHeight  = 1024;      break;    case FB_ACCEL_NEOMAGIC_NM2200:      videoRam   = 2560;      maxClock   = 110000;      CursorMem  = 1024;      CursorOff  = 0x1000;      linearSize = 4096;      maxWidth   = 1280;      maxHeight  = 1024;  /* ???? */      info->neo2200 = (Neo2200*) info->mmio.vbase;      break;    case FB_ACCEL_NEOMAGIC_NM2230:      videoRam   = 3008;      maxClock   = 110000;      CursorMem  = 1024;      CursorOff  = 0x1000;      linearSize = 4096;      maxWidth   = 1280;      maxHeight  = 1024;  /* ???? */      info->neo2200 = (Neo2200*) info->mmio.vbase;      break;    case FB_ACCEL_NEOMAGIC_NM2360:      videoRam   = 4096;      maxClock   = 110000;      CursorMem  = 1024;      CursorOff  = 0x1000;      linearSize = 4096;      maxWidth   = 1280;      maxHeight  = 1024;  /* ???? */      info->neo2200 = (Neo2200*) info->mmio.vbase;      break;    case FB_ACCEL_NEOMAGIC_NM2380:      videoRam   = 6144;      maxClock   = 110000;      CursorMem  = 1024;      CursorOff  = 0x1000;      linearSize = 8192;      maxWidth   = 1280;      maxHeight  = 1024;  /* ???? */      info->neo2200 = (Neo2200*) info->mmio.vbase;      break;    }  info->maxClock = maxClock;  return videoRam * 1024;}static struct neofb_info * __devinit neo_alloc_fb_info (struct pci_dev *dev,							const struct pci_device_id *id){  struct neofb_info *info;  info = kmalloc (sizeof(struct neofb_info) + sizeof(struct display) +		  sizeof(u32) * 16, GFP_KERNEL);  if (!info)    return NULL;  memset (info, 0, sizeof(struct neofb_info) + sizeof(struct display));  info->currcon = -1;  info->pcidev  = dev;  info->accel   = id->driver_data;  info->pci_burst   = !nopciburst;  info->lcd_stretch = !nostretch;  if (!internal && !external)    {      info->internal_display = 1;      info->external_display = 0;    }  else    {      info->internal_display = internal;      info->external_display = external;    }  switch (info->accel)    {    case FB_ACCEL_NEOMAGIC_NM2070:      sprintf (info->fb.fix.id, "MagicGraph 128");      break;    case FB_ACCEL_NEOMAGIC_NM2090:      sprintf (info->fb.fix.id, "MagicGraph 128V");      break;    case FB_ACCEL_NEOMAGIC_NM2093:      sprintf (info->fb.fix.id, "MagicGraph 128ZV");      break;    case FB_ACCEL_NEOMAGIC_NM2097:      sprintf (info->fb.fix.id, "MagicGraph 128ZV+");      break;    case FB_ACCEL_NEOMAGIC_NM2160:      sprintf (info->fb.fix.id, "MagicGraph 128XD");      break;    case FB_ACCEL_NEOMAGIC_NM2200:      sprintf (info->fb.fix.id, "MagicGraph 256AV");      break;    case FB_ACCEL_NEOMAGIC_NM2230:      sprintf (info->fb.fix.id, "MagicGraph 256AV+");      break;    case FB_ACCEL_NEOMAGIC_NM2360:      sprintf (info->fb.fix.id, "MagicGraph 256ZX");      break;    case FB_ACCEL_NEOMAGIC_NM2380:      sprintf (info->fb.fix.id, "MagicGraph 256XL+");      break;    }  info->fb.fix.type	   = FB_TYPE_PACKED_PIXELS;  info->fb.fix.type_aux	   = 0;  info->fb.fix.xpanstep	   = 0;  info->fb.fix.ypanstep	   = 4;  info->fb.fix.ywrapstep   = 0;  info->fb.fix.accel       = id->driver_data;  info->fb.var.nonstd      = 0;  info->fb.var.activate    = FB_ACTIVATE_NOW;  info->fb.var.height      = -1;  info->fb.var.width       = -1;  info->fb.var.accel_flags = 0;  strcpy (info->fb.modename, info->fb.fix.id);  info->fb.fbops          = &neofb_ops;  info->fb.changevar      = NULL;  info->fb.switch_con     = neofb_switch;  info->fb.updatevar      = neofb_updatevar;  info->fb.blank          = neofb_blank;  info->fb.flags          = FBINFO_FLAG_DEFAULT;  info->fb.disp           = (struct display *)(info + 1);  info->fb.pseudo_palette = (void *)(info->fb.disp + 1);  fb_alloc_cmap (&info->fb.cmap, NR_PALETTE, 0);  return info;}static void __devinit neo_free_fb_info (struct neofb_info *info){  if (info)    {      /*       * Free the colourmap       */      fb_alloc_cmap (&info->fb.cmap, 0, 0);      kfree (info);    }}/* --------------------------------------------------------------------- */static int __devinit neofb_probe (struct pci_dev* dev, const struct pci_device_id* id){  struct neofb_info *info;  u_int h_sync, v_sync;  int err;  int video_len;  DBG("neofb_probe");  err = pci_enable_device (dev);  if (err)    return err;  err = -ENOMEM;  info = neo_alloc_fb_info (dev, id);  if (!info)    goto failed;  err = neo_map_mmio (info);  if (err)    goto failed;  video_len = neo_init_hw (info);  if (video_len < 0)    {      err = video_len;      goto failed;    }  err = neo_map_video (info, video_len);  if (err)    goto failed;  neofb_set_var (neofb_var, -1, &info->fb);  /*   * Calculate the hsync and vsync frequencies.  Note that   * we split the 1e12 constant up so that we can preserve   * the precision and fit the results into 32-bit registers.   *  (1953125000 * 512 = 1e12)   */  h_sync = 1953125000 / info->fb.var.pixclock;  h_sync = h_sync * 512 / (info->fb.var.xres + info->fb.var.left_margin +			   info->fb.var.right_margin + info->fb.var.hsync_len);  v_sync = h_sync / (info->fb.var.yres + info->fb.var.upper_margin +		     info->fb.var.lower_margin + info->fb.var.vsync_len);  printk(KERN_INFO "neofb v" NEOFB_VERSION ": %dkB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",	 info->fb.fix.smem_len >> 10,	 info->fb.var.xres, info->fb.var.yres,	 h_sync / 1000, h_sync % 1000, v_sync);  err = register_framebuffer (&info->fb);  if (err < 0)    goto failed;  printk (KERN_INFO "fb%d: %s frame buffer device\n",	  GET_FB_IDX(info->fb.node), info->fb.modename);  /*   * Our driver data   */  pci_set_drvdata(dev, info);  return 0;failed:  neo_unmap_video (info);  neo_unmap_mmio (info);  neo_free_fb_info (info);  return err;}static void __devexit neofb_remove (struct pci_dev *dev){  struct neofb_info *info = pci_get_drvdata(dev);  DBG("neofb_remove");  if (info)    {      /*       * If unregister_framebuffer fails, then       * we will be leaving hooks that could cause       * oopsen laying around.       */      if (unregister_framebuffer (&info->fb))	printk (KERN_WARNING "neofb: danger danger!  Oopsen imminent!\n");      neo_unmap_video (info);      neo_unmap_mmio (info);      neo_free_fb_info (info);      /*       * Ensure that the driver data is no longer       * valid.       */      pci_set_drvdata(dev, NULL);    }}static struct pci_device_id neofb_devices[] __devinitdata = {  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2070,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2070},  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2090,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2090},  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2093,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2093},  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2097,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2097},  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2160,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2160},  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2200,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2200},  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2230,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2230},  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2360,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2360},  {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2380,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2380},  {0, 0, 0, 0, 0, 0, 0}};MODULE_DEVICE_TABLE(pci, neofb_devices);static struct pci_driver neofb_driver = {  name:      "neofb",  id_table:  neofb_devices,  probe:     neofb_probe,  remove:    __devexit_p(neofb_remove)};/* **************************** init-time only **************************** */static void __init neo_init (void){  DBG("neo_init");  pci_register_driver (&neofb_driver);}/* **************************** exit-time only **************************** */static void __exit neo_done (void){  DBG("neo_done");  pci_unregister_driver (&neofb_driver);}#ifndef MODULE/* ************************* init in-kernel code ************************** */int __init neofb_setup (char *options){  char *this_opt;  DBG("neofb_setup");  if (!options || !*options)    return 0;  for (this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,","))    {      if (!*this_opt) continue;      if (!strncmp(this_opt, "disabled", 8))	disabled = 1;      if (!strncmp(this_opt, "internal", 8))	internal = 1;      if (!strncmp(this_opt, "external", 8))	external = 1;      if (!strncmp(this_opt, "nostretch", 9))	nostretch = 1;      if (!strncmp(this_opt, "nopciburst", 10))	nopciburst = 1;    }  return 0;}static int __initdata initialized = 0;int __init neofb_init(void){  DBG("neofb_init");  if (disabled)    return -ENXIO;  if (!initialized)    {      initialized = 1;      neo_init();    }  /* never return failure, user can hotplug card later... */  return 0;}#else/* *************************** init module code **************************** */int __init init_module(void){  DBG("init_module");  if (disabled)    return -ENXIO;  neo_init();  /* never return failure; user can hotplug card later... */  return 0;}#endif	/* MODULE */module_exit(neo_done);

⌨️ 快捷键说明

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