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