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