2 * $Id: hitfb.c,v 1.1.1.1 2005/04/11 02:50:42 jack Exp $
3 * linux/drivers/video/hitfb.c -- Hitachi LCD frame buffer device
4 * (C) 1999 Mihai Spatar
5 * (C) 2000 YAEGASHI Takeshi
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
12 #include <linux/config.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/errno.h>
17 #include <linux/string.h>
19 #include <linux/tty.h>
20 #include <linux/slab.h>
21 #include <linux/delay.h>
22 #include <linux/nubus.h>
23 #include <linux/init.h>
25 #include <asm/machvec.h>
26 #include <asm/uaccess.h>
27 #include <asm/pgtable.h>
29 #include <asm/hd64461.h>
33 #include <video/fbcon.h>
34 #include <video/fbcon-cfb8.h>
35 #include <video/fbcon-cfb16.h>
46 struct fb_info_gen gen;
48 struct hitfb_par current_par;
49 struct fb_var_screeninfo default_var;
50 int current_par_valid;
51 unsigned long hit_videobase, hit_videosize;
53 #ifdef FBCON_HAS_CFB16
67 static void hitfb_set_par(const void *fb_par, struct fb_info_gen *info);
68 static int hitfb_encode_var(struct fb_var_screeninfo *var, const void *fb_par,
69 struct fb_info_gen *info);
72 static void hitfb_detect(void)
75 unsigned short lcdclor, ldr3, ldvntr;
77 fb_info.hit_videobase = CONFIG_HD64461_IOBASE + 0x02000000;
78 fb_info.hit_videosize = (MACH_HP680 || MACH_HP690) ? 1024*1024 : 512*1024;
80 lcdclor = inw(HD64461_LCDCLOR);
81 ldvntr = inw(HD64461_LDVNTR);
82 ldr3 = inw(HD64461_LDR3);
98 hitfb_set_par(&par, NULL);
99 hitfb_encode_var(&fb_info.default_var, &par, NULL);
103 static int hitfb_encode_fix(struct fb_fix_screeninfo *fix, const void *fb_par,
104 struct fb_info_gen *info)
106 const struct hitfb_par *par = fb_par;
108 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
110 strcpy(fix->id, "Hitachi HD64461");
111 fix->smem_start = fb_info.hit_videobase;
112 fix->smem_len = fb_info.hit_videosize;
113 fix->type = FB_TYPE_PACKED_PIXELS;
115 fix->visual = (par->bpp == 8) ?
116 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
124 fix->line_length = par->x;
127 fix->line_length = par->x*2;
135 static int hitfb_decode_var(const struct fb_var_screeninfo *var, void *fb_par,
136 struct fb_info_gen *info)
138 struct hitfb_par *par = fb_par;
142 par->bpp = var->bits_per_pixel;
147 static int hitfb_encode_var(struct fb_var_screeninfo *var, const void *fb_par,
148 struct fb_info_gen *info)
150 const struct hitfb_par *par = fb_par;
152 memset(var, 0, sizeof(*var));
156 var->xres_virtual = var->xres;
157 var->yres_virtual = var->yres;
160 var->bits_per_pixel = par->bpp;
162 var->transp.offset = 0;
163 var->transp.length = 0;
164 var->transp.msb_right = 0;
169 var->vmode = FB_VMODE_NONINTERLACED;
172 var->left_margin = 0;
173 var->right_margin = 0;
174 var->upper_margin = 0;
175 var->lower_margin = 0;
179 switch (var->bits_per_pixel) {
184 var->green.offset = 0;
185 var->green.length = 8;
186 var->blue.offset = 0;
187 var->blue.length = 8;
188 var->transp.offset = 0;
189 var->transp.length = 0;
192 case 16: /* RGB 565 */
193 var->red.offset = 11;
195 var->green.offset = 5;
196 var->green.length = 6;
197 var->blue.offset = 0;
198 var->blue.length = 5;
199 var->transp.offset = 0;
200 var->transp.length = 0;
204 var->red.msb_right = 0;
205 var->green.msb_right = 0;
206 var->blue.msb_right = 0;
207 var->transp.msb_right = 0;
213 static void hitfb_get_par(void *par, struct fb_info_gen *info)
215 *(struct hitfb_par *)par = fb_info.current_par;
219 static void hitfb_set_par(const void *fb_par, struct fb_info_gen *info)
221 const struct hitfb_par *par = fb_par;
222 fb_info.current_par = *par;
223 fb_info.current_par_valid = 1;
227 static int hitfb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
228 unsigned *blue, unsigned *transp,
229 struct fb_info *info)
234 outw(regno<<8, HD64461_CPTRAR);
235 *red = inw(HD64461_CPTRDR)<<10;
236 *green = inw(HD64461_CPTRDR)<<10;
237 *blue = inw(HD64461_CPTRDR)<<10;
244 static int hitfb_setcolreg(unsigned regno, unsigned red, unsigned green,
245 unsigned blue, unsigned transp,
246 struct fb_info *info)
251 outw(regno<<8, HD64461_CPTWAR);
252 outw(red>>10, HD64461_CPTWDR);
253 outw(green>>10, HD64461_CPTWDR);
254 outw(blue>>10, HD64461_CPTWDR);
257 switch(fb_info.current_par.bpp) {
258 #ifdef FBCON_HAS_CFB16
260 fb_info.fbcon_cmap.cfb16[regno] =
262 ((green & 0xfc00) >> 5) |
263 ((blue & 0xf800) >> 11);
273 static int hitfb_pan_display(const struct fb_var_screeninfo *var,
274 struct fb_info_gen *info)
276 if (!fb_info.current_par_valid)
283 static int hitfb_blank(int blank_mode, struct fb_info_gen *info)
285 if (!fb_info.current_par_valid)
292 static void hitfb_set_disp(const void *fb_par, struct display *disp,
293 struct fb_info_gen *info)
295 const struct hitfb_par *par = fb_par;
297 disp->screen_base = (void *)fb_info.hit_videobase;
298 disp->scrollmode = SCROLL_YREDRAW;
300 switch(((struct hitfb_par *)par)->bpp) {
301 #ifdef FBCON_HAS_CFB8
303 disp->dispsw = &fbcon_cfb8;
306 #ifdef FBCON_HAS_CFB16
308 disp->dispsw = &fbcon_cfb16;
309 disp->dispsw_data = fb_info.fbcon_cmap.cfb16;
313 disp->dispsw = &fbcon_dummy;
318 struct fbgen_hwswitch hitfb_switch = {
333 static struct fb_ops hitfb_ops = {
335 fb_get_fix: fbgen_get_fix,
336 fb_get_var: fbgen_get_var,
337 fb_set_var: fbgen_set_var,
338 fb_get_cmap: fbgen_get_cmap,
339 fb_set_cmap: fbgen_set_cmap,
340 fb_pan_display: fbgen_pan_display,
344 int __init hitfb_init(void)
346 strcpy(fb_info.gen.info.modename, "Hitachi HD64461");
347 fb_info.gen.info.node = -1;
348 fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
349 fb_info.gen.info.fbops = &hitfb_ops;
350 fb_info.gen.info.disp = &fb_info.disp;
351 fb_info.gen.info.changevar = NULL;
352 fb_info.gen.info.switch_con = &fbgen_switch;
353 fb_info.gen.info.updatevar = &fbgen_update_var;
354 fb_info.gen.info.blank = &fbgen_blank;
355 fb_info.gen.parsize = sizeof(struct hitfb_par);
356 fb_info.gen.fbhw = &hitfb_switch;
357 fb_info.gen.fbhw->detect();
359 fbgen_get_var(&fb_info.disp.var, -1, &fb_info.gen.info);
360 fb_info.disp.var.activate = FB_ACTIVATE_NOW;
361 fbgen_do_set_var(&fb_info.disp.var, 1, &fb_info.gen);
362 fbgen_set_disp(-1, &fb_info.gen);
363 fbgen_install_cmap(0, &fb_info.gen);
365 if(register_framebuffer(&fb_info.gen.info)<0) return -EINVAL;
367 printk(KERN_INFO "fb%d: %s frame buffer device\n",
368 GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename);
374 void hitfb_cleanup(struct fb_info *info)
376 unregister_framebuffer(info);
381 MODULE_LICENSE("GPL");
383 int init_module(void)
388 void cleanup_module(void)