q40fb.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * linux/drivers/video/q40fb.c -- Q40 frame buffer device
  3. *
  4. * Copyright (C) 2001
  5. *
  6. * Richard Zidlicky <rz@linux-m68k.org>
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file COPYING in the main directory of this archive for
  10. * more details.
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/errno.h>
  14. #include <linux/string.h>
  15. #include <linux/mm.h>
  16. #include <linux/tty.h>
  17. #include <linux/slab.h>
  18. #include <linux/delay.h>
  19. #include <linux/interrupt.h>
  20. #include <asm/uaccess.h>
  21. #include <asm/setup.h>
  22. #include <asm/system.h>
  23. #include <asm/q40_master.h>
  24. #include <linux/fb.h>
  25. #include <linux/module.h>
  26. #include <asm/pgtable.h>
  27. #define Q40_PHYS_SCREEN_ADDR 0xFE800000
  28. static struct fb_fix_screeninfo q40fb_fix __initdata = {
  29. .id = "Q40",
  30. .smem_len = 1024*1024,
  31. .type = FB_TYPE_PACKED_PIXELS,
  32. .visual = FB_VISUAL_TRUECOLOR,
  33. .line_length = 1024*2,
  34. .accel = FB_ACCEL_NONE,
  35. };
  36. static struct fb_var_screeninfo q40fb_var __initdata = {
  37. .xres = 1024,
  38. .yres = 512,
  39. .xres_virtual = 1024,
  40. .yres_virtual = 512,
  41. .bits_per_pixel = 16,
  42. .red = {6, 5, 0},
  43. .green = {11, 5, 0},
  44. .blue = {0, 6, 0},
  45. .activate = FB_ACTIVATE_NOW,
  46. .height = 230,
  47. .width = 300,
  48. .vmode = FB_VMODE_NONINTERLACED,
  49. };
  50. static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
  51. unsigned blue, unsigned transp,
  52. struct fb_info *info)
  53. {
  54. /*
  55. * Set a single color register. The values supplied have a 16 bit
  56. * magnitude.
  57. * Return != 0 for invalid regno.
  58. */
  59. if (regno > 255)
  60. return 1;
  61. red>>=11;
  62. green>>=11;
  63. blue>>=10;
  64. if (regno < 16) {
  65. ((u32 *)info->pseudo_palette)[regno] = ((red & 31) <<6) |
  66. ((green & 31) << 11) |
  67. (blue & 63);
  68. }
  69. return 0;
  70. }
  71. static struct fb_ops q40fb_ops = {
  72. .owner = THIS_MODULE,
  73. .fb_setcolreg = q40fb_setcolreg,
  74. .fb_fillrect = cfb_fillrect,
  75. .fb_copyarea = cfb_copyarea,
  76. .fb_imageblit = cfb_imageblit,
  77. .fb_cursor = soft_cursor,
  78. };
  79. static int __init q40fb_probe(struct device *device)
  80. {
  81. struct platform_device *dev = to_platform_device(device);
  82. struct fb_info *info;
  83. if (!MACH_IS_Q40)
  84. return -ENXIO;
  85. /* mapped in q40/config.c */
  86. q40fb_fix.smem_start = Q40_PHYS_SCREEN_ADDR;
  87. info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
  88. if (!info)
  89. return -ENOMEM;
  90. info->var = q40fb_var;
  91. info->fix = q40fb_fix;
  92. info->fbops = &q40fb_ops;
  93. info->flags = FBINFO_DEFAULT; /* not as module for now */
  94. info->pseudo_palette = info->par;
  95. info->par = NULL;
  96. info->screen_base = (char *) q40fb_fix.smem_start;
  97. if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
  98. framebuffer_release(info);
  99. return -ENOMEM;
  100. }
  101. master_outb(3, DISPLAY_CONTROL_REG);
  102. if (register_framebuffer(info) < 0) {
  103. printk(KERN_ERR "Unable to register Q40 frame buffer\n");
  104. fb_dealloc_cmap(&info->cmap);
  105. framebuffer_release(info);
  106. return -EINVAL;
  107. }
  108. printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n",
  109. info->node);
  110. return 0;
  111. }
  112. static struct device_driver q40fb_driver = {
  113. .name = "q40fb",
  114. .bus = &platform_bus_type,
  115. .probe = q40fb_probe,
  116. };
  117. static struct platform_device q40fb_device = {
  118. .name = "q40fb",
  119. };
  120. int __init q40fb_init(void)
  121. {
  122. int ret = 0;
  123. if (fb_get_options("q40fb", NULL))
  124. return -ENODEV;
  125. ret = driver_register(&q40fb_driver);
  126. if (!ret) {
  127. ret = platform_device_register(&q40fb_device);
  128. if (ret)
  129. driver_unregister(&q40fb_driver);
  130. }
  131. return ret;
  132. }
  133. module_init(q40fb_init);
  134. MODULE_LICENSE("GPL");